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

lpmv6.c (153229B)


      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:    lpv6.c
      8  * Purpose: L3 LPM V6 function implementations
      9  */
     10 
     11 #include <soc/defs.h>
     12 #include <shared/bsl.h>
     13 #ifdef INCLUDE_L3  
     14 
     15 #include <soc/drv.h>
     16 #include <bcm/vlan.h>
     17 #include <bcm/error.h>
     18 
     19 #include <bcm/l3.h>
     20 #include <soc/l3x.h>
     21 #include <soc/lpm.h>
     22 #include <soc/format.h>
     23 #ifdef ALPM_ENABLE
     24 #include <soc/alpm.h>
     25 #endif
     26 #include <bcm/tunnel.h>
     27 #include <bcm/debug.h>
     28 #include <bcm/error.h>
     29 #include <bcm/stack.h>
     30 #include <soc/trident2.h>
     31 
     32 #include <bcm_int/esw/trident2.h>
     33 #include <bcm_int/esw/lpmv6.h>
     34 #include <bcm_int/esw/firebolt.h>
     35 #include <bcm_int/esw/triumph.h>
     36 #include <bcm_int/esw/triumph2.h>
     37 #include <bcm_int/esw/stack.h>
     38 #include <bcm_int/esw/flex_ctr.h>
     39 #include <bcm_int/esw_dispatch.h>
     40 #include <bcm_int/esw/flex_ctr.h>
     41 #include <bcm_int/esw/virtual.h>
     42 #include <bcm_int/esw/l3.h>
     43 #include <bcm_int/esw/alpm.h>
     44 #include <bcm_int/esw/alpm_util.h>
     45 
     46 #ifdef BCM_KATANA2_SUPPORT
     47 #include <bcm_int/esw/katana2.h>
     48 #endif /* BCM_KATANA2_SUPPORT */
     49 
     50 #ifdef BCM_TRIDENT3_SUPPORT
     51 #include <bcm_int/esw/trident3.h>
     52 #include <bcm_int/esw/flow.h>
     53 #include <soc/esw/flow_db.h>
     54 #endif /* TRIDENT3_SUPPORT */
     55 
     56 #if defined(BCM_TRX_SUPPORT) 
     57 #include <bcm_int/esw/trx.h>
     58 #endif /* BCM_TRX_SUPPORT */
     59 
     60 #define _BCM_L3_MEM_BANKS_ALL     (-1)
     61 #define _BCM_HOST_ENTRY_NOT_FOUND (-1)
     62 
     63 /* L3 LPM state */
     64 _bcm_defip_pair128_table_t *l3_defip_pair128[BCM_MAX_NUM_UNITS];
     65 
     66 #define SOC_LPM_128_LPM_CACHE_FIELD_CREATE(m, f) soc_field_info_t * m##f
     67 #define SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(m_u, s, m, f) \
     68                 (s)->m##f = soc_mem_fieldinfo_get(m_u, m, f)
     69 typedef struct soc_lpm_128_field_cache_s {
     70     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, CLASS_IDf);
     71     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, DST_DISCARDf);
     72     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, ECMPf);
     73     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, ECMP_COUNTf);
     74     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, ECMP_PTRf);
     75     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, GLOBAL_ROUTEf);
     76     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, HITf);
     77     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IP_ADDR0_UPRf);
     78     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IP_ADDR1_UPRf);
     79     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IP_ADDR0_LWRf);
     80     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IP_ADDR1_LWRf);
     81     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IP_ADDR_MASK0_UPRf);
     82     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IP_ADDR_MASK1_UPRf);
     83     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IP_ADDR_MASK0_LWRf);
     84     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IP_ADDR_MASK1_LWRf);
     85     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, MODE0_UPRf);
     86     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, MODE1_UPRf);
     87     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, MODE0_LWRf);
     88     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, MODE1_LWRf);
     89     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, MODE_MASK0_UPRf);
     90     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, MODE_MASK1_UPRf);
     91     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, MODE_MASK0_LWRf);
     92     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, MODE_MASK1_LWRf);
     93     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, NEXT_HOP_INDEXf);
     94     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, PRIf);
     95     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, RPEf);
     96     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VALID0_UPRf);
     97     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VALID1_UPRf);
     98     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VALID0_LWRf);
     99     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VALID1_LWRf);
    100     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VRF_ID_0_UPRf);
    101     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VRF_ID_1_UPRf);
    102     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VRF_ID_0_LWRf);
    103     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VRF_ID_1_LWRf);
    104     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VRF_ID_MASK0_UPRf);
    105     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VRF_ID_MASK1_UPRf);
    106     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VRF_ID_MASK0_LWRf);
    107     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, VRF_ID_MASK1_LWRf);
    108     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, GLOBAL_HIGHf);
    109     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, ALG_HIT_IDXf);
    110     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, ALG_BKT_PTRf);
    111     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, DEFAULT_MISSf);
    112     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, FLEX_CTR_BASE_COUNTER_IDXf);
    113     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, FLEX_CTR_POOL_NUMBERf);
    114     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, SRC_DISCARDf);    
    115     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, DEFAULTROUTEf);    
    116     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, HIT0f);
    117     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, HIT1f);
    118 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    119     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, MULTICAST_ROUTEf);
    120     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IPMC_EXPECTED_L3_IIF_MISMATCH_TOCPUf);
    121     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, IPMC_EXPECTED_L3_IIF_MISMATCH_DROPf);
    122     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, EXPECTED_L3_IIFf);
    123     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, RPA_IDf);
    124     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_128m, L3MC_INDEXf);
    125 #endif
    126 #if defined(BCM_TOMAHAWK3_SUPPORT)
    127     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_HIT0f);
    128     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_HIT1f);
    129     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_VALID0f);
    130     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_VALID1f);
    131     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, UPR_VALID0f);
    132     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, UPR_VALID1f);
    133     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_KEY0f);
    134     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_KEY1f);
    135     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, UPR_KEY0f);
    136     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, UPR_KEY1f);
    137     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_MASK0f);
    138     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_MASK1f);
    139     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, UPR_MASK0f);
    140     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, UPR_MASK1f);
    141     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_ASSOC_DATA0f);
    142     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_ASSOC_DATA1f);
    143     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_FIXED_DATA0f);
    144     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_FIXED_DATA1f);
    145     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_ALPM1_DATA0f);
    146     SOC_LPM_128_LPM_CACHE_FIELD_CREATE(L3_DEFIP_PAIR_LEVEL1m, LWR_ALPM1_DATA1f);
    147 #endif
    148 } soc_lpm_128_field_cache_t, *soc_lpm_128_field_cache_p;
    149 
    150 static soc_lpm_128_field_cache_p 
    151                         soc_lpm_128_field_cache_state[SOC_MAX_NUM_DEVICES];
    152 
    153 #define SOC_TH3_MEM_OPT_FLD_SET(m_unit, m_entry_data, m_field, m_pval) \
    154         soc_meminfo_fieldinfo_field_set((m_entry_data), \
    155         (&SOC_MEM_INFO(m_unit, L3_DEFIP_PAIR_LEVEL1m)), \
    156         (soc_lpm_128_field_cache_state[(m_unit)]->L3_DEFIP_PAIR_LEVEL1m##m_field), (m_pval))
    157 
    158 #define SOC_TH3_MEM_OPT_FLD_VALID(m_unit, m_mem, m_field) \
    159         ((soc_lpm_128_field_cache_state[(m_unit)]->L3_DEFIP_PAIR_LEVEL1m##m_field) != NULL)
    160 
    161 #define SOC_TH3_MEM_OPT_FLD_LENGTH(m_unit, m_mem, m_field) \
    162         ((soc_lpm_128_field_cache_state[(m_unit)]->L3_DEFIP_PAIR_LEVEL1m##m_field)->len)
    163 
    164 #define SOC_TH3_MEM_OPT_FLD32_GET(m_unit, m_mem, m_entry_data, m_field) \
    165         soc_meminfo_fieldinfo_field32_get((&SOC_MEM_INFO(m_unit, m_mem)), \
    166         (m_entry_data), (soc_lpm_128_field_cache_state[(m_unit)]->L3_DEFIP_PAIR_LEVEL1m##m_field))
    167 
    168 #define SOC_TH3_MEM_OPT_FLD32_SET(m_unit, m_mem, m_entry_data, m_field, m_val) \
    169         soc_meminfo_fieldinfo_field32_set((&SOC_MEM_INFO(m_unit, m_mem)), \
    170         (m_entry_data), (soc_lpm_128_field_cache_state[(m_unit)]->L3_DEFIP_PAIR_LEVEL1m##m_field), (m_val))
    171 
    172 #define SOC_TH3_MEM_OPT_FLD_GET(m_unit, m_mem, m_entry_data, m_field, m_pval) \
    173         soc_meminfo_fieldinfo_field_get((m_entry_data), \
    174         (&SOC_MEM_INFO(m_unit, m_mem)), \
    175         (soc_lpm_128_field_cache_state[(m_unit)]->L3_DEFIP_PAIR_LEVEL1m##m_field), (m_pval))
    176 
    177 
    178 #define SOC_MEM_OPT_FLD32_GET(m_unit, m_mem, m_entry_data, m_field) \
    179         soc_meminfo_fieldinfo_field32_get((&SOC_MEM_INFO(m_unit, m_mem)), \
    180         (m_entry_data), (soc_lpm_128_field_cache_state[(m_unit)]->m_mem##m_field))
    181 
    182 #define SOC_MEM_OPT_FLD32_SET(m_unit, m_mem, m_entry_data, m_field, m_val) \
    183         soc_meminfo_fieldinfo_field32_set((&SOC_MEM_INFO(m_unit, m_mem)), \
    184         (m_entry_data), (soc_lpm_128_field_cache_state[(m_unit)]->m_mem##m_field), (m_val))
    185 
    186 #define SOC_MEM_OPT_FLD_GET(m_unit, m_mem, m_entry_data, m_field, m_pval) \
    187         soc_meminfo_fieldinfo_field_get((m_entry_data), \
    188         (&SOC_MEM_INFO(m_unit, m_mem)), \
    189         (soc_lpm_128_field_cache_state[(m_unit)]->m_mem##m_field), (m_pval))
    190 
    191 #define SOC_MEM_OPT_FLD_SET(m_unit, m_mem, m_entry_data, m_field, m_pval) \
    192         soc_meminfo_fieldinfo_field_set((m_entry_data), \
    193         (&SOC_MEM_INFO(m_unit, m_mem)), \
    194         (soc_lpm_128_field_cache_state[(m_unit)]->m_mem##m_field), (m_pval))
    195 
    196 #define SOC_MEM_OPT_FLD_VALID(m_unit, m_mem, m_field) \
    197         ((soc_lpm_128_field_cache_state[(m_unit)]->m_mem##m_field) != NULL)
    198 
    199 #define SOC_MEM_OPT_FLD_LENGTH(m_unit, m_mem, m_field) \
    200         ((soc_lpm_128_field_cache_state[(m_unit)]->m_mem##m_field)->len)
    201 
    202 
    203 /*
    204  * Function:
    205  *      _bcm_l3_defip_mem_get
    206  * Purpose:
    207  *      Resolve route table memory for a given route entry.
    208  * Parameters:
    209  *      unit       - (IN)SOC unit number.
    210  *      flags      - (IN)IPv6/IPv4 route.
    211  *      plen       - (IN)Prefix length.
    212  *      mem        - (OUT)Route table memory.
    213  * Returns:
    214  *      BCM_E_XXX
    215  */
    216 STATIC int
    217 _bcm_l3_defip_mem_get(int unit, uint32 flags, int plen, soc_mem_t *mem)
    218 {
    219     /* Default value */
    220     *mem = L3_DEFIPm;
    221     if(!SOC_MEM_IS_VALID(unit, L3_DEFIPm) &&
    222        (SOC_MEM_IS_VALID(unit, L3_DEFIP_LEVEL1m))) {
    223         *mem = L3_DEFIP_LEVEL1m;
    224     }
    225 
    226     if ((flags & BCM_L3_IP6) && (plen > 64)) {
    227         *mem = L3_DEFIP_PAIR_128m;
    228         if(!SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_128m)) {
    229             *mem = L3_DEFIP_PAIR_LEVEL1m;
    230         }
    231     }
    232     return BCM_E_NONE;
    233 }
    234 
    235 /*
    236  * Function:
    237  *      _bcm_defip_pair128_hash
    238  * Purpose:
    239  *      Calculate an entry 16 bit hash.
    240  * Parameters:
    241  *      unit        - (IN)SOC unit number.
    242  *      lpm_cfg     - (IN)Buffer to fill defip information. 
    243  *      entry_hash  - (OUT)Entry hash
    244  * Returns:
    245  *      BCM_E_XXX
    246  */
    247 STATIC int
    248 _bcm_defip_pair128_hash(int unit, _bcm_defip_cfg_t *lpm_cfg, uint16 *hash) 
    249 {
    250     uint32 key[BCM_DEFIP_PAIR128_HASH_SZ];
    251 
    252     if (hash == NULL) {
    253         return (BCM_E_PARAM);
    254     }
    255 
    256     if (lpm_cfg->defip_flags & BCM_L3_IP6) {
    257         SAL_IP6_ADDR_TO_UINT32(lpm_cfg->defip_ip6_addr, key);
    258         key[4] = lpm_cfg->defip_sub_len;
    259         key[5] = lpm_cfg->defip_vrf;
    260 
    261         *hash = _shr_crc16b(0, (void *)key,
    262                          WORDS2BITS((BCM_DEFIP_PAIR128_HASH_SZ)));
    263     } else {
    264         /* Call V4 hash function */
    265     }   
    266     return (BCM_E_NONE);
    267 }
    268 
    269 int
    270 _bcm_defip_lkup_plen_get(int unit, _bcm_defip_cfg_t *lpm_cfg)
    271 {
    272     int f, mc;
    273 
    274     f = ((BCM_L3_VRF_OVERRIDE == lpm_cfg->defip_vrf) ? 2 : 1);
    275     mc = (lpm_cfg->defip_flags & BCM_L3_IPMC);
    276 
    277     if (soc_feature(unit, soc_feature_td3_lpm_ipmc_war) && mc) {
    278         f += 3;
    279     }
    280 
    281     return lpm_cfg->defip_sub_len * f;
    282 }
    283 
    284 #ifdef BCM_WARM_BOOT_SUPPORT
    285 /*
    286  * Function:
    287  *      _bcm_defip_pair128_reinit
    288  * Purpose:
    289  *      Re-Initialize sw image for L3_DEFIP_PAIR_128 internal tcam.
    290  *      during warm boot. 
    291  * Parameters:
    292  *      unit    - (IN)SOC unit number.
    293  *      idx     - (IN)Entry index   
    294  *      lpm_cfg - (IN)Inserted entry. 
    295  * Returns:
    296  *      BCM_E_XXX
    297  */
    298 STATIC int 
    299 _bcm_defip_pair128_reinit(int unit, int idx, _bcm_defip_cfg_t *lpm_cfg)
    300 {
    301     int   lkup_plen;         /* Vrf weighted lookup prefix. */
    302     uint16 hash = 0;         /* Entry hash value.           */
    303 
    304     /* Calculate vrf weighted prefix length. */
    305     lkup_plen = _bcm_defip_lkup_plen_get(unit, lpm_cfg);
    306 
    307     /* Calculate entry lookup hash. */
    308     BCM_IF_ERROR_RETURN(_bcm_defip_pair128_hash(unit, lpm_cfg, &hash));
    309 
    310     /* Set software structure info. */
    311     BCM_DEFIP_PAIR128_ENTRY_SET(unit, idx, lkup_plen, hash);
    312 
    313     /* Update software usage counter. */
    314     BCM_DEFIP_PAIR128_USED_COUNT(unit)++;
    315     soc_lpm_stat_128b_count_update(unit, 1);
    316 
    317     return (BCM_E_NONE);
    318 }
    319 #endif /* BCM_WARM_BOOT_SUPPORT */
    320 
    321 /*
    322  * Function:
    323  *      _bcm_defip_pair128_deinit
    324  * Purpose:
    325  *      De-initialize sw image for L3_DEFIP_PAIR_128 internal tcam.
    326  * Parameters:
    327  *      unit - (IN)SOC unit number.
    328  * Returns:
    329  *      BCM_E_XXX
    330  */
    331 int 
    332 _bcm_defip_pair128_deinit(int unit)
    333 {
    334 
    335     if (BCM_DEFIP_PAIR128(unit) == NULL) {
    336         return (BCM_E_NONE);
    337     }
    338 
    339     /* De-allocate any existing structures. */
    340     if (soc_lpm_128_field_cache_state[unit] != NULL) {
    341         sal_free(soc_lpm_128_field_cache_state[unit]);
    342         soc_lpm_128_field_cache_state[unit] = NULL;
    343     }
    344     
    345     if (BCM_DEFIP_PAIR128_ARR(unit) != NULL) {
    346         sal_free(BCM_DEFIP_PAIR128_ARR(unit));
    347         BCM_DEFIP_PAIR128_ARR(unit) = NULL;
    348     }
    349     sal_free(BCM_DEFIP_PAIR128(unit));
    350     BCM_DEFIP_PAIR128(unit) = NULL;
    351 
    352     return (BCM_E_NONE);
    353 }
    354 
    355 int
    356 _bcm_defip_pair128_field_cache_init(int unit)
    357 {
    358     /* De-allocate existing structures. */
    359     if (soc_lpm_128_field_cache_state[unit] != NULL) {
    360         sal_free(soc_lpm_128_field_cache_state[unit]);
    361     }
    362 
    363     soc_lpm_128_field_cache_state[unit] = 
    364            sal_alloc(sizeof(soc_lpm_128_field_cache_t), "lpm_128_field_state");
    365     if (NULL == soc_lpm_128_field_cache_state[unit]) {
    366         return (BCM_E_MEMORY);
    367     }
    368     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    369                                     L3_DEFIP_PAIR_128m, CLASS_IDf);
    370     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    371                                     L3_DEFIP_PAIR_128m, DST_DISCARDf);
    372     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    373                                     L3_DEFIP_PAIR_128m, ECMPf);
    374     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    375                                     L3_DEFIP_PAIR_128m, ECMP_COUNTf);
    376     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    377                                     L3_DEFIP_PAIR_128m, ECMP_PTRf);
    378     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    379                                     L3_DEFIP_PAIR_128m, GLOBAL_ROUTEf);
    380     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    381                                     L3_DEFIP_PAIR_128m, HITf);
    382     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    383                                     L3_DEFIP_PAIR_128m, IP_ADDR0_LWRf);
    384     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    385                                     L3_DEFIP_PAIR_128m, IP_ADDR0_UPRf);
    386     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    387                                     L3_DEFIP_PAIR_128m, IP_ADDR1_LWRf);
    388     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    389                                     L3_DEFIP_PAIR_128m, IP_ADDR1_UPRf);
    390     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    391                                     L3_DEFIP_PAIR_128m, IP_ADDR_MASK0_LWRf);
    392     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    393                                     L3_DEFIP_PAIR_128m, IP_ADDR_MASK0_UPRf);
    394     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    395                                     L3_DEFIP_PAIR_128m, IP_ADDR_MASK1_LWRf);
    396     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    397                                     L3_DEFIP_PAIR_128m, IP_ADDR_MASK1_UPRf);
    398     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    399                                     L3_DEFIP_PAIR_128m, MODE0_LWRf);
    400     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    401                                     L3_DEFIP_PAIR_128m, MODE0_UPRf);
    402     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    403                                     L3_DEFIP_PAIR_128m, MODE1_LWRf);
    404     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    405                                     L3_DEFIP_PAIR_128m, MODE1_UPRf);
    406     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    407                                     L3_DEFIP_PAIR_128m, MODE_MASK0_LWRf);
    408     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    409                                     L3_DEFIP_PAIR_128m, MODE_MASK0_UPRf);
    410     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    411                                     L3_DEFIP_PAIR_128m, MODE_MASK1_LWRf);
    412     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    413                                     L3_DEFIP_PAIR_128m, MODE_MASK1_UPRf);
    414     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    415                                     L3_DEFIP_PAIR_128m, NEXT_HOP_INDEXf);
    416     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    417                                     L3_DEFIP_PAIR_128m, PRIf);
    418     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    419                                     L3_DEFIP_PAIR_128m, RPEf);
    420     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    421                                     L3_DEFIP_PAIR_128m, VALID0_LWRf);
    422     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    423                                     L3_DEFIP_PAIR_128m, VALID0_UPRf);
    424     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    425                                     L3_DEFIP_PAIR_128m, VALID1_LWRf);
    426     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    427                                     L3_DEFIP_PAIR_128m, VALID1_UPRf);
    428     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    429                                     L3_DEFIP_PAIR_128m, VRF_ID_0_LWRf);
    430     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    431                                     L3_DEFIP_PAIR_128m, VRF_ID_0_UPRf);
    432     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    433                                     L3_DEFIP_PAIR_128m, VRF_ID_1_LWRf);
    434     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    435                                     L3_DEFIP_PAIR_128m, VRF_ID_1_UPRf);
    436     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    437                                     L3_DEFIP_PAIR_128m, VRF_ID_MASK0_LWRf);
    438     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    439                                     L3_DEFIP_PAIR_128m, VRF_ID_MASK0_UPRf);
    440     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    441                                     L3_DEFIP_PAIR_128m, VRF_ID_MASK1_LWRf);
    442     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    443                                     L3_DEFIP_PAIR_128m, VRF_ID_MASK1_UPRf);
    444     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    445                                     L3_DEFIP_PAIR_128m, GLOBAL_HIGHf);
    446     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    447                                     L3_DEFIP_PAIR_128m, ALG_HIT_IDXf);
    448     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    449                                     L3_DEFIP_PAIR_128m, ALG_BKT_PTRf);
    450     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    451                                     L3_DEFIP_PAIR_128m, DEFAULT_MISSf);
    452     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    453                                     L3_DEFIP_PAIR_128m, 
    454                                     FLEX_CTR_BASE_COUNTER_IDXf);
    455     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    456                                     L3_DEFIP_PAIR_128m, 
    457                                     FLEX_CTR_POOL_NUMBERf);    
    458     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    459                                     L3_DEFIP_PAIR_128m, 
    460                                     SRC_DISCARDf);
    461     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    462                                     L3_DEFIP_PAIR_128m, DEFAULTROUTEf);
    463     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    464                                     L3_DEFIP_PAIR_128m, HIT0f);
    465     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    466                                     L3_DEFIP_PAIR_128m, HIT1f);
    467 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
    468     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    469                                     L3_DEFIP_PAIR_128m, MULTICAST_ROUTEf);
    470     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    471                                     L3_DEFIP_PAIR_128m, IPMC_EXPECTED_L3_IIF_MISMATCH_TOCPUf);
    472     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    473                                     L3_DEFIP_PAIR_128m, IPMC_EXPECTED_L3_IIF_MISMATCH_DROPf);
    474     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    475                                     L3_DEFIP_PAIR_128m, EXPECTED_L3_IIFf);
    476     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    477                                     L3_DEFIP_PAIR_128m, RPA_IDf);
    478     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    479                                     L3_DEFIP_PAIR_128m, L3MC_INDEXf);
    480 #endif
    481 #if defined(BCM_TOMAHAWK3_SUPPORT)
    482     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    483                                     L3_DEFIP_PAIR_LEVEL1m, LWR_HIT0f);
    484     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    485                                     L3_DEFIP_PAIR_LEVEL1m, LWR_HIT1f);
    486     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    487                                     L3_DEFIP_PAIR_LEVEL1m, LWR_VALID0f);
    488     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    489                                     L3_DEFIP_PAIR_LEVEL1m, LWR_VALID1f);
    490     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    491                                     L3_DEFIP_PAIR_LEVEL1m, UPR_VALID0f);
    492     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    493                                     L3_DEFIP_PAIR_LEVEL1m, UPR_VALID1f);
    494     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    495                                     L3_DEFIP_PAIR_LEVEL1m, LWR_KEY0f);
    496     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    497                                     L3_DEFIP_PAIR_LEVEL1m, LWR_KEY1f);
    498     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    499                                     L3_DEFIP_PAIR_LEVEL1m, UPR_KEY0f);
    500     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    501                                     L3_DEFIP_PAIR_LEVEL1m, UPR_KEY1f);
    502     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    503                                     L3_DEFIP_PAIR_LEVEL1m, LWR_MASK0f);
    504     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    505                                     L3_DEFIP_PAIR_LEVEL1m, LWR_MASK1f);
    506     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    507                                     L3_DEFIP_PAIR_LEVEL1m, UPR_MASK0f);
    508     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    509                                     L3_DEFIP_PAIR_LEVEL1m, UPR_MASK1f);
    510     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    511                                     L3_DEFIP_PAIR_LEVEL1m, LWR_ASSOC_DATA0f);
    512     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    513                                     L3_DEFIP_PAIR_LEVEL1m, LWR_ASSOC_DATA1f);
    514     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    515                                     L3_DEFIP_PAIR_LEVEL1m, LWR_FIXED_DATA0f);
    516     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    517                                     L3_DEFIP_PAIR_LEVEL1m, LWR_FIXED_DATA1f);
    518     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    519                                     L3_DEFIP_PAIR_LEVEL1m, LWR_ALPM1_DATA0f);
    520     SOC_LPM_128_LPM_CACHE_FIELD_ASSIGN(unit, soc_lpm_128_field_cache_state[unit],
    521                                     L3_DEFIP_PAIR_LEVEL1m, LWR_ALPM1_DATA1f);
    522 #endif
    523     return BCM_E_NONE;
    524 }
    525 
    526 /*
    527  * Function:
    528  *      _bcm_defip_pair128_init
    529  * Purpose:
    530  *      Initialize sw image for L3_DEFIP_PAIR_128 internal tcam.
    531  * Parameters:
    532  *      unit        - (IN)SOC unit number.
    533  * Returns:
    534  *      BCM_E_XXX
    535  */
    536 STATIC int
    537 _bcm_defip_pair128_init(int unit)
    538 {
    539     int rv;
    540     int mem_sz;   
    541     int ipv6_128_depth;
    542  
    543     /* De-allocate any existing structures. */
    544     if (BCM_DEFIP_PAIR128(unit) != NULL) {
    545         rv = _bcm_defip_pair128_deinit(unit);
    546         BCM_IF_ERROR_RETURN(rv);
    547     }
    548 
    549     /* Allocate cam control structure. */
    550     mem_sz = sizeof(_bcm_defip_pair128_table_t);
    551     BCM_DEFIP_PAIR128(unit) = sal_alloc(mem_sz, "td2_l3_defip_pair128");
    552     if (BCM_DEFIP_PAIR128(unit) == NULL) {
    553         return (BCM_E_MEMORY);
    554     }
    555 
    556     /* Reset cam control structure. */
    557     sal_memset(BCM_DEFIP_PAIR128(unit), 0, mem_sz);
    558 
    559     ipv6_128_depth = SOC_L3_DEFIP_MAX_128B_ENTRIES(unit);
    560     BCM_DEFIP_PAIR128_TOTAL(unit) = ipv6_128_depth;
    561     BCM_DEFIP_PAIR128_URPF_OFFSET(unit) = 0;
    562     BCM_DEFIP_PAIR128_IDX_MAX(unit) = ipv6_128_depth - 1;
    563     if (ipv6_128_depth) {
    564         mem_sz = ipv6_128_depth * sizeof(_bcm_defip_pair128_entry_t);
    565         BCM_DEFIP_PAIR128_ARR(unit) = 
    566                               sal_alloc(mem_sz, 
    567                                         "td2_l3_defip_pair128_entry_array");
    568         if (BCM_DEFIP_PAIR128_ARR(unit) == NULL) {
    569             BCM_IF_ERROR_RETURN(_bcm_defip_pair128_deinit(unit));
    570             return (BCM_E_MEMORY);
    571         }
    572         sal_memset(BCM_DEFIP_PAIR128_ARR(unit), 0, mem_sz);
    573     }
    574 
    575     rv = _bcm_defip_pair128_field_cache_init(unit);
    576     if (BCM_FAILURE(rv)) {
    577         BCM_IF_ERROR_RETURN(_bcm_defip_pair128_deinit(unit));
    578         return rv;
    579     }
    580     
    581     return (BCM_E_NONE);
    582 }
    583 
    584 /*
    585  * Function:    
    586  *     _bcm_defip_pair128_ip6_mask_set
    587  * Purpose:  
    588  *     Set IP6 mask field in memory from ip6 addr type. 
    589  * Parameters: 
    590  *     unit  - (IN) BCM device number. 
    591  *     mem   - (IN) Memory id.
    592  *     entry - (IN) HW entry buffer.
    593  *     ip6   - (IN) SW ip6 address buffer.
    594  * Returns:      void
    595  */
    596 STATIC void
    597 _bcm_defip_pair128_ip6_mask_set(int unit, soc_mem_t mem, uint32 *entry, 
    598                                 const ip6_addr_t ip6)
    599 {
    600     uint32              ip6_field[4];
    601     
    602 #if defined(BCM_TOMAHAWK3_SUPPORT)
    603     assert((mem == L3_DEFIP_PAIR_128m) || (mem == L3_DEFIP_PAIR_LEVEL1m));
    604 #else
    605     assert(mem == L3_DEFIP_PAIR_128m);
    606 #endif
    607     ip6_field[3] = ((ip6[12] << 24)| (ip6[13] << 16) |
    608                     (ip6[14] << 8) | (ip6[15] << 0));
    609 
    610 #if defined(BCM_TOMAHAWK3_SUPPORT)
    611     if (!SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_128m)) {
    612         int vrf_mask = 0;
    613         uint32 _key_data[2] = {0,0};
    614         vrf_mask = (1 << soc_format_field_length(unit, L3_DEFIP_TCAM_KEYfmt, VRF_IDf)) - 1;
    615         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf, ip6_field[3]);
    616         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, VRF_IDf, vrf_mask);
    617         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_MODEf, 0x3);
    618         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_TYPEf, 0x1);
    619         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)entry, LWR_MASK0f, _key_data);
    620 
    621         ip6_field[2] = ((ip6[8] << 24) | (ip6[9] << 16) |
    622                         (ip6[10] << 8) | (ip6[11] << 0));
    623         _key_data[0] = _key_data[1] = 0;
    624         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf, ip6_field[2]);
    625         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, VRF_IDf, vrf_mask);
    626         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_MODEf, 0x3);
    627         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_TYPEf, 0x1);
    628         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)entry, LWR_MASK1f, _key_data);
    629 
    630         ip6_field[1] = ((ip6[4] << 24) | (ip6[5] << 16) |
    631                         (ip6[6] << 8)  | (ip6[7] << 0));
    632         _key_data[0] = _key_data[1] = 0;
    633         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf, ip6_field[1]);
    634         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, VRF_IDf, vrf_mask);
    635         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_MODEf, 0x3);
    636         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_TYPEf, 0x1);
    637         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)entry, UPR_MASK0f, _key_data);
    638 
    639         ip6_field[0] = ((ip6[0] << 24) | (ip6[1] << 16) |
    640                         (ip6[2] << 8)  | (ip6[3] << 0));
    641         _key_data[0] = _key_data[1] = 0;
    642         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf, ip6_field[0]);
    643         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, VRF_IDf, vrf_mask);
    644         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_MODEf, 0x3);
    645         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_TYPEf, 0x1);
    646         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)entry, UPR_MASK1f, _key_data);
    647     } else
    648 #endif
    649     {
    650         SOC_MEM_OPT_FLD_SET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR_MASK0_LWRf, &ip6_field[3]);
    651         ip6_field[2] = ((ip6[8] << 24) | (ip6[9] << 16) |
    652                         (ip6[10] << 8) | (ip6[11] << 0));
    653         SOC_MEM_OPT_FLD_SET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR_MASK1_LWRf, &ip6_field[2]);
    654         ip6_field[1] = ((ip6[4] << 24) | (ip6[5] << 16) |
    655                         (ip6[6] << 8)  | (ip6[7] << 0));
    656         SOC_MEM_OPT_FLD_SET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR_MASK0_UPRf, &ip6_field[1]);
    657         ip6_field[0] = ((ip6[0] << 24) | (ip6[1] << 16) |
    658                         (ip6[2] << 8)  | (ip6[3] << 0));
    659         SOC_MEM_OPT_FLD_SET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR_MASK1_UPRf, ip6_field);
    660     }
    661 }
    662 
    663 /*
    664  * Function:    
    665  *     _bcm_defip_pair128_ip6_mask_get
    666  * Purpose:  
    667  *     Read IP6 mask field from memory field to ip6_addr_t buffer. 
    668  * Parameters: 
    669  *     unit  - (IN) BCM device number. 
    670  *     mem   - (IN) Memory id.
    671  *     entry - (IN) HW entry buffer.
    672  *     ip6   - (OUT) SW ip6 address buffer.
    673  * Returns:      void
    674  */
    675 STATIC void
    676 _bcm_defip_pair128_ip6_mask_get(int unit, soc_mem_t mem, const void *entry, 
    677                                 ip6_addr_t ip6)
    678 {
    679     uint32              ip6_field[4];
    680 
    681     assert((mem == L3_DEFIP_PAIR_128m) || (mem == L3_DEFIP_PAIR_LEVEL1m));
    682 
    683 #if defined(BCM_TOMAHAWK3_SUPPORT)
    684     if (!SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_128m)) {
    685         uint32 _key_data[2] = {0, 0};
    686         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)entry, LWR_MASK0f, _key_data);
    687         ip6_field[3] = soc_format_field32_get(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf);
    688         ip6[12] = (uint8) (ip6_field[3] >> 24);
    689         ip6[13] = (uint8) (ip6_field[3] >> 16 & 0xff);
    690         ip6[14] = (uint8) (ip6_field[3] >> 8 & 0xff);
    691         ip6[15] = (uint8) (ip6_field[3] & 0xff);
    692         _key_data[0] = _key_data[1] = 0;
    693         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)entry, LWR_MASK1f, _key_data);
    694         ip6_field[2] = soc_format_field32_get(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf);
    695         ip6[8] = (uint8) (ip6_field[2] >> 24);
    696         ip6[9] = (uint8) (ip6_field[2] >> 16 & 0xff);
    697         ip6[10] = (uint8) (ip6_field[2] >> 8 & 0xff);
    698         ip6[11] = (uint8) (ip6_field[2] & 0xff);
    699         _key_data[0] = _key_data[1] = 0;
    700         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)entry, UPR_MASK0f, _key_data);
    701         ip6_field[1] = soc_format_field32_get(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf);
    702         ip6[4] = (uint8) (ip6_field[1] >> 24);
    703         ip6[5] = (uint8) (ip6_field[1] >> 16 & 0xff);
    704         ip6[6] = (uint8) (ip6_field[1] >> 8 & 0xff);
    705         ip6[7] = (uint8) (ip6_field[1] & 0xff);
    706         _key_data[0] = _key_data[1] = 0;
    707         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)entry, UPR_MASK1f, _key_data);
    708         ip6_field[0] = soc_format_field32_get(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf);
    709         ip6[0] = (uint8) (ip6_field[0] >> 24);
    710         ip6[1] = (uint8) (ip6_field[0] >> 16 & 0xff);
    711         ip6[2] = (uint8) (ip6_field[0] >> 8 & 0xff);
    712         ip6[3] = (uint8) (ip6_field[0] & 0xff);
    713     } else
    714 #endif
    715     {
    716         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR_MASK0_LWRf, (uint32 *)&ip6_field[3]);
    717         ip6[12] = (uint8) (ip6_field[3] >> 24);
    718         ip6[13] = (uint8) (ip6_field[3] >> 16 & 0xff);
    719         ip6[14] = (uint8) (ip6_field[3] >> 8 & 0xff);
    720         ip6[15] = (uint8) (ip6_field[3] & 0xff);
    721         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR_MASK1_LWRf, (uint32 *)&ip6_field[2]);
    722         ip6[8]  = (uint8) (ip6_field[2] >> 24);
    723         ip6[9]  = (uint8) (ip6_field[2] >> 16 & 0xff);
    724         ip6[10] = (uint8) (ip6_field[2] >> 8 & 0xff);
    725         ip6[11] = (uint8) (ip6_field[2] & 0xff);
    726         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR_MASK0_UPRf, (uint32 *)&ip6_field[1]);
    727         ip6[4] = (uint8) (ip6_field[1] >> 24);
    728         ip6[5] = (uint8) (ip6_field[1] >> 16 & 0xff);
    729         ip6[6] = (uint8) (ip6_field[1] >> 8 & 0xff);
    730         ip6[7] = (uint8) (ip6_field[1] & 0xff);
    731         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR_MASK1_UPRf, ip6_field);
    732         ip6[0] = (uint8) (ip6_field[0] >> 24);
    733         ip6[1] = (uint8) (ip6_field[0] >> 16 & 0xff);
    734         ip6[2] = (uint8) (ip6_field[0] >> 8 & 0xff);
    735         ip6[3] = (uint8) (ip6_field[0] & 0xff);
    736     }
    737 }
    738 
    739 /*
    740  * Function:    
    741  *     _bcm_defip_pair128_ip6_addr_set
    742  * Purpose:  
    743  *     Set IP6 address field in memory from ip6 addr type. 
    744  * Parameters: 
    745  *     unit  - (IN) BCM device number. 
    746  *     mem   - (IN) Memory id.
    747  *     entry - (IN) HW entry buffer.
    748  *     ip6   - (IN) SW ip6 address buffer.
    749  * Returns:      void
    750  */
    751 STATIC void
    752 _bcm_defip_pair128_ip6_addr_set(int unit, soc_mem_t mem, uint32 *entry, 
    753                                 const ip6_addr_t ip6)
    754 {
    755     uint32              ip6_field[4];
    756 
    757     assert(mem == L3_DEFIP_PAIR_128m);
    758 
    759     ip6_field[3] = ((ip6[12] << 24)| (ip6[13] << 16) |
    760                     (ip6[14] << 8) | (ip6[15] << 0));
    761     SOC_MEM_OPT_FLD_SET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR0_LWRf, &ip6_field[3]);
    762     ip6_field[2] = ((ip6[8] << 24) | (ip6[9] << 16) |
    763                     (ip6[10] << 8) | (ip6[11] << 0));
    764     SOC_MEM_OPT_FLD_SET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR1_LWRf, &ip6_field[2]);
    765     ip6_field[1] = ((ip6[4] << 24) | (ip6[5] << 16) |
    766                     (ip6[6] << 8)  | (ip6[7] << 0));
    767     SOC_MEM_OPT_FLD_SET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR0_UPRf, &ip6_field[1]);
    768     ip6_field[0] = ((ip6[0] << 24) | (ip6[1] << 16) |
    769                     (ip6[2] << 8)  | (ip6[3] << 0));
    770     SOC_MEM_OPT_FLD_SET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR1_UPRf, ip6_field);
    771 
    772 }
    773 
    774 /*
    775  * Function:    
    776  *     _bcm_defip_pair128_ip6_addr_get
    777  * Purpose:  
    778  *     Read IP6 address field from memory field to ip6_addr_t buffer. 
    779  * Parameters: 
    780  *     unit  - (IN) BCM device number. 
    781  *     mem   - (IN) Memory id.
    782  *     entry - (IN) HW entry buffer.
    783  *     ip6   - (OUT) SW ip6 address buffer.
    784  * Returns:      void
    785  */
    786 STATIC void
    787 _bcm_defip_pair128_ip6_addr_get(int unit, soc_mem_t mem, const void *entry, 
    788                                 ip6_addr_t ip6)
    789 {
    790     uint32              ip6_field[4];
    791 
    792     assert((mem == L3_DEFIP_PAIR_128m) || (mem == L3_DEFIP_PAIR_LEVEL1m));
    793 
    794     if (mem == L3_DEFIP_PAIR_128m) {
    795         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR0_LWRf, (uint32 *)&ip6_field[3]);
    796         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR1_LWRf, (uint32 *)&ip6_field[2]);
    797         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR0_UPRf, (uint32 *)&ip6_field[1]);
    798         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_128m, entry, IP_ADDR1_UPRf, ip6_field);
    799     } else {
    800 #ifdef BCM_TOMAHAWK3_SUPPORT
    801         uint32 _key_data[2] = {0, 0};
    802         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)entry, LWR_KEY0f, _key_data);
    803         ip6_field[3] = soc_format_field32_get(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf);
    804         _key_data[0] = _key_data[1] = 0;
    805         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)entry, LWR_KEY1f, _key_data);
    806         ip6_field[2] = soc_format_field32_get(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf);
    807         _key_data[0] = _key_data[1] = 0;
    808         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)entry, UPR_KEY0f, _key_data);
    809         ip6_field[1] = soc_format_field32_get(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf);
    810         _key_data[0] = _key_data[1] = 0;
    811         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)entry, UPR_KEY1f, _key_data);
    812         ip6_field[0] = soc_format_field32_get(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf);
    813 #endif
    814     }
    815     ip6[12] = (uint8) (ip6_field[3] >> 24);
    816     ip6[13] = (uint8) (ip6_field[3] >> 16 & 0xff);
    817     ip6[14] = (uint8) (ip6_field[3] >> 8 & 0xff);
    818     ip6[15] = (uint8) (ip6_field[3] & 0xff);
    819     ip6[8] = (uint8) (ip6_field[2] >> 24);
    820     ip6[9] = (uint8) (ip6_field[2] >> 16 & 0xff);
    821     ip6[10] = (uint8) (ip6_field[2] >> 8 & 0xff);
    822     ip6[11] = (uint8) (ip6_field[2] & 0xff);
    823     ip6[4] = (uint8) (ip6_field[1] >> 24);
    824     ip6[5] = (uint8) (ip6_field[1] >> 16 & 0xff);
    825     ip6[6] =(uint8) (ip6_field[1] >> 8 & 0xff);
    826     ip6[7] =(uint8) (ip6_field[1] & 0xff);
    827     ip6[0] =(uint8) (ip6_field[0] >> 24);
    828     ip6[1] =(uint8) (ip6_field[0] >> 16 & 0xff);
    829     ip6[2] =(uint8) (ip6_field[0] >> 8 & 0xff);
    830     ip6[3] =(uint8) (ip6_field[0] & 0xff);
    831     
    832 }
    833 
    834 /*
    835  * Function:
    836  *      _bcm_defip_pair128_get_key
    837  * Purpose:
    838  *      Parse route entry key from L3_DEFIP_PAIR_128 table.
    839  * Parameters:
    840  *      unit        - (IN)SOC unit number.
    841  *      entry       - (IN)Hw entry buffer. 
    842  *      lpm_cfg     - (IN/OUT)Buffer to fill defip information. 
    843  * Returns:
    844  *      BCM_E_XXX
    845  */
    846 STATIC int 
    847 _bcm_defip_pair128_get_key(int unit, uint32 *hw_entry, _bcm_defip_cfg_t *lpm_cfg)
    848 {
    849     bcm_ip6_t mask;                      /* Subnet mask.        */
    850     soc_mem_t mem = L3_DEFIP_PAIR_128m;
    851 
    852     /* Input parameters check. */
    853     if ((lpm_cfg == NULL) || (hw_entry == NULL)) {
    854         return (BCM_E_PARAM);
    855     }
    856 
    857     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
    858 #ifdef BCM_TOMAHAWK3_SUPPORT
    859         uint32 _key_data[2] = {0, 0};
    860         uint8 priority = 0;
    861         mem = L3_DEFIP_PAIR_LEVEL1m;
    862 
    863         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)hw_entry, LWR_KEY0f, _key_data);
    864         lpm_cfg->defip_vrf = soc_format_field32_get(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, VRF_IDf);
    865         _key_data[0] = _key_data[1] = 0;
    866         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)hw_entry, LWR_FIXED_DATA0f, _key_data);
    867         priority = soc_format_field32_get(unit, FIXED_DATAfmt, _key_data, SUB_DB_PRIORITYf);
    868         if (priority == 0) {
    869             lpm_cfg->defip_vrf = BCM_L3_VRF_OVERRIDE;
    870         } else if (priority == 2) {
    871             lpm_cfg->defip_vrf = BCM_L3_VRF_GLOBAL;
    872         }
    873 #endif
    874     }
    875 
    876 #ifdef BCM_TRIDENT3_SUPPORT
    877     if (soc_feature(unit, soc_feature_flex_flow)) {
    878         uint32 key_type;
    879 
    880         key_type = soc_mem_field32_get(unit, L3_DEFIP_PAIR_128m,
    881                 hw_entry, KEY_TYPE0_LWRf);
    882 
    883         if (BCMI_LPM_FLEX_VIEW(key_type)) {
    884             BCM_IF_ERROR_RETURN(
    885                     _bcm_defip_pair128_flex_get_key(unit, hw_entry, lpm_cfg, key_type));
    886             return BCM_E_NONE;
    887         }
    888     }
    889 #endif
    890 
    891     /* Extract ip6 address. */
    892     _bcm_defip_pair128_ip6_addr_get(unit, mem, hw_entry, lpm_cfg->defip_ip6_addr);
    893 
    894     /* Extract subnet mask. */
    895     _bcm_defip_pair128_ip6_mask_get(unit, mem, hw_entry, mask);
    896     lpm_cfg->defip_sub_len = bcm_ip6_mask_length(mask);
    897 
    898     /* Extract vrf id & vrf mask. */
    899     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_128m)) {
    900         if (!SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_MASK0_LWRf)) {
    901             lpm_cfg->defip_vrf = BCM_L3_VRF_OVERRIDE;
    902         } else {
    903             lpm_cfg->defip_vrf = SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_0_LWRf);
    904         }
    905     }
    906     return (BCM_E_NONE);
    907 }
    908 
    909 /*
    910  * Function:
    911  *      _bcm_defip_pair128_match
    912  * Purpose:
    913  *      Lookup route entry from L3_DEFIP_PAIR_128 table.
    914  * Parameters:
    915  *      unit        - (IN)SOC unit number.
    916  *      lpm_cfg     - (IN)Buffer to fill defip information. 
    917  *      hw_entry    - (OUT)Matching hw entry. 
    918  *      hw_index    - (OUT)HW table index. 
    919  * Returns:
    920  *      BCM_E_XXX
    921  */
    922 STATIC int 
    923 _bcm_defip_pair128_match(int unit, _bcm_defip_cfg_t *lpm_cfg, 
    924                          uint32 *hw_entry, int *hw_index)
    925 {
    926     _bcm_defip_cfg_t candidate;        /* Match condidate.            */
    927     int   lkup_plen;                   /* Vrf weighted lookup prefix. */
    928     int   index;                       /* Table iteration index.      */
    929     uint16 hash = 0;                   /* Entry hash value.           */
    930     int   rv = BCM_E_NONE;             /* Internal operation status.  */
    931     soc_mem_t  mem = L3_DEFIP_PAIR_128m;
    932 
    933     /* Initialization */
    934     sal_memset(&candidate, 0, sizeof(_bcm_defip_cfg_t));
    935     
    936     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
    937         mem = L3_DEFIP_PAIR_LEVEL1m;
    938     }
    939 
    940     /* Calculate vrf weighted prefix length. */
    941     lkup_plen = _bcm_defip_lkup_plen_get(unit, lpm_cfg);
    942 
    943     /* Calculate entry lookup hash. */
    944     BCM_IF_ERROR_RETURN(_bcm_defip_pair128_hash(unit, lpm_cfg, &hash));
    945 
    946     /*    coverity[assignment : FALSE]    */
    947     for (index = 0; index <= BCM_DEFIP_PAIR128_IDX_MAX(unit); index++) {
    948 
    949         /* Route prefix length comparison. */
    950         if (lkup_plen != BCM_DEFIP_PAIR128_ARR(unit)[index].prefix_len) {
    951             continue;
    952         }
    953 
    954         /* Route lookup key hash comparison. */
    955         if (hash != BCM_DEFIP_PAIR128_ARR(unit)[index].entry_hash) {
    956             continue;
    957         }
    958 
    959         /* Hash & prefix length match -> read and compare hw entry itself. */
    960         rv = BCM_XGS3_MEM_READ(unit, mem, index, hw_entry);
    961         if (BCM_FAILURE(rv)) {
    962             break;
    963         }
    964 
    965         /* Make sure entry is valid.  */
    966 #ifdef BCM_TOMAHAWK3_SUPPORT
    967         if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
    968             if ((!SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_VALID0f)) ||
    969                 (!SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_VALID1f)) ||
    970                 (!SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, UPR_VALID0f)) ||
    971                 (!SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, UPR_VALID1f))
    972                 ) {
    973                 /* Too bad sw image doesn't match hardware. */
    974                 continue;
    975             }
    976         } else
    977 #endif
    978         if ((!SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, VALID0_LWRf)) ||
    979             (!SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, VALID1_LWRf)) ||
    980             (!SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, VALID0_UPRf)) ||
    981             (!SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, VALID1_UPRf))
    982             ) {
    983             /* Too bad sw image doesn't match hardware. */
    984             continue;
    985         }
    986 
    987         /* Extract entry address vrf */
    988         rv =  _bcm_defip_pair128_get_key(unit, hw_entry, &candidate);
    989         if (BCM_FAILURE(rv)) {
    990             break;
    991         }
    992 
    993 
    994         /* Address & Vrf comparison. */
    995         if (lpm_cfg->defip_vrf != candidate.defip_vrf) {
    996             continue;
    997         }
    998 
    999         /* Subnet mask comparison. */
   1000         if (lpm_cfg->defip_sub_len != candidate.defip_sub_len) {
   1001             continue;
   1002         }
   1003 
   1004 
   1005         if (sal_memcmp(lpm_cfg->defip_ip6_addr, candidate.defip_ip6_addr,
   1006                        sizeof(bcm_ip6_t))) {
   1007             continue;
   1008         }
   1009 
   1010         /* Matching entry found. */
   1011         break;
   1012 
   1013     }
   1014 
   1015     BCM_IF_ERROR_RETURN(rv);
   1016 
   1017     if (index > BCM_DEFIP_PAIR128_IDX_MAX(unit))  {
   1018         return (BCM_E_NOT_FOUND);
   1019     }
   1020 
   1021     *hw_index = index;
   1022     return (BCM_E_NONE);
   1023 }
   1024 
   1025 /*
   1026  * Function:
   1027  *      _bcm_defip_pair128_entry_clear
   1028  * Purpose:
   1029  *      Clear/Reset a single route entry. 
   1030  * Parameters:
   1031  *      unit      - (IN)SOC unit number.
   1032  *      hw_index  - (IN)Entry index in the tcam. 
   1033  * Returns:
   1034  *      BCM_E_XXX
   1035  */
   1036 STATIC int 
   1037 _bcm_defip_pair128_entry_clear(int unit, int hw_index)  
   1038 {
   1039     soc_mem_t mem = L3_DEFIP_PAIR_128m;
   1040     uint32 hw_entry[SOC_MAX_MEM_FIELD_WORDS];
   1041     soc_field_t key_field[4], mask_field[4];
   1042     int field_count, i;
   1043     uint64 val64;
   1044     key_field[0] = KEY0_UPRf;
   1045     key_field[1] = KEY1_UPRf;
   1046     key_field[2] = KEY0_LWRf;
   1047     key_field[3] = KEY1_LWRf;
   1048     mask_field[0] = MASK0_UPRf;
   1049     mask_field[1] = MASK1_UPRf;
   1050     mask_field[2] = MASK0_LWRf;
   1051     mask_field[3] = MASK1_LWRf;
   1052     field_count = 4;
   1053 
   1054     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
   1055         key_field[0] = UPR_KEY0f;
   1056         key_field[1] = UPR_KEY1f;
   1057         key_field[2] = LWR_KEY0f;
   1058         key_field[3] = LWR_KEY1f;
   1059         mask_field[0] = UPR_MASK0f;
   1060         mask_field[1] = UPR_MASK1f;
   1061         mask_field[2] = LWR_MASK0f;
   1062         mask_field[3] = LWR_MASK1f;
   1063         mem = L3_DEFIP_PAIR_LEVEL1m;
   1064     }
   1065     sal_memset(hw_entry, 0, WORDS2BYTES(SOC_MAX_MEM_FIELD_WORDS));
   1066     COMPILER_64_ZERO(val64);
   1067     for (i = 0; i < field_count; i++) {
   1068         soc_mem_field64_set(unit, mem, hw_entry, key_field[i], val64);
   1069         soc_mem_field64_set(unit, mem, hw_entry, mask_field[i], val64);
   1070     }
   1071 
   1072     /* Reset hw entry. */
   1073     BCM_IF_ERROR_RETURN
   1074         (BCM_XGS3_MEM_WRITE(unit, mem, hw_index,
   1075                             &soc_mem_entry_null(unit, mem)));
   1076     BCM_IF_ERROR_RETURN
   1077         (BCM_XGS3_MEM_WRITE(unit, mem, hw_index, hw_entry));
   1078 
   1079     /* Reset sw entry. */
   1080     BCM_DEFIP_PAIR128_ENTRY_SET(unit, hw_index, 0, 0);
   1081 
   1082     /* Reset urpf source lookup entry. */
   1083     /* If soc_feature_l3_defip_advanced_lookup is TRUE then
   1084      * both DIP and SIP lookup is done using 1 L3_DEFIP entry.
   1085      * L3_DEFIP table is not divided into 2 to support URPF (Ex: KT2).
   1086      */
   1087     if (SOC_URPF_STATUS_GET(unit) &&
   1088         !soc_feature(unit, soc_feature_l3_defip_advanced_lookup)) {
   1089         BCM_IF_ERROR_RETURN
   1090             (BCM_XGS3_MEM_WRITE(unit, mem,
   1091                             (hw_index + BCM_DEFIP_PAIR128_URPF_OFFSET(unit)),
   1092                             &soc_mem_entry_null(unit, mem)));
   1093         BCM_IF_ERROR_RETURN
   1094             (BCM_XGS3_MEM_WRITE(unit, mem,
   1095                  (hw_index+ BCM_DEFIP_PAIR128_URPF_OFFSET(unit)), hw_entry));
   1096     }
   1097     return (BCM_E_NONE);
   1098 }
   1099 
   1100 /*
   1101  * Function:
   1102  *      _bcm_defip_pair128_parse
   1103  * Purpose:
   1104  *      Parse route entry from L3_DEFIP_PAIR_128 table to sw structure.
   1105  * Parameters:
   1106  *      unit        - (IN)SOC unit number.
   1107  *      hw_entry    - (IN)Hw entry buffer. 
   1108  *      lpm_cfg     - (IN/OUT)Buffer to fill defip information. 
   1109  *      nh_ecmp_idx - (OUT)Next hop ecmp table index. 
   1110  * Returns:
   1111  *      BCM_E_XXX
   1112  */
   1113 static INLINE int
   1114 _bcm_defip_pair128_parse(int unit, uint32 *hw_entry,
   1115                          _bcm_defip_cfg_t *lpm_cfg, int *nh_ecmp_idx)
   1116 {
   1117     /* Input parameters check. */
   1118     if ((lpm_cfg == NULL) || (hw_entry == NULL)) {
   1119         return (BCM_E_PARAM);
   1120     }
   1121 
   1122     /* Reset entry flags first. */
   1123     lpm_cfg->defip_flags = 0;
   1124 
   1125 #ifdef BCM_TRIDENT3_SUPPORT
   1126     if (soc_feature(unit, soc_feature_flex_flow)) {
   1127         uint32 key_type;
   1128 
   1129         key_type = soc_mem_field32_get(unit, L3_DEFIP_PAIR_128m,
   1130                                          hw_entry, KEY_TYPE0_LWRf);
   1131 
   1132         if (BCMI_LPM_FLEX_VIEW(key_type)) {
   1133             return _bcm_td3_lpm_flex_ent_parse(unit, hw_entry, key_type,
   1134                                                 L3_DEFIP_PAIR_128m, lpm_cfg,
   1135                                                 nh_ecmp_idx);
   1136         }
   1137     }
   1138 #endif
   1139 
   1140 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1141     if (soc_feature(unit, soc_feature_ipmc_defip)) {
   1142         int ipmc_route = 0;
   1143         if (soc_mem_field_valid(unit, L3_DEFIP_PAIR_128m, MULTICAST_ROUTEf)) {
   1144             ipmc_route = soc_mem_field32_get(unit, L3_DEFIP_PAIR_128m,
   1145                                              hw_entry, MULTICAST_ROUTEf);
   1146         } else if (soc_mem_field_valid(unit, L3_DEFIP_PAIR_128m, DATA_TYPEf)) {
   1147             if (soc_mem_field32_get(unit, L3_DEFIP_PAIR_128m,
   1148                                     hw_entry, DATA_TYPEf) == 2) {
   1149                 ipmc_route = 1;
   1150             } else {
   1151                 ipmc_route = 0;
   1152             }
   1153         }
   1154 
   1155         if (ipmc_route) {
   1156             int val;
   1157             lpm_cfg->defip_flags |= BCM_L3_IPMC;
   1158 
   1159             if (SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, IPMC_EXPECTED_L3_IIF_MISMATCH_DROPf)) {
   1160                 lpm_cfg->defip_ipmc_flags |= BCM_IPMC_RPF_FAIL_DROP;
   1161             }
   1162             if (SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, IPMC_EXPECTED_L3_IIF_MISMATCH_TOCPUf)) {
   1163                 lpm_cfg->defip_ipmc_flags |= BCM_IPMC_RPF_FAIL_TOCPU;
   1164             }
   1165             val = SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, EXPECTED_L3_IIFf);
   1166             /*
   1167              * RP ID and ExpectedIIF are overlaid.
   1168              */
   1169             if (soc_feature(unit, soc_feature_l3defip_rp_l3iif_resolve)) {
   1170                 int rpa_id_mask =
   1171                     (1 << soc_mem_field_length(unit, L3_DEFIP_PAIR_128m, RPA_IDf)) - 1;
   1172                 /*
   1173                  * 1) If value is more than RPA_ID field then its l3_iif.
   1174                  *    N/A for TD3/MV2/HX5 to support warmboot.
   1175                  * 2) When RPF FAIL DROP/TOCPU flags are set then its l3iif valid
   1176                  */
   1177                 if ((lpm_cfg->defip_ipmc_flags &
   1178                      (BCM_IPMC_RPF_FAIL_DROP | BCM_IPMC_RPF_FAIL_TOCPU)) ||
   1179                     (!(SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit) ||
   1180                        SOC_IS_HELIX5(unit)) && (val > rpa_id_mask))) {
   1181                     lpm_cfg->defip_expected_intf = val;
   1182                     if (0 != lpm_cfg->defip_expected_intf) {
   1183                         lpm_cfg->defip_ipmc_flags |= BCM_IPMC_POST_LOOKUP_RPF_CHECK;
   1184                     }
   1185                     lpm_cfg->defip_l3a_rp = BCM_IPMC_RP_ID_INVALID;
   1186                 } else {
   1187                     lpm_cfg->defip_ipmc_flags |= BCM_IPMC_RP_ID_EXPECTED_INTF_RESOLVE;
   1188                     lpm_cfg->defip_l3a_rp = val & rpa_id_mask;
   1189                     lpm_cfg->defip_expected_intf = val;
   1190                 }
   1191             } else if (_BCM_DEFIP_IPMC_RP_IS_SET(val)) {
   1192                 lpm_cfg->defip_l3a_rp = _BCM_DEFIP_IPMC_RP_GET(val);
   1193             } else {
   1194                 lpm_cfg->defip_expected_intf = val;
   1195 
   1196                 if (0 != lpm_cfg->defip_expected_intf) {
   1197                     lpm_cfg->defip_ipmc_flags |= BCM_IPMC_POST_LOOKUP_RPF_CHECK;
   1198                 }
   1199                 lpm_cfg->defip_l3a_rp = BCM_IPMC_RP_ID_INVALID;
   1200             }
   1201 
   1202             if (soc_feature(unit, soc_feature_generic_dest)) {
   1203                 uint32 dest_type = SOC_MEM_FIF_DEST_INVALID;
   1204                 uint32 dest_value = 0;
   1205                 dest_value = soc_mem_field32_dest_get(unit,
   1206                         L3_DEFIP_PAIR_128m, hw_entry,
   1207                         DESTINATIONf, &dest_type);
   1208                 if (dest_type == SOC_MEM_FIF_DEST_IPMC) {
   1209                     lpm_cfg->defip_mc_group = dest_value;
   1210                 } else {
   1211                     lpm_cfg->defip_mc_group = 0;
   1212                 }
   1213             } else {
   1214                 lpm_cfg->defip_mc_group = soc_mem_field32_get(unit, L3_DEFIP_PAIR_128m,
   1215                                 hw_entry, L3MC_INDEXf);
   1216             }
   1217         }
   1218     }
   1219 #endif
   1220 
   1221 #if defined(BCM_TOMAHAWK3_SUPPORT)
   1222     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
   1223         uint32 _key_data[2] = {0, 0};
   1224         uint8 ecmp = 0;
   1225         SOC_MEM_OPT_FLD_GET(unit, L3_DEFIP_PAIR_LEVEL1m, (void *)hw_entry, LWR_ASSOC_DATA0f, _key_data);
   1226         ecmp = soc_format_field32_get(unit, ASSOC_DATA_FULLfmt, _key_data, DEST_TYPEf);
   1227         if (ecmp) {
   1228             lpm_cfg->defip_ecmp = TRUE;
   1229             lpm_cfg->defip_flags |= BCM_L3_MULTIPATH;
   1230         } else {
   1231             lpm_cfg->defip_ecmp = 0;
   1232             lpm_cfg->defip_ecmp_count = 0;
   1233         }
   1234         if (nh_ecmp_idx != NULL) {
   1235             *nh_ecmp_idx = soc_format_field32_get(unit, ASSOC_DATA_FULLfmt, _key_data, DESTINATIONf);
   1236         }
   1237         /* Mark entry as IPv6 */
   1238         lpm_cfg->defip_flags |= BCM_L3_IP6;
   1239 
   1240         /* Get entry priority. */
   1241         lpm_cfg->defip_prio = soc_format_field32_get(unit, ASSOC_DATA_FULLfmt, _key_data, PRIf);
   1242 
   1243         /* Get classification group id. */
   1244         lpm_cfg->defip_lookup_class =
   1245             soc_format_field32_get(unit, ASSOC_DATA_FULLfmt, _key_data, CLASS_IDf);
   1246 
   1247         /* Get priority override bit. */
   1248         if (soc_format_field32_get(unit, ASSOC_DATA_FULLfmt, _key_data, RPEf))  {
   1249             lpm_cfg->defip_flags |= BCM_L3_RPE;
   1250         }
   1251 
   1252         /* Get destination discard field. */
   1253         if (soc_format_field32_get(unit, ASSOC_DATA_FULLfmt, _key_data, DST_DISCARDf)) {
   1254             lpm_cfg->defip_flags |= BCM_L3_DST_DISCARD;
   1255         }
   1256 
   1257         /* Get hit bit. */
   1258         if (SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_HIT0f)) {
   1259             lpm_cfg->defip_flags |= BCM_L3_HIT;
   1260         }
   1261 
   1262         if (SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_HIT1f)) {
   1263             lpm_cfg->defip_flags |= BCM_L3_HIT;
   1264         }
   1265 
   1266         return (BCM_E_NONE);
   1267     }
   1268 #endif
   1269     if (soc_feature(unit, soc_feature_generic_dest)) {
   1270         uint32 dstt = 0, dstv;
   1271         dstv = soc_mem_field32_dest_get(unit, L3_DEFIP_PAIR_128m, hw_entry,
   1272                                         DESTINATIONf, &dstt);
   1273         if (dstt == SOC_MEM_FIF_DEST_ECMP) {
   1274             lpm_cfg->defip_ecmp = TRUE;
   1275             lpm_cfg->defip_flags |= BCM_L3_MULTIPATH;
   1276         } else {
   1277             lpm_cfg->defip_ecmp = 0;
   1278             lpm_cfg->defip_ecmp_count = 0;
   1279         }
   1280         if (nh_ecmp_idx != NULL) {
   1281             *nh_ecmp_idx = dstv;
   1282         }
   1283     } else {
   1284         /* Check if entry points to ecmp group. */
   1285         if (SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, ECMPf)) {
   1286             /* Mark entry as ecmp */
   1287             lpm_cfg->defip_ecmp = TRUE;
   1288             lpm_cfg->defip_flags |= BCM_L3_MULTIPATH;
   1289 
   1290             /* Get ecmp group id. */
   1291             if (nh_ecmp_idx != NULL) {
   1292                 *nh_ecmp_idx = SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m,
   1293                                                      hw_entry, ECMP_PTRf);
   1294             }
   1295         } else {
   1296             /* Mark entry as non-ecmp. */
   1297             lpm_cfg->defip_ecmp = 0;
   1298 
   1299             /* Reset ecmp group next hop count. */
   1300             lpm_cfg->defip_ecmp_count = 0;
   1301 
   1302             /* Get next hop index. */
   1303             if (nh_ecmp_idx != NULL) {
   1304 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1305                 if (soc_feature(unit, soc_feature_ipmc_defip) &&
   1306                         (lpm_cfg->defip_flags & BCM_L3_IPMC)) {
   1307                     *nh_ecmp_idx = BCM_XGS3_L3_INVALID_INDEX;
   1308                 } else
   1309 #endif
   1310                 {
   1311                     *nh_ecmp_idx = SOC_MEM_OPT_FLD32_GET(unit,
   1312                         L3_DEFIP_PAIR_128m, hw_entry, NEXT_HOP_INDEXf);
   1313                 }
   1314             }
   1315         }
   1316     }
   1317 
   1318     /* Mark entry as IPv6 */
   1319     lpm_cfg->defip_flags |= BCM_L3_IP6;
   1320 
   1321     /* Get entry priority. */
   1322     lpm_cfg->defip_prio = SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, PRIf);
   1323 
   1324     /* Get classification group id. */
   1325     lpm_cfg->defip_lookup_class = 
   1326         SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, CLASS_IDf);
   1327 
   1328     /* Get hit bit. */
   1329     if (SOC_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_128m, HITf)) {
   1330         if (SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, HITf)) {
   1331             lpm_cfg->defip_flags |= BCM_L3_HIT;
   1332         }
   1333     }
   1334 
   1335     if (SOC_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_128m, HIT0f)) {
   1336         if (SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, HIT0f)) {
   1337             lpm_cfg->defip_flags |= BCM_L3_HIT;
   1338         }
   1339     }
   1340 
   1341     /* Get priority override bit. */
   1342     if (SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, RPEf))  {
   1343         lpm_cfg->defip_flags |= BCM_L3_RPE;
   1344     }
   1345 
   1346     /* Get destination discard field. */
   1347     if (SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, DST_DISCARDf)) {
   1348         lpm_cfg->defip_flags |= BCM_L3_DST_DISCARD;
   1349     }
   1350     return (BCM_E_NONE);
   1351 }
   1352 
   1353 /*
   1354  * Function:
   1355  *      _bcm_defip_pair128_shift
   1356  * Purpose:
   1357  *      Shift entries in the tcam. 
   1358  * Parameters:
   1359  *      unit    - (IN)SOC unit number.
   1360  *      idx_src     - (IN)Entry source. 
   1361  *      idx_dest    - (IN)Entry destination.
   1362  * Returns:
   1363  *      BCM_E_XXX
   1364  */
   1365 STATIC int 
   1366 _bcm_defip_pair128_shift(int unit, int idx_src, int idx_dest)  
   1367 {
   1368     uint32 hw_entry[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer. */
   1369     soc_mem_t mem = L3_DEFIP_PAIR_128m;
   1370 
   1371     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
   1372         mem = L3_DEFIP_PAIR_LEVEL1m;
   1373     }
   1374 
   1375     /* Don't copy uninstalled entries. */
   1376     if (0 != BCM_DEFIP_PAIR128_ARR(unit)[idx_src].prefix_len) {
   1377         /* Read entry from source index. */
   1378         BCM_IF_ERROR_RETURN
   1379             (BCM_XGS3_MEM_READ(unit, mem, idx_src, hw_entry));
   1380 
   1381         /* Write entry to the destination index. */
   1382         BCM_IF_ERROR_RETURN
   1383             (BCM_XGS3_MEM_WRITE(unit, mem, idx_dest, hw_entry));
   1384 
   1385         /* Shift corresponding  URPF/source lookup entries. */
   1386         /* If soc_feature_l3_defip_advanced_lookup is TRUE then
   1387          * both DIP and SIP lookup is done using 1 L3_DEFIP entry.
   1388          * L3_DEFIP table is not divided into 2 to support URPF (Ex: KT2).
   1389          */
   1390         if (SOC_URPF_STATUS_GET(unit) &&
   1391             !soc_feature(unit, soc_feature_l3_defip_advanced_lookup)) {
   1392             /* Read entry from source index + half tcam. */
   1393             BCM_IF_ERROR_RETURN
   1394                 (BCM_XGS3_MEM_READ(unit, mem,
   1395                               idx_src + BCM_DEFIP_PAIR128_URPF_OFFSET(unit),
   1396                               hw_entry));
   1397 
   1398             /* Write entry to the destination index + half tcam. */
   1399             BCM_IF_ERROR_RETURN
   1400                 (BCM_XGS3_MEM_WRITE(unit, mem,
   1401                             idx_dest +  BCM_DEFIP_PAIR128_URPF_OFFSET(unit),
   1402                             hw_entry));
   1403         }
   1404     }
   1405 
   1406     /* Copy software portion of the entry. */ 
   1407     sal_memcpy (&BCM_DEFIP_PAIR128_ARR(unit)[idx_dest],
   1408                 &BCM_DEFIP_PAIR128_ARR(unit)[idx_src], 
   1409                 sizeof(_bcm_defip_pair128_entry_t));
   1410 
   1411     return (BCM_E_NONE);
   1412 }
   1413 
   1414 /*
   1415  * Function:
   1416  *      _bcm_defip_pair128_shift_range
   1417  * Purpose:
   1418  *      Shift entries in the tcam. 
   1419  * Parameters:
   1420  *      unit        - (IN)SOC unit number.
   1421  *      idx_start   - (IN)Start index
   1422  *      idx_end     - (IN)End index
   1423  * Returns:
   1424  *      BCM_E_XXX
   1425  */
   1426 STATIC int 
   1427 _bcm_defip_pair128_shift_range(int unit, int idx_start, int idx_end)  
   1428 {
   1429     int idx;     /* Iteration index. */
   1430     int rv = BCM_E_NONE;   /* Operaton status. */ 
   1431 
   1432     /* Shift entries down (1 index up) */
   1433     if (idx_end > idx_start) {
   1434         for (idx = idx_end - 1; idx >= idx_start; idx--) {
   1435             rv = _bcm_defip_pair128_shift(unit, idx, idx + 1);  
   1436             if (BCM_FAILURE(rv)) { 
   1437                 break;
   1438             }
   1439         }
   1440         /* Delete last entry from hardware & software. */
   1441         rv = _bcm_defip_pair128_entry_clear(unit, idx_start);
   1442     }
   1443 
   1444     /* Shift entries up (1 index down) */
   1445     if (idx_end < idx_start) {
   1446         for (idx = idx_end + 1; idx <= idx_start; idx++) {
   1447             rv = _bcm_defip_pair128_shift(unit, idx, idx - 1);  
   1448             if (BCM_FAILURE(rv)) { 
   1449                 break;
   1450             }
   1451         }
   1452         /* Delete last entry from hardware & software. */
   1453         rv = _bcm_defip_pair128_entry_clear(unit, idx_start);
   1454     }
   1455 
   1456     return (rv);
   1457 }
   1458 
   1459 /*
   1460  * Function:
   1461  *      _bcm_defip_pair128_idx_alloc
   1462  * Purpose:
   1463  *      Shuffle the tcam in order to insert a new entry 
   1464  *      based on vrf weighted prefix length.
   1465  * Parameters:
   1466  *      unit        - (IN)SOC unit number.
   1467  *      lpm_cfg     - (IN)Route info 
   1468  *      hw_index    - (OUT)Allocated hw index. 
   1469  * Returns:
   1470  *      BCM_E_XXX
   1471  */
   1472 int
   1473 _bcm_defip_pair128_idx_alloc(int unit, _bcm_defip_cfg_t *lpm_cfg, int *hw_index,
   1474                              int nh_ecmp_idx)
   1475 {
   1476     int  lkup_plen;                   /* Vrf weighted lookup prefix.    */
   1477     uint16 hash = 0;                  /* Entry hash value.              */
   1478     int  idx;                         /* Table iteration index.         */
   1479     int  rv;                          /* Operation return status.       */
   1480     int  shift_min = 0;               /* Minimum entry shift required.  */
   1481     int  range_start = 0;             /* First valid location for pfx.  */
   1482     int  range_end = BCM_DEFIP_PAIR128_IDX_MAX(unit);
   1483                                       /* Last valid location for pfx.   */
   1484     int  free_idx_before = -1;        /* Free index before range_start. */
   1485     int  free_idx_after  = -1;        /* Free index after range_end.    */
   1486 
   1487     /* Input parameters check. */
   1488     if ((lpm_cfg == NULL) || (hw_index == NULL)) {
   1489         return (BCM_E_PARAM);
   1490     }
   1491 
   1492     /* Calculate vrf weighted prefix length. */
   1493     lkup_plen = _bcm_defip_lkup_plen_get(unit, lpm_cfg);
   1494 
   1495     /* Calculate entry hash. */
   1496     BCM_IF_ERROR_RETURN(_bcm_defip_pair128_hash(unit, lpm_cfg, &hash));
   1497 
   1498     /* Make sure at least one slot is available. */
   1499     if (BCM_DEFIP_PAIR128_USED_COUNT(unit) ==
   1500                       BCM_DEFIP_PAIR128_TOTAL(unit)) {
   1501         return (BCM_E_FULL);
   1502     }
   1503 
   1504     /* 
   1505      *  Find first valid index for the prefix;
   1506      */ 
   1507     for (idx = 0; idx <= BCM_DEFIP_PAIR128_IDX_MAX(unit); idx++) {
   1508         /* Remember free entry before installation location. */
   1509         if (0 == BCM_DEFIP_PAIR128_ARR(unit)[idx].prefix_len) {
   1510             free_idx_before = idx;
   1511             continue;
   1512         }
   1513         /* Route prefix length comparison. */
   1514         if (lkup_plen < BCM_DEFIP_PAIR128_ARR(unit)[idx].prefix_len) {
   1515             range_start = idx;
   1516             continue;
   1517         }
   1518         break;
   1519     }
   1520 
   1521     /* 
   1522      *  Find last valid index for the prefix;
   1523      */ 
   1524     for (idx = BCM_DEFIP_PAIR128_IDX_MAX(unit); idx >= 0; idx--) {
   1525 
   1526         /* Remeber free entry after installation location. */
   1527         if (0 == BCM_DEFIP_PAIR128_ARR(unit)[idx].prefix_len) {
   1528             free_idx_after = idx;
   1529             continue;
   1530         }
   1531         /* Route prefix length comparison. */
   1532         if (lkup_plen >  BCM_DEFIP_PAIR128_ARR(unit)[idx].prefix_len) {
   1533             range_end = idx;
   1534             continue;
   1535         }
   1536         break;
   1537     }
   1538 
   1539     /* Check if entry should be inserted at the end. */
   1540     if (range_start == BCM_DEFIP_PAIR128_IDX_MAX(unit)) {
   1541         /* Shift all entries from free_idx_before till the end 1 up. */   
   1542         rv = _bcm_defip_pair128_shift_range(unit, BCM_DEFIP_PAIR128_IDX_MAX(unit), free_idx_before);
   1543 
   1544         if (BCM_SUCCESS(rv)) { 
   1545             /* Allocated index is last TCAM entry. */
   1546             *hw_index = BCM_DEFIP_PAIR128_IDX_MAX(unit);
   1547             BCM_DEFIP_PAIR128_ENTRY_SET(unit, *hw_index, lkup_plen, hash);
   1548         }
   1549         return (rv);
   1550     }
   1551 
   1552     /* Check if entry should be inserted at the beginning. */
   1553     if (range_end < 0) {
   1554         /* Shift all entries from 0 till free_idx_after 1 down. */
   1555         rv = _bcm_defip_pair128_shift_range(unit, 0, free_idx_after);
   1556 
   1557         if (BCM_SUCCESS(rv)) {
   1558             /* Allocated index is first TCAM entry. */
   1559             *hw_index = 0;
   1560             BCM_DEFIP_PAIR128_ENTRY_SET(unit, 0, lkup_plen, hash);
   1561         }
   1562         return (rv);
   1563     }
   1564 
   1565     /* Find if there is any free index in range. */
   1566     for (idx = range_start; idx <= range_end; idx++) {
   1567         if (0 == BCM_DEFIP_PAIR128_ARR(unit)[idx].prefix_len) {
   1568             *hw_index = idx;
   1569             BCM_DEFIP_PAIR128_ENTRY_SET(unit, idx, lkup_plen, hash);
   1570             return (BCM_E_NONE);
   1571         }
   1572     }
   1573 
   1574     /* Check if entry should be inserted at the end of range. */
   1575     if ((free_idx_after > range_end) && (free_idx_after != -1))  {
   1576         shift_min = free_idx_after - range_end;
   1577     } 
   1578 
   1579     /* Check if entry should be inserted in the beginning. */
   1580     if ((free_idx_before < range_start) && (free_idx_before != -1))  {
   1581         if((shift_min > (range_start - free_idx_before)) || (free_idx_after == -1)) {
   1582             shift_min = -1;
   1583         }
   1584     }
   1585 
   1586     if (shift_min <= 0) {
   1587         rv = _bcm_defip_pair128_shift_range(unit, range_start, free_idx_before);
   1588         if (BCM_SUCCESS(rv)) {
   1589             *hw_index= range_start;
   1590             BCM_DEFIP_PAIR128_ENTRY_SET(unit, range_start, lkup_plen, hash);
   1591         }
   1592     } else {
   1593         rv = _bcm_defip_pair128_shift_range(unit, range_end, free_idx_after);
   1594         if (BCM_SUCCESS(rv)) {
   1595             *hw_index = range_end;
   1596             BCM_DEFIP_PAIR128_ENTRY_SET(unit, range_end, lkup_plen, hash);
   1597         }
   1598     }
   1599     return (rv);
   1600 }
   1601 
   1602 /*
   1603  * Function:
   1604  *      _bcm_l3_defip_pair128_get
   1605  * Purpose:
   1606  *      Get an entry from L3_DEFIP_PAIR_128 table.
   1607  * Parameters:
   1608  *      unit        - (IN)SOC unit number.
   1609  *      lpm_cfg     - (IN)Buffer to fill defip information. 
   1610  *      nh_ecmp_idx - (IN)Next hop or ecmp group index
   1611  * Returns:
   1612  *      BCM_E_XXX
   1613  */
   1614 int 
   1615 _bcm_l3_defip_pair128_get(int unit, _bcm_defip_cfg_t *lpm_cfg, 
   1616                               int *nh_ecmp_idx) 
   1617 {
   1618     uint32 hw_entry[SOC_MAX_MEM_FIELD_WORDS];/* Hw entry buffer.          */
   1619     bcm_ip6_t mask;                          /* Subnet mask.              */
   1620     int clear_hit;                           /* Clear entry hit bit flag. */
   1621     int hw_index;                            /* Entry offset in the TCAM. */ 
   1622     int rv;                                  /* Internal operation status.*/
   1623     soc_mem_t mem = L3_DEFIP_PAIR_128m;
   1624 
   1625     /* Input parameters check. */
   1626     if (lpm_cfg == NULL) {
   1627         return (BCM_E_PARAM);
   1628     }
   1629 
   1630     /* Check if clear hit bit required. */
   1631     clear_hit = lpm_cfg->defip_flags & BCM_L3_HIT_CLEAR;
   1632 
   1633     /* Create mask from prefix length. */
   1634     bcm_ip6_mask_create(mask, lpm_cfg->defip_sub_len);
   1635 
   1636     /* Apply mask on address. */
   1637     bcm_xgs3_l3_mask6_apply(mask, lpm_cfg->defip_ip6_addr);
   1638 
   1639     /* Search for matching entry in the cam. */
   1640     rv =  _bcm_defip_pair128_match(unit, lpm_cfg, hw_entry, &hw_index);
   1641     BCM_IF_ERROR_RETURN(rv);
   1642 
   1643     lpm_cfg->defip_index = hw_index;
   1644 
   1645     /* Parse matched entry. */
   1646     rv = _bcm_defip_pair128_parse(unit, hw_entry, lpm_cfg, nh_ecmp_idx);
   1647     BCM_IF_ERROR_RETURN(rv);
   1648 
   1649     /* Clear the HIT bit */
   1650     if (clear_hit) {
   1651 
   1652 #if defined(BCM_TOMAHAWK3_SUPPORT)
   1653         if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
   1654             mem = L3_DEFIP_PAIR_LEVEL1m;
   1655             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_HIT0f, 0);
   1656             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_HIT1f, 0);
   1657         } else
   1658 #endif
   1659         {
   1660             if (SOC_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_128m, HITf)) {
   1661                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, HITf, 0);
   1662             }
   1663 
   1664             if (SOC_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_128m, HIT0f)) {
   1665                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, HIT0f, 0);
   1666             }
   1667 
   1668             if (SOC_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_128m, HIT1f)) {
   1669                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, HIT1f, 0);
   1670             }
   1671         }
   1672         rv = BCM_XGS3_MEM_WRITE(unit, mem, hw_index, hw_entry);
   1673     }
   1674 
   1675     return (rv);
   1676 }
   1677 
   1678 /*
   1679  * Function:
   1680  *      _bcm_l3_defip_pair128_add
   1681  * Purpose:
   1682  *      Add an entry to internal L3_DEFIP_PAIR_128 table.
   1683  * Parameters:
   1684  *      unit        - (IN)SOC unit number.
   1685  *      lpm_cfg     - (IN)Buffer to fill defip information. 
   1686  *      nh_ecmp_idx - (IN)Next hop or ecmp group index.
   1687  * Returns:
   1688  *      BCM_E_XXX
   1689  */
   1690 int
   1691 _bcm_l3_defip_pair128_add(int unit, _bcm_defip_cfg_t *lpm_cfg,
   1692                               int nh_ecmp_idx) 
   1693 {
   1694     uint32 hw_entry[SOC_MAX_MEM_FIELD_WORDS];   /* New entry hw buffer.      */
   1695     bcm_ip6_t mask;                             /* Subnet mask.              */
   1696     int hw_index = 0;                           /* Entry offset in the TCAM. */ 
   1697     int rv = BCM_E_NONE;                        /* Operation return status.  */
   1698     soc_mem_t mem = L3_DEFIP_PAIR_128m;
   1699 
   1700     uint32 max_v6_entries = BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit);
   1701     uint32 used_cnt = BCM_DEFIP_PAIR128_USED_COUNT(unit);
   1702     /* Input parameters check. */
   1703     if (lpm_cfg == NULL) {
   1704         return (BCM_E_PARAM);
   1705     }
   1706 
   1707     if ((used_cnt >= max_v6_entries) && 
   1708         !(lpm_cfg->defip_flags & BCM_L3_REPLACE)) {
   1709         return BCM_E_FULL;     
   1710     }
   1711 
   1712     /* No support for routes matchin AFTER vrf specific. */
   1713     if (BCM_L3_VRF_GLOBAL == lpm_cfg->defip_vrf) {
   1714         return (BCM_E_UNAVAIL);
   1715     }
   1716 
   1717     /* Zero buffers. */
   1718     sal_memset(hw_entry, 0, WORDS2BYTES(SOC_MAX_MEM_FIELD_WORDS));
   1719 
   1720 #ifdef BCM_TRIDENT3_SUPPORT
   1721     if (soc_feature(unit, soc_feature_flex_flow) &&
   1722         lpm_cfg->defip_flow_handle != 0) {
   1723 
   1724         BCM_IF_ERROR_RETURN(
   1725             _bcm_l3_defip_pair128_flex_add(unit, lpm_cfg, nh_ecmp_idx, hw_entry));
   1726         return BCM_E_NONE;
   1727     }
   1728 #endif
   1729 
   1730     /* Create mask from prefix length. */
   1731     bcm_ip6_mask_create(mask, lpm_cfg->defip_sub_len);
   1732 
   1733     /* Apply mask on address. */
   1734     bcm_xgs3_l3_mask6_apply(mask, lpm_cfg->defip_ip6_addr);
   1735 
   1736     /* Allocate a new index for inserted entry. */
   1737     if (BCM_XGS3_L3_INVALID_INDEX == lpm_cfg->defip_index) {
   1738         rv = _bcm_defip_pair128_idx_alloc(unit, lpm_cfg, &hw_index, nh_ecmp_idx);
   1739         BCM_IF_ERROR_RETURN(rv);
   1740     } else {
   1741         hw_index = lpm_cfg->defip_index;
   1742     }
   1743 
   1744     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_128m)) {
   1745         /* Set hit bit. */
   1746         if (lpm_cfg->defip_flags & BCM_L3_HIT) {
   1747             if (SOC_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_128m, HITf)) {
   1748                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, HITf, 1);
   1749             }
   1750             if (SOC_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_128m, HIT0f)) {
   1751                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, HIT0f, 1);
   1752             }
   1753             if (SOC_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_128m, HIT1f)) {
   1754                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, HIT1f, 1);
   1755             }
   1756         }
   1757     }
   1758 
   1759     /* Set ip mask. */
   1760     _bcm_defip_pair128_ip6_mask_set(unit, mem, hw_entry, mask);
   1761 
   1762 #if defined(BCM_TOMAHAWK3_SUPPORT)
   1763     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
   1764         uint32              ip6_field;
   1765         uint32 _key_data[2] = {0,0};
   1766         uint32          fmte[4] = {0,0,0,0};
   1767 
   1768         mem = L3_DEFIP_PAIR_LEVEL1m;
   1769 
   1770         if (lpm_cfg->defip_flags & BCM_L3_HIT) {
   1771             if (SOC_TH3_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_LEVEL1m, LWR_HIT0f)) {
   1772                 SOC_TH3_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_HIT0f, 1);
   1773             }
   1774             if (SOC_TH3_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_LEVEL1m, LWR_HIT1f)) {
   1775                 SOC_TH3_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_HIT1f, 1);
   1776             }
   1777         }
   1778 
   1779         /* Set valid bits. */
   1780         SOC_TH3_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, UPR_VALID1f, 1);
   1781         SOC_TH3_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, UPR_VALID0f, 1);
   1782         SOC_TH3_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_VALID1f, 1);
   1783         SOC_TH3_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_VALID0f, 1);
   1784 
   1785         ip6_field = ((lpm_cfg->defip_ip6_addr[12] << 24)| (lpm_cfg->defip_ip6_addr[13] << 16) |
   1786                         (lpm_cfg->defip_ip6_addr[14] << 8) | (lpm_cfg->defip_ip6_addr[15] << 0));
   1787         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf, ip6_field);
   1788         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_MODEf, 0x3);
   1789         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_TYPEf, 0x1);
   1790         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, VRF_IDf,
   1791                                (BCM_L3_VRF_OVERRIDE != lpm_cfg->defip_vrf) ? lpm_cfg->defip_vrf:0);
   1792         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)hw_entry, LWR_KEY0f, _key_data);
   1793 
   1794         _key_data[0] = _key_data[1] = 0;
   1795         ip6_field = ((lpm_cfg->defip_ip6_addr[8] << 24)| (lpm_cfg->defip_ip6_addr[9] << 16) |
   1796                         (lpm_cfg->defip_ip6_addr[10] << 8) | (lpm_cfg->defip_ip6_addr[11] << 0));
   1797         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf, ip6_field);
   1798         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_MODEf, 0x3);
   1799         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_TYPEf, 0x1);
   1800         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, VRF_IDf,
   1801                                (BCM_L3_VRF_OVERRIDE != lpm_cfg->defip_vrf) ? lpm_cfg->defip_vrf:0);
   1802         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)hw_entry, LWR_KEY1f, _key_data);
   1803 
   1804         _key_data[0] = _key_data[1] = 0;
   1805         ip6_field = ((lpm_cfg->defip_ip6_addr[4] << 24)| (lpm_cfg->defip_ip6_addr[5] << 16) |
   1806                         (lpm_cfg->defip_ip6_addr[6] << 8) | (lpm_cfg->defip_ip6_addr[7] << 0));
   1807         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf, ip6_field);
   1808         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_MODEf, 0x3);
   1809         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_TYPEf, 0x1);
   1810         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, VRF_IDf,
   1811                                (BCM_L3_VRF_OVERRIDE != lpm_cfg->defip_vrf) ? lpm_cfg->defip_vrf:0);
   1812         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)hw_entry, UPR_KEY0f, _key_data);
   1813 
   1814         _key_data[0] = _key_data[1] = 0;
   1815         ip6_field = ((lpm_cfg->defip_ip6_addr[0] << 24)| (lpm_cfg->defip_ip6_addr[1] << 16) |
   1816                         (lpm_cfg->defip_ip6_addr[2] << 8) | (lpm_cfg->defip_ip6_addr[3] << 0));
   1817         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, IP_ADDRf, ip6_field);
   1818         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_MODEf, 0x3);
   1819         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, KEY_TYPEf, 0x1);
   1820         soc_format_field32_set(unit, L3_DEFIP_TCAM_KEYfmt, _key_data, VRF_IDf,
   1821                                (BCM_L3_VRF_OVERRIDE != lpm_cfg->defip_vrf) ? lpm_cfg->defip_vrf:0);
   1822         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)hw_entry, UPR_KEY1f, _key_data);
   1823 
   1824         sal_memset(fmte, 0, sizeof(fmte));
   1825         if (BCM_L3_VRF_GLOBAL == lpm_cfg->defip_vrf) {
   1826             soc_format_field32_set(unit, FIXED_DATAfmt, fmte,
   1827                                    SUB_DB_PRIORITYf, 2);
   1828         } else if (BCM_L3_VRF_OVERRIDE == lpm_cfg->defip_vrf) {
   1829             soc_format_field32_set(unit, FIXED_DATAfmt, fmte,
   1830                                    SUB_DB_PRIORITYf, 0);
   1831         } else {
   1832             soc_format_field32_set(unit, FIXED_DATAfmt, fmte,
   1833                                    SUB_DB_PRIORITYf, 1);
   1834         }
   1835         soc_mem_field_set(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry,
   1836                           LWR_FIXED_DATA0f, fmte);
   1837 
   1838         fmte[0] = fmte[1] = fmte[2] = fmte[3] = 0;
   1839         if (lpm_cfg->defip_flags & BCM_L3_RPE) {
   1840             soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, RPEf, 1);
   1841         }
   1842         soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, PRIf, lpm_cfg->defip_prio);
   1843         soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, CLASS_IDf,
   1844                                       lpm_cfg->defip_lookup_class);
   1845         if (lpm_cfg->defip_flags & BCM_L3_MULTIPATH) {
   1846             soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, DEST_TYPEf, 1);
   1847         } else if (nh_ecmp_idx != BCM_XGS3_L3_INVALID_INDEX) {
   1848             soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, DEST_TYPEf, 0);
   1849         }
   1850         soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, DESTINATIONf, nh_ecmp_idx);
   1851         if (lpm_cfg->defip_flags & BCM_L3_RPE) {
   1852             soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, RPEf, 1);
   1853         }
   1854         if (lpm_cfg->defip_flags & BCM_L3_DST_DISCARD) {
   1855             soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, DST_DISCARDf, 1);
   1856         }
   1857         soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, CLASS_IDf, lpm_cfg->defip_lookup_class);
   1858         soc_format_field32_set(unit, ASSOC_DATA_FULLfmt, fmte, PRIf, lpm_cfg->defip_prio);
   1859         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)hw_entry, LWR_ASSOC_DATA0f, fmte);
   1860         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)hw_entry, LWR_ASSOC_DATA1f, fmte);
   1861         fmte[0] = fmte[1] = fmte[2] = fmte[3] = 0;
   1862         soc_format_field32_set(unit, ALPM1_DATAfmt, fmte, DIRECT_ROUTEf, 1);
   1863         SOC_TH3_MEM_OPT_FLD_SET(unit, (uint32 *)hw_entry, LWR_ALPM1_DATA0f, fmte);
   1864     } else
   1865 #endif
   1866     {
   1867         /* Set priority override bit. */
   1868         if (lpm_cfg->defip_flags & BCM_L3_RPE) {
   1869             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, RPEf, 1);
   1870         }
   1871 
   1872         /* Set classification group id. */
   1873         SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, CLASS_IDf,
   1874                 lpm_cfg->defip_lookup_class);
   1875 
   1876         /* Write priority field. */
   1877         SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, PRIf, lpm_cfg->defip_prio);
   1878 
   1879 
   1880         /* Fill next hop information. */
   1881         if (lpm_cfg->defip_flags & BCM_L3_MULTIPATH) {
   1882             if (soc_feature(unit, soc_feature_generic_dest)) {
   1883                 soc_mem_field32_dest_set(unit, L3_DEFIP_PAIR_128m, hw_entry,
   1884                     DESTINATIONf, SOC_MEM_FIF_DEST_ECMP, nh_ecmp_idx);
   1885             } else {
   1886                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry,
   1887                                       ECMP_PTRf, nh_ecmp_idx);
   1888                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, ECMPf, 1);
   1889             }
   1890         } else if (!(lpm_cfg->defip_flags & BCM_L3_IPMC)) {
   1891             if (soc_feature(unit, soc_feature_generic_dest)) {
   1892                 soc_mem_field32_dest_set(unit, L3_DEFIP_PAIR_128m, hw_entry,
   1893                     DESTINATIONf, SOC_MEM_FIF_DEST_NEXTHOP, nh_ecmp_idx);
   1894             } else {
   1895                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry,
   1896                                       NEXT_HOP_INDEXf, nh_ecmp_idx);
   1897             }
   1898         }
   1899 
   1900         /* Set destination discard flag. */
   1901         if (lpm_cfg->defip_flags & BCM_L3_DST_DISCARD) {
   1902             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, DST_DISCARDf, 1);
   1903         }
   1904 
   1905         /* Set mode bits to indicate IP v6 128b pair mode */
   1906         if (soc_mem_field_valid(unit, L3_DEFIP_PAIR_128m, KEY_MODE0_UPRf)) {
   1907             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry, KEY_MODE1_UPRf, 0x3);
   1908             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry, KEY_MODE0_UPRf, 0x3);
   1909             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry, KEY_MODE1_LWRf, 0x3);
   1910             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry, KEY_MODE0_LWRf, 0x3);
   1911 
   1912             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry, KEY_MODE_MASK1_UPRf, 0x3);
   1913             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry, KEY_MODE_MASK0_UPRf, 0x3);
   1914             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry, KEY_MODE_MASK1_LWRf, 0x3);
   1915             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry, KEY_MODE_MASK0_LWRf, 0x3);
   1916         } else {
   1917             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, MODE1_UPRf, 0x3);
   1918             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, MODE0_UPRf, 0x3);
   1919             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, MODE1_LWRf, 0x3);
   1920             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, MODE0_LWRf, 0x3);
   1921 
   1922             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, MODE_MASK1_UPRf, 0x3);
   1923             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, MODE_MASK0_UPRf, 0x3);
   1924             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, MODE_MASK1_LWRf, 0x3);
   1925             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, MODE_MASK0_LWRf, 0x3);
   1926         }
   1927 
   1928 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
   1929         if (soc_feature(unit, soc_feature_ipmc_defip) &&
   1930                 (lpm_cfg->defip_flags & BCM_L3_IPMC)) {
   1931 
   1932         if (soc_mem_field_valid(unit, L3_DEFIP_PAIR_128m, MULTICAST_ROUTEf)) {
   1933             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, MULTICAST_ROUTEf, 1);
   1934         } else if (soc_mem_field_valid(unit, L3_DEFIP_PAIR_128m, DATA_TYPEf)) {
   1935             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry, DATA_TYPEf, 2);
   1936         }
   1937 
   1938         if (soc_feature(unit, soc_feature_generic_dest)) {
   1939             if (lpm_cfg->defip_mc_group > 0) {
   1940                 soc_mem_field32_dest_set(unit, L3_DEFIP_PAIR_128m, hw_entry,
   1941                                          DESTINATIONf, SOC_MEM_FIF_DEST_IPMC,
   1942                                          lpm_cfg->defip_mc_group);
   1943             }
   1944         } else {
   1945             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, L3MC_INDEXf, lpm_cfg->defip_mc_group);
   1946         }
   1947 
   1948             /*
   1949              * RP ID has be encoded to 14 bit value, Now it will fit in EXPECTED_L3_IIFf
   1950              */
   1951             if (lpm_cfg->defip_l3a_rp != BCM_IPMC_RP_ID_INVALID) {
   1952                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, EXPECTED_L3_IIFf,
   1953                                         _BCM_DEFIP_IPMC_RP_SET(lpm_cfg->defip_l3a_rp));
   1954 
   1955             } else if ((lpm_cfg->defip_ipmc_flags & BCM_IPMC_POST_LOOKUP_RPF_CHECK) &&
   1956                     (lpm_cfg->defip_expected_intf != 0))  {
   1957 
   1958                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, EXPECTED_L3_IIFf, lpm_cfg->defip_expected_intf);
   1959 
   1960                 if (lpm_cfg->defip_ipmc_flags & BCM_IPMC_RPF_FAIL_DROP) {
   1961                     SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, IPMC_EXPECTED_L3_IIF_MISMATCH_DROPf, 1);
   1962                 }
   1963                 if (lpm_cfg->defip_ipmc_flags & BCM_IPMC_RPF_FAIL_TOCPU) {
   1964                     SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, IPMC_EXPECTED_L3_IIF_MISMATCH_TOCPUf, 1);
   1965                 }
   1966             }
   1967         }
   1968 #endif
   1969 
   1970         /* Set valid bits. */
   1971         SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VALID1_UPRf, 1);
   1972         SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VALID0_UPRf, 1);
   1973         SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VALID1_LWRf, 1);
   1974         SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VALID0_LWRf, 1);
   1975 
   1976         /* Set destination/source ip address. */
   1977         _bcm_defip_pair128_ip6_addr_set(unit, L3_DEFIP_PAIR_128m, hw_entry, lpm_cfg->defip_ip6_addr);
   1978 
   1979         /* Set vrf id & vrf mask. */
   1980         if (BCM_L3_VRF_OVERRIDE != lpm_cfg->defip_vrf) {
   1981             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_0_LWRf, lpm_cfg->defip_vrf);
   1982             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_1_LWRf, lpm_cfg->defip_vrf);
   1983             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_0_UPRf, lpm_cfg->defip_vrf);
   1984             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_1_UPRf, lpm_cfg->defip_vrf);
   1985             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_MASK0_LWRf,
   1986                                 (1 << SOC_MEM_OPT_FLD_LENGTH(unit, L3_DEFIP_PAIR_128m,
   1987                                                            VRF_ID_MASK0_LWRf)) - 1);
   1988             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_MASK1_LWRf,
   1989                                 (1 << SOC_MEM_OPT_FLD_LENGTH(unit, L3_DEFIP_PAIR_128m,
   1990                                                            VRF_ID_MASK1_LWRf)) - 1);
   1991             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_MASK0_UPRf,
   1992                                 (1 << SOC_MEM_OPT_FLD_LENGTH(unit, L3_DEFIP_PAIR_128m,
   1993                                                            VRF_ID_MASK0_UPRf)) - 1);
   1994             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_MASK1_LWRf,
   1995                                 (1 << SOC_MEM_OPT_FLD_LENGTH(unit, L3_DEFIP_PAIR_128m,
   1996                                                            VRF_ID_MASK1_UPRf)) - 1);
   1997             if (SOC_MEM_OPT_FLD_VALID(unit, L3_DEFIP_PAIR_128m, GLOBAL_ROUTEf)) {
   1998                 SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, GLOBAL_ROUTEf, 0);
   1999             }
   2000         } else {
   2001             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_0_LWRf, 0);
   2002             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_1_LWRf, 0);
   2003             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_0_UPRf, 0);
   2004             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_1_UPRf, 0);
   2005             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_MASK0_LWRf, 0);
   2006             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_MASK1_LWRf, 0);
   2007             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_MASK0_UPRf, 0);
   2008             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, VRF_ID_MASK1_UPRf, 0);
   2009         }
   2010 
   2011         /* Configure entry for SIP lookup if URPF is enabled. This => SIP is default route.*/
   2012         /* If soc_feature_l3_defip_advanced_lookup is TRUE then
   2013          * both DIP and SIP lookup is done using 1 L3_DEFIP entry.
   2014          * L3_DEFIP table is not divided into 2 to support URPF (Ex: KT2).
   2015          */
   2016         if (soc_feature(unit, soc_feature_l3_defip_advanced_lookup)) {
   2017             SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, DEFAULTROUTEf,
   2018                 (SOC_URPF_STATUS_GET(unit) ? 1 : 0));
   2019 
   2020         }
   2021     }
   2022 
   2023     /* Write buffer to hw. */
   2024     rv = BCM_XGS3_MEM_WRITE(unit, mem, hw_index, hw_entry);
   2025     if (BCM_FAILURE(rv)) {
   2026         BCM_DEFIP_PAIR128_ENTRY_SET(unit, hw_index, 0, 0);
   2027         return (rv);
   2028     }
   2029 
   2030     /* Write source lookup portion of the entry. */
   2031     /* If soc_feature_l3_defip_advanced_lookup is TRUE then 
   2032      * both DIP and SIP lookup is done using 1 L3_DEFIP entry.
   2033      * L3_DEFIP table is not divided into 2 to support URPF (Ex: KT2).
   2034      */
   2035     if (SOC_URPF_STATUS_GET(unit) &&
   2036         !soc_feature(unit, soc_feature_l3_defip_advanced_lookup) &&
   2037         SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_128m)) {
   2038         SOC_MEM_OPT_FLD32_SET(unit, L3_DEFIP_PAIR_128m, hw_entry, SRC_DISCARDf, 0);
   2039         if (SOC_IS_TRIDENT3(unit)) {
   2040             soc_mem_field32_set(unit, L3_DEFIP_PAIR_128m, hw_entry,
   2041                                 FLEX_CTR_BASE_COUNTER_IDXf, 0);
   2042         }
   2043 
   2044         rv = BCM_XGS3_MEM_WRITE(unit, L3_DEFIP_PAIR_128m,
   2045                     (hw_index + BCM_DEFIP_PAIR128_URPF_OFFSET(unit)), hw_entry);
   2046         if (BCM_FAILURE(rv)) {
   2047             _bcm_defip_pair128_entry_clear(unit, hw_index);
   2048             return (rv);
   2049         }
   2050     }
   2051 
   2052     /* If new route added increment total number of routes.  */
   2053     /* Lack of index indicates a new route. */
   2054     if (BCM_XGS3_L3_INVALID_INDEX == lpm_cfg->defip_index) {
   2055         BCM_XGS3_L3_DEFIP_CNT_INC(unit, TRUE);
   2056         BCM_DEFIP_PAIR128_USED_COUNT(unit)++;
   2057         soc_lpm_stat_128b_count_update(unit, 1);
   2058     }
   2059 
   2060     return rv;
   2061 
   2062 }
   2063 
   2064 /*
   2065  * Function:
   2066  *      _bcm_l3_defip_pair128_del
   2067  * Purpose:
   2068  *      Delete an entry from L3_DEFIP_PAIR_128 table.
   2069  * Parameters:
   2070  *      unit    - (IN)SOC unit number.
   2071  *      lpm_cfg - (IN)Buffer to fill defip information. 
   2072  * Returns:
   2073  *      BCM_E_XXX
   2074  */
   2075 int 
   2076 _bcm_l3_defip_pair128_del(int unit, _bcm_defip_cfg_t *lpm_cfg) 
   2077 {
   2078     uint32 hw_entry[SOC_MAX_MEM_FIELD_WORDS];/* Hw entry buffer.          */
   2079     uint32 temp_hw_entry[SOC_MAX_MEM_FIELD_WORDS];/* Hw entry buffer.          */
   2080     bcm_ip6_t mask;                          /* Subnet mask.              */
   2081     int hw_index;                            /* Entry offset in the TCAM. */ 
   2082     int rv;    
   2083     _bcm_defip_cfg_t temp_lpm;
   2084     int temp_nh_ecmp_idx, idx;
   2085 
   2086     /* Input parameters check. */
   2087     if (lpm_cfg == NULL) {
   2088         return (BCM_E_PARAM);
   2089     }
   2090 
   2091     /* Create mask from prefix length. */
   2092     bcm_ip6_mask_create(mask, lpm_cfg->defip_sub_len);
   2093 
   2094     /* Apply mask on address. */
   2095     bcm_xgs3_l3_mask6_apply(mask, lpm_cfg->defip_ip6_addr);
   2096     /* Search for matching entry in theL3_DEFIP_PAIR_128  cam.  */
   2097     rv =  _bcm_defip_pair128_match(unit, lpm_cfg, hw_entry, &hw_index);
   2098     if (BCM_FAILURE(rv)) {
   2099         return (rv);
   2100     }
   2101 
   2102     /* Delete entry from hardware & software (L3_DEFIP_PAIR_128m). */
   2103     rv = _bcm_defip_pair128_entry_clear(unit, hw_index);
   2104     if (BCM_SUCCESS(rv)) {
   2105         BCM_XGS3_L3_DEFIP_CNT_DEC(unit, TRUE);
   2106         BCM_DEFIP_PAIR128_USED_COUNT(unit)--;
   2107         soc_lpm_stat_128b_count_update(unit, 0);
   2108         /* Delete valid entry at highest index (or lowest LPM) in 
   2109          * L3_DEFIP_128m table if available
   2110          * and add it to L3_DEFIP_PAIR_128m */
   2111         hw_index = BCM_DEFIP_PAIR128_IDX_MAX(unit);
   2112         for (idx = BCM_DEFIP_PAIR128_IDX_MAX(unit); idx >=0; idx--) {
   2113             if (0 == BCM_DEFIP_PAIR128_ARR(unit)[idx].prefix_len) {
   2114                 hw_index =  idx - 1;
   2115                 continue;
   2116             }
   2117             break;
   2118         }
   2119 
   2120         rv = BCM_XGS3_MEM_READ(unit, L3_DEFIP_128m, hw_index, &temp_hw_entry);
   2121         if (rv != BCM_E_NONE && rv != BCM_E_UNAVAIL) {  
   2122             return rv;
   2123         }
   2124         if (rv != BCM_E_UNAVAIL) {
   2125             sal_memset(&temp_lpm, 0, sizeof(_bcm_defip_cfg_t));
   2126             /* Parse entry. */
   2127             rv = _bcm_defip_pair128_parse(unit, temp_hw_entry,
   2128                                                 &temp_lpm, &temp_nh_ecmp_idx);
   2129             BCM_IF_ERROR_RETURN(rv);
   2130         
   2131             /* Extract entry address vrf */
   2132             rv =  _bcm_defip_pair128_get_key(unit, temp_hw_entry, &temp_lpm);
   2133             BCM_IF_ERROR_RETURN(rv);
   2134 
   2135             /* Add the copied entry to L3_DEFIP_PAIR_128 table */
   2136             temp_lpm.defip_index = BCM_XGS3_L3_INVALID_INDEX;
   2137             rv = _bcm_l3_defip_pair128_add(unit, &temp_lpm, temp_nh_ecmp_idx);
   2138             BCM_IF_ERROR_RETURN(rv);
   2139 
   2140             
   2141             /* Delete entry from L3_DEFIP_128 table. */
   2142             temp_lpm.defip_index = hw_index;
   2143             rv = BCM_E_UNAVAIL;
   2144             rv = _bcm_l3_defip_pair128_del(unit, &temp_lpm);
   2145             return rv;
   2146         }
   2147         return BCM_E_NONE;  
   2148     }
   2149     return (rv);
   2150 }
   2151 
   2152 /*
   2153  * Function:
   2154  *      _bcm_l3_defip_pair128_update_match
   2155  * Purpose:
   2156  *      Update/Delete all entries in defip table matching a certain rule.
   2157  * Parameters:
   2158  *      unit     - (IN)SOC unit number.
   2159  *      trv_data - (IN)Delete pattern + compare,act,notify routines.  
   2160  * Returns:
   2161  *      BCM_E_XXX
   2162  */
   2163 int
   2164 _bcm_l3_defip_pair128_update_match(int unit, _bcm_l3_trvrs_data_t *trv_data)
   2165 {
   2166     int idx;                                 /* Iteration index.           */
   2167     int rv;                                  /* Operation return status.   */
   2168     int cmp_result;                          /* Test routine result.       */
   2169     int nh_ecmp_idx;                         /* Next hop/Ecmp group index. */
   2170     uint32 *hw_entry;                        /* Hw entry buffer.           */
   2171     char *lpm_tbl_ptr;                       /* Dma table pointer.         */
   2172     int defip_pair128_tbl_size;                    /* Defip table size.          */
   2173     _bcm_defip_cfg_t lpm_cfg;                /* Buffer to fill route info. */
   2174     _bcm_trvs_range_t *range_info;
   2175     int max_index,start_index = 0;               /* START/MAX index to traverse on Entries. */
   2176     soc_mem_t  mem = L3_DEFIP_PAIR_128m;
   2177     int validf = 0;
   2178 
   2179     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
   2180         mem = L3_DEFIP_PAIR_LEVEL1m;
   2181     }
   2182     /* Table DMA the LPM table to software copy */
   2183     BCM_IF_ERROR_RETURN
   2184         (bcm_xgs3_l3_tbl_dma(unit, mem, BCM_L3_MEM_ENT_SIZE(unit, mem),
   2185                              "lpm_tbl", &lpm_tbl_ptr, &defip_pair128_tbl_size));
   2186 
   2187     /* If soc_feature_l3_defip_advanced_lookup is TRUE then 
   2188      * both DIP and SIP lookup is done using 1 L3_DEFIP entry.
   2189      * L3_DEFIP table is not divided into 2 to support URPF (Ex: KT2).
   2190      */
   2191     if (SOC_URPF_STATUS_GET(unit) &&
   2192         !soc_feature(unit, soc_feature_l3_defip_advanced_lookup)) {
   2193         defip_pair128_tbl_size >>= 1;
   2194         BCM_DEFIP_PAIR128_URPF_OFFSET(unit) = defip_pair128_tbl_size;
   2195     } 
   2196 
   2197     max_index = defip_pair128_tbl_size - 1;
   2198     if (!(trv_data->flags & BCM_XGS3_L3_OP_DEL)) {
   2199         range_info = trv_data->pattern;
   2200         if ((range_info != NULL) && (defip_pair128_tbl_size > range_info->end)) {
   2201             max_index = range_info->end;
   2202             start_index = range_info->start;
   2203             range_info->current_count =  start_index;
   2204         }
   2205     }
   2206 
   2207     for (idx = start_index ; idx <= max_index; idx++) {
   2208         /* Calculate entry ofset. */
   2209         hw_entry = soc_mem_table_idx_to_pointer(unit, mem, uint32 *,
   2210                                                 lpm_tbl_ptr, idx);
   2211 
   2212 #if defined(BCM_TOMAHAWK3_SUPPORT)
   2213         if (SOC_MEM_IS_VALID(unit, L3_DEFIP_PAIR_LEVEL1m)) {
   2214             validf = SOC_TH3_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_LEVEL1m, hw_entry, LWR_VALID0f);
   2215         } else
   2216 #endif
   2217         {
   2218             validf = SOC_MEM_OPT_FLD32_GET(unit, L3_DEFIP_PAIR_128m, hw_entry, VALID0_LWRf);
   2219         }
   2220 
   2221         /* Make sure entry is valid. */
   2222         if (!validf) {
   2223             continue;
   2224         }
   2225 
   2226         /* Zero destination buffer first. */
   2227         sal_memset(&lpm_cfg, 0, sizeof(_bcm_defip_cfg_t));
   2228 
   2229         /* Parse  the entry. */
   2230         _bcm_defip_pair128_parse(unit, hw_entry, &lpm_cfg, &nh_ecmp_idx);
   2231        lpm_cfg.defip_index = idx;
   2232 
   2233         /* Fill entry ip address &  subnet mask. */
   2234         _bcm_defip_pair128_get_key(unit, hw_entry, &lpm_cfg);
   2235 
   2236         /* Execute operation routine if any. */
   2237         if (trv_data->op_cb) {
   2238             rv = (*trv_data->op_cb) (unit, (void *)trv_data,
   2239                                      (void *)&lpm_cfg,
   2240                                      (void *)&nh_ecmp_idx, &cmp_result);
   2241             if (BCM_FAILURE(rv)) {
   2242                 soc_cm_sfree(unit, lpm_tbl_ptr);
   2243                 return rv;
   2244             }
   2245         }
   2246 #ifdef BCM_WARM_BOOT_SUPPORT
   2247         if (SOC_WARM_BOOT(unit)) {
   2248             rv = _bcm_defip_pair128_reinit(unit, idx, &lpm_cfg);
   2249             if (BCM_FAILURE(rv)) {
   2250                 soc_cm_sfree(unit, lpm_tbl_ptr);
   2251                 return rv;
   2252             }
   2253         }
   2254 #endif /* BCM_WARM_BOOT_SUPPORT */
   2255     }
   2256     
   2257 #ifdef BCM_WARM_BOOT_SUPPORT
   2258     if (SOC_WARM_BOOT(unit)) {
   2259         SOC_IF_ERROR_RETURN(soc_fb_lpm_reinit_done(unit, 1));
   2260     }
   2261 #endif /* BCM_WARM_BOOT_SUPPORT */
   2262     soc_cm_sfree(unit, lpm_tbl_ptr);
   2263     return (BCM_E_NONE);
   2264 }
   2265 
   2266 /* Configure L3_DEFIP_KEY_SELr register */
   2267 int
   2268 _bcm_l3_defip_key_sel_set(int unit, int urpf, int tcam_pair_count)
   2269 {
   2270     int i;
   2271     soc_reg_t key_selr = L3_DEFIP_KEY_SELr;
   2272     uint32 defip_key_sel_val = 0;
   2273     soc_field_t key_sel_f[4] = {
   2274         V6_KEY_SEL_CAM0_1f,
   2275         V6_KEY_SEL_CAM2_3f,
   2276         V6_KEY_SEL_CAM4_5f,
   2277         V6_KEY_SEL_CAM6_7f
   2278     };
   2279     /* Trident3 Style */
   2280     soc_field_t key_sel_f2[4] = {
   2281         KEY_SEL_CAM0_1f,
   2282         KEY_SEL_CAM2_3f,
   2283         KEY_SEL_CAM4_5f,
   2284         KEY_SEL_CAM6_7f
   2285     };
   2286 
   2287     /* Key sel value
   2288      *   2,   0x00b non-URPF + lpm-64b
   2289      *   0,   0x01b non-URPF + lpm-128b
   2290      *   3,   0x10b uRPF + lpm-64b
   2291      *   1    0x11b uRPF + lpm-128b
   2292      */
   2293     if (tcam_pair_count < 0 || tcam_pair_count > 4) {
   2294         return BCM_E_NONE;
   2295     }
   2296 
   2297     if (soc_reg_field_valid(unit, key_selr, KEY_SEL_CAM0_1f)) {
   2298         /* Trident3 Style */
   2299         if (urpf) {
   2300             switch (tcam_pair_count) {
   2301                 case 0:
   2302                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2303                                       key_sel_f2[0], 2);
   2304                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2305                                       key_sel_f2[1], 2);
   2306                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2307                                       key_sel_f2[2], 3);
   2308                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2309                                       key_sel_f2[3], 3);
   2310                     break;
   2311                 case 1:
   2312                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2313                                       key_sel_f2[0], 0);
   2314                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2315                                       key_sel_f2[1], 2);
   2316                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2317                                       key_sel_f2[2], 1);
   2318                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2319                                       key_sel_f2[3], 3);
   2320                     break;
   2321                 case 2:
   2322                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2323                                       key_sel_f2[0], 0);
   2324                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2325                                       key_sel_f2[1], 2);
   2326                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2327                                       key_sel_f2[2], 1);
   2328                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2329                                       key_sel_f2[3], 3);
   2330                     break;
   2331                 case 3:
   2332                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2333                                       key_sel_f2[0], 0);
   2334                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2335                                       key_sel_f2[1], 0);
   2336                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2337                                       key_sel_f2[2], 1);
   2338                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2339                                       key_sel_f2[3], 1);
   2340                     break;
   2341                 case 4:
   2342                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2343                                       key_sel_f2[0], 0);
   2344                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2345                                       key_sel_f2[1], 0);
   2346                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2347                                       key_sel_f2[2], 1);
   2348                     soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2349                                       key_sel_f2[3], 1);
   2350                     break;
   2351                 /* coverity[dead_error_begin : FALSE] */
   2352                 default:
   2353                     break;
   2354             }
   2355         } else {
   2356             for (i = 0; i < (4 - tcam_pair_count); i++) {
   2357                 soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2358                                   key_sel_f2[3 - i], 2);
   2359             }
   2360         }
   2361     } else {
   2362         for (i = 0; i < tcam_pair_count; i++) {
   2363             soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2364                               key_sel_f[i], 0x1);
   2365         }
   2366 
   2367         if (urpf) {
   2368             soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2369                               URPF_LOOKUP_CAM4f, 0x1);
   2370             soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2371                               URPF_LOOKUP_CAM5f, 0x1);
   2372             soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2373                               URPF_LOOKUP_CAM6f, 0x1);
   2374             soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2375                               URPF_LOOKUP_CAM7f, 0x1);
   2376 
   2377             if (tcam_pair_count == 1) {
   2378                 soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2379                                   key_sel_f[2], 0x1);
   2380             } else if (tcam_pair_count == 2) {
   2381                 soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2382                                   key_sel_f[1], 0);
   2383                 soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2384                                   key_sel_f[2], 0x1);
   2385             } else if (tcam_pair_count == 3) {
   2386                 soc_reg_field_set(unit, key_selr, &defip_key_sel_val,
   2387                                   key_sel_f[3], 0x1);
   2388             }
   2389         }
   2390     }
   2391 
   2392     BCM_IF_ERROR_RETURN(WRITE_L3_DEFIP_KEY_SELr(unit, defip_key_sel_val));
   2393     return BCM_E_NONE;
   2394 }
   2395 
   2396 /*
   2397  * Function:
   2398  *      _bcm_l3_defip_init
   2399  * Purpose:
   2400  *      Configure TD2 internal route table as per soc properties.
   2401  *      (tcam pairing for IPv4, 64/128 bit IPV6 prefixes)
   2402  * Parameters:
   2403  *      unit     - (IN)SOC unit number.
   2404  * Returns:
   2405  *      BCM_E_XXX
   2406  */
   2407 int
   2408 _bcm_l3_defip_init(int unit)
   2409 {
   2410     int num_ipv6_128b_entries;
   2411     int mem_v4, mem_v6, mem_v6_128; /* Route table memories */
   2412     int ipv6_64_depth = 0;
   2413     int start_index = 0;
   2414     int tcam_pair_count = 0;
   2415     int tcam_depth = SOC_L3_DEFIP_TCAM_DEPTH_GET(unit);
   2416 
   2417     num_ipv6_128b_entries =  SOC_L3_DEFIP_MAX_128B_ENTRIES(unit);
   2418     BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit) = num_ipv6_128b_entries;
   2419 #ifdef ALPM_ENABLE
   2420     /* ALPM Mode */
   2421     if (soc_property_get(unit, spn_L3_ALPM_ENABLE, 0)) {
   2422         int rv = BCM_E_NONE;
   2423         if (soc_feature(unit, soc_feature_alpm)) {
   2424             if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit)) {
   2425                 rv = soc_alpm_init(unit);
   2426             }
   2427 #if defined(BCM_TOMAHAWK_SUPPORT)
   2428             else if (soc_feature(unit, soc_feature_alpm2)) {
   2429                 rv = bcm_esw_alpm_init(unit);
   2430             }
   2431 #endif
   2432 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)
   2433             else {
   2434                 rv = soc_th_alpm_init(unit);
   2435             }
   2436 #endif
   2437             if (BCM_SUCCESS(rv)) {
   2438                 LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2439                             (BSL_META_U(unit,
   2440                                         "ALPM mode initialized\n")));
   2441             } else {
   2442                 LOG_ERROR(BSL_LS_BCM_ALPM,
   2443                           (BSL_META_U(unit,
   2444                                       "ALPM mode initialization failed, "
   2445                                       "retVal = %d\n"), rv));
   2446             }
   2447             return rv;
   2448         } else {
   2449             LOG_WARN(BSL_LS_BCM_ALPM,
   2450                      (BSL_META_U(unit,
   2451                       "ALPM feature is not available in this device.\n")));
   2452         }
   2453     }
   2454 #else /* ALPM_ENABLE */
   2455     if (soc_feature(unit, soc_feature_alpm) &&
   2456         soc_property_get(unit, spn_L3_ALPM_ENABLE, 0)) {
   2457         LOG_WARN(BSL_LS_BCM_ALPM,
   2458                  (BSL_META_U(unit,
   2459                              "ALPM mode support is not compiled. Please, "
   2460                              "recompile the SDK with ALPM_ENABLE proprocessor variable "
   2461                              "defined\n")));
   2462     }
   2463 #endif /* ALPM_ENABLE */
   2464 
   2465     SOC_IF_ERROR_RETURN(soc_fb_lpm_tcam_pair_count_get(unit, &tcam_pair_count));
   2466 
   2467     if (!SOC_IS_TOMAHAWK3(unit)) {
   2468         BCM_IF_ERROR_RETURN(_bcm_l3_defip_key_sel_set(unit,
   2469             SOC_URPF_STATUS_GET(unit), tcam_pair_count));
   2470     }
   2471     if(!SOC_MEM_IS_VALID(unit, L3_DEFIPm)) {
   2472         if (SOC_MEM_IS_VALID(unit, L3_DEFIP_LEVEL1m)) {
   2473             ipv6_64_depth =  soc_mem_index_count(unit, L3_DEFIP_LEVEL1m);
   2474         }
   2475     } else {
   2476         ipv6_64_depth =  soc_mem_index_count(unit, L3_DEFIPm);
   2477     }
   2478 
   2479     /* Get memory for IPv4 entries. */
   2480     BCM_IF_ERROR_RETURN(_bcm_l3_defip_mem_get(unit, 0, 0, &mem_v4));
   2481 
   2482     /* Initialize IPv4 entries lookup engine. */
   2483     BCM_IF_ERROR_RETURN(soc_fb_lpm_init(unit));
   2484 
   2485     /* Overriding defaults set during lpm init */
   2486 
   2487     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   2488         BCM_IF_ERROR_RETURN(soc_fb_lpm128_init(unit));
   2489         ipv6_64_depth -= (tcam_pair_count * tcam_depth * 2);
   2490         start_index = (tcam_pair_count * tcam_depth * 2);
   2491     } else {
   2492         start_index = 0;
   2493     }
   2494 
   2495     SOC_LPM_STATE_START(unit, (MAX_PFX_INDEX(unit))) = start_index;
   2496     SOC_LPM_STATE_END(unit, (MAX_PFX_INDEX(unit)))   = start_index - 1;
   2497 
   2498     SOC_LPM_STATE_FENT(unit, (MAX_PFX_INDEX(unit))) = ipv6_64_depth;
   2499     BCM_IF_ERROR_RETURN(soc_fb_lpm_state_config(unit, ipv6_64_depth, 
   2500                                                 start_index));    
   2501 
   2502     /* Get memory for IPv6 entries. */
   2503     BCM_IF_ERROR_RETURN
   2504         (_bcm_l3_defip_mem_get(unit, BCM_L3_IP6, 0, &mem_v6));
   2505 
   2506     /* Get memory for IPv6 entries with prefix length > 64. */
   2507     BCM_IF_ERROR_RETURN
   2508         (_bcm_l3_defip_mem_get(unit, BCM_L3_IP6,
   2509                                   BCM_XGS3_L3_IPV6_PREFIX_LEN,
   2510                                   &mem_v6_128));
   2511 
   2512     /* Initialize IPv6 entries lookup engine. */
   2513     if (mem_v6 != mem_v6_128) {
   2514         if (!soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   2515             BCM_IF_ERROR_RETURN(_bcm_defip_pair128_init(unit));
   2516         }
   2517     }
   2518 
   2519     return BCM_E_NONE;
   2520 }
   2521 
   2522 /*
   2523  * Function:
   2524  *      _bcm_l3_defip_deinit
   2525  * Purpose:
   2526  *      De-initialize route table for trident2 devices.
   2527  * Parameters:
   2528  *      unit - (IN)  SOC unit number.
   2529  * Returns:
   2530  *      BCM_E_XXX
   2531  */
   2532 int 
   2533 _bcm_l3_defip_deinit(int unit)
   2534 {
   2535     soc_mem_t mem_v4;      /* IPv4 Route table memory.             */
   2536     soc_mem_t mem_v6;      /* IPv6 Route table memory.             */
   2537     soc_mem_t mem_v6_128;  /* IPv6 full prefix route table memory. */
   2538 
   2539     /* Get memory for IPv4 entries. */
   2540     BCM_IF_ERROR_RETURN(_bcm_l3_defip_mem_get(unit, 0, 0, &mem_v4));
   2541 
   2542     /* Initialize IPv4 entries lookup engine. */
   2543     BCM_IF_ERROR_RETURN(soc_fb_lpm_deinit(unit));
   2544 
   2545     /* Get memory for IPv6 entries. */
   2546     BCM_IF_ERROR_RETURN
   2547         (_bcm_l3_defip_mem_get(unit, BCM_L3_IP6, 0, &mem_v6));
   2548 
   2549     /* Initialize IPv6 entries lookup engine. */
   2550     if (mem_v4 != mem_v6) {
   2551         BCM_IF_ERROR_RETURN(soc_fb_lpm_deinit(unit));
   2552     }
   2553 
   2554     /* Get memory for IPv6 entries with prefix length > 64. */
   2555     BCM_IF_ERROR_RETURN
   2556         (_bcm_l3_defip_mem_get(unit, BCM_L3_IP6,
   2557                                   BCM_XGS3_L3_IPV6_PREFIX_LEN,
   2558                                   &mem_v6_128));
   2559 
   2560     /* Initialize IPv6 entries lookup engine. */
   2561     if (mem_v6 != mem_v6_128) {
   2562          if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {   
   2563              BCM_IF_ERROR_RETURN(soc_fb_lpm128_deinit(unit));   
   2564          } else {
   2565              BCM_IF_ERROR_RETURN(_bcm_defip_pair128_deinit(unit));
   2566          } 
   2567     }
   2568 
   2569 #ifdef ALPM_ENABLE
   2570     /* Delete WAR entries before uRPF status change, or we may not  
   2571      * be able to delete the old WAR entries after status change, 
   2572      * because alpm_lpm_deinit is currently inside alpm_lpm_init which
   2573      * will try to delete WAR uRPF entry which is not exist before uPRF 
   2574      * status change.
   2575      */
   2576     (void) soc_alpm_ipmc_war(unit, FALSE);
   2577     (void) soc_alpm_128_ipmc_war(unit, FALSE);
   2578 #endif
   2579 
   2580     return (BCM_E_NONE);
   2581 }
   2582 
   2583 STATIC int
   2584 _bcm_l3_lpm_table_sizes_get(int unit, int *paired_table_size, 
   2585                             int *defip_table_size)
   2586 {
   2587     return soc_fb_lpm_table_sizes_get(unit, paired_table_size, 
   2588                                       defip_table_size);
   2589 }
   2590 
   2591 int 
   2592 _bcm_l3_is_v4_64b_allowed_in_paired_tcam(int unit)
   2593 {
   2594     return soc_fb_lpm128_is_v4_64b_allowed_in_paired_tcam(unit);
   2595 }
   2596 
   2597 int
   2598 _bcm_l3_scaled_lpm_get(int unit, _bcm_defip_cfg_t *lpm_cfg, int *nh_ecmp_idx)
   2599 {
   2600     int rv = BCM_E_NOT_FOUND;
   2601     int defip_table_size = 0;
   2602     int paired_table_size = 0;
   2603  
   2604     if (!soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   2605        return BCM_E_UNAVAIL;
   2606     }
   2607 
   2608     BCM_IF_ERROR_RETURN(_bcm_l3_lpm_table_sizes_get(unit, &paired_table_size,
   2609                                                     &defip_table_size));
   2610 
   2611     if (paired_table_size == 0 && lpm_cfg->defip_sub_len > 64) {
   2612         return BCM_E_NOT_FOUND;
   2613     }
   2614 
   2615     if ((paired_table_size != 0) && 
   2616         (lpm_cfg->defip_sub_len > 64 || defip_table_size == 0)) {
   2617         return  _bcm_fb_lpm128_get(unit, lpm_cfg, nh_ecmp_idx);
   2618     }
   2619   
   2620     rv = _bcm_fb_lpm_get(unit, lpm_cfg, nh_ecmp_idx);
   2621     if ((rv == BCM_E_NOT_FOUND) && 
   2622          _bcm_l3_is_v4_64b_allowed_in_paired_tcam(unit)) {
   2623         rv =  _bcm_fb_lpm128_get(unit, lpm_cfg, nh_ecmp_idx);
   2624         if (BCM_FAILURE(rv)) {
   2625             lpm_cfg->defip_flags_high &= ~BCM_XGS3_L3_ENTRY_IN_DEFIP_PAIR;
   2626         }
   2627     }
   2628  
   2629     return rv;
   2630 }
   2631 
   2632 /*
   2633  * Function:
   2634  *      _bcm_l3_lpm_get
   2635  * Purpose:
   2636  *      Get an entry from the route table.
   2637  * Parameters:
   2638  *      unit        - (IN)SOC unit number.
   2639  *      lpm_cfg     - (IN)Buffer to fill defip information. 
   2640  *      nh_ecmp_idx - (IN)Next hop or ecmp group index
   2641  * Returns:
   2642  *      BCM_E_XXX
   2643  */
   2644 int
   2645 _bcm_l3_lpm_get(int unit, _bcm_defip_cfg_t *lpm_cfg, int *nh_ecmp_idx)
   2646 {
   2647     soc_mem_t mem = L3_DEFIPm;
   2648     uint32 max_v6_entries = BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit);
   2649   
   2650     /* Input parameters check */
   2651     if (NULL == lpm_cfg) {
   2652         return (BCM_E_PARAM);
   2653     }
   2654 #if defined(BCM_TRIDENT3_SUPPORT)
   2655     if (SOC_IS_TRIDENT3X(unit) && soc_feature(unit, soc_feature_flex_flow)
   2656             && (lpm_cfg->defip_flow_handle != 0)) {
   2657         soc_mem_t view_id;
   2658         soc_flow_db_mem_view_info_t vinfo;
   2659 
   2660         BCM_IF_ERROR_RETURN( soc_flow_db_ffo_to_mem_view_id_get(unit,
   2661                     lpm_cfg->defip_flow_handle,
   2662                     lpm_cfg->defip_flow_option_handle,
   2663                     SOC_FLOW_DB_FUNC_L3_ROUTE_ID,
   2664                     (uint32 *)&view_id));
   2665         BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit, view_id, &vinfo));
   2666         mem = vinfo.mem;
   2667     } else
   2668 #endif
   2669     {
   2670         BCM_IF_ERROR_RETURN(_bcm_l3_defip_mem_get(unit, lpm_cfg->defip_flags,
   2671                     lpm_cfg->defip_sub_len, &mem));
   2672     }
   2673 
   2674     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   2675         return _bcm_l3_scaled_lpm_get(unit, lpm_cfg, nh_ecmp_idx);
   2676     }
   2677 
   2678     switch (mem) {
   2679         case L3_DEFIP_PAIR_128m:
   2680         case L3_DEFIP_PAIR_LEVEL1m:
   2681             if (max_v6_entries > 0) {
   2682                 return _bcm_l3_defip_pair128_get(unit, lpm_cfg, nh_ecmp_idx);
   2683             }
   2684             break;  
   2685         default:
   2686             if (soc_mem_index_count(unit, mem) > 0) {
   2687                 return _bcm_fb_lpm_get(unit, lpm_cfg, nh_ecmp_idx);
   2688             }
   2689             break;
   2690     }
   2691 
   2692     return (BCM_E_NOT_FOUND);
   2693 }
   2694 
   2695 void
   2696 _bcm_defip_cfg_t_dump(_bcm_defip_cfg_t *lpm_cfg)
   2697 {
   2698     int i = 0;
   2699 
   2700     if (lpm_cfg) {
   2701         LOG_CLI((BSL_META("flags: 0x%x  vrf: %d\n"), lpm_cfg->defip_flags, lpm_cfg->defip_vrf));
   2702         if (lpm_cfg->defip_flags & BCM_L3_IP6) {
   2703             LOG_CLI((BSL_META("defip_ip6_addr - ")));
   2704             for (i = 0; i < sizeof(bcm_ip6_t); i++) {
   2705                 LOG_CLI((BSL_META("0x%x:"), lpm_cfg->defip_ip6_addr[i]));
   2706             }
   2707             LOG_CLI((BSL_META("\n")));
   2708         } else {
   2709             LOG_CLI((BSL_META("defip_ip_addr: 0x%x\n"), lpm_cfg->defip_ip_addr));
   2710         }
   2711         LOG_CLI((BSL_META("defip_sub_len: %d defip_index: %d\n"), 
   2712                  lpm_cfg->defip_sub_len, lpm_cfg->defip_index));
   2713         for(i = 0; i < sizeof(bcm_mac_t); i++) {
   2714             LOG_CLI((BSL_META("defip_mac_addr - ")));
   2715             LOG_CLI((BSL_META("0x%x:"), lpm_cfg->defip_mac_addr[i]));
   2716         }
   2717 
   2718         if (lpm_cfg->defip_flags & BCM_L3_IP6) {
   2719             LOG_CLI((BSL_META("\ndefip_nexthop_ip6 - ")));
   2720             for (i = 0; i < sizeof(bcm_ip6_t); i++) {
   2721                 LOG_CLI((BSL_META("0x%x:"), lpm_cfg->defip_nexthop_ip6[i])); 
   2722             }
   2723             LOG_CLI((BSL_META("\n")));
   2724         } else {
   2725             LOG_CLI((BSL_META("defip_nexthop_ip: 0x%x\n"), lpm_cfg->defip_nexthop_ip));
   2726         }
   2727 
   2728         LOG_CLI((BSL_META("defip_tunnel: %d defip_prio: %d\n"), 
   2729                  lpm_cfg->defip_tunnel, lpm_cfg->defip_prio));
   2730 
   2731         LOG_CLI((BSL_META("defip_intf: %d defip_port_tgid: %d\n"), 
   2732                  lpm_cfg->defip_intf, lpm_cfg->defip_port_tgid));
   2733 
   2734         LOG_CLI((BSL_META("defip_stack_port: %d defip_modid: %d\n"), 
   2735                  lpm_cfg->defip_stack_port, lpm_cfg->defip_modid));
   2736 
   2737         LOG_CLI((BSL_META("defip_vid: %d defip_ecmp: %d\n"), 
   2738                  lpm_cfg->defip_vid, lpm_cfg->defip_ecmp));
   2739 
   2740         LOG_CLI((BSL_META("defip_ecmp_count: %d defip_ecmp_index: %d\n"), 
   2741                  lpm_cfg->defip_ecmp_count, lpm_cfg->defip_ecmp_index));
   2742 
   2743         LOG_CLI((BSL_META("defip_l3hw_index: %d defip_tunnel_option: %d\n"), 
   2744                  lpm_cfg->defip_l3hw_index, lpm_cfg->defip_tunnel_option));
   2745 
   2746         LOG_CLI((BSL_META("defip_mpls_label: %d defip_lookup_class: %d\n"),
   2747                  lpm_cfg->defip_mpls_label, lpm_cfg->defip_lookup_class));
   2748     }
   2749 }
   2750 
   2751 /* When a entry is delete in unpaired TCAM, then check if you can move
   2752  * 64B V6 or V4 entries back to unpaired TCAM. This is required to keep
   2753  * the entries in order
   2754  */
   2755 int _bcm_l3_lpm128_ripple_entries(int unit)
   2756 {
   2757     _bcm_defip_cfg_t lpm_cfg_array[2];
   2758     int nh_ecmp_idx[2];
   2759     uint32 e[SOC_MAX_MEM_FIELD_WORDS];
   2760     uint32 eupr[SOC_MAX_MEM_FIELD_WORDS];
   2761     int index   = 0;
   2762     int pfx_len = 0;
   2763     int count   = 0;
   2764     int ipv6    = 0;
   2765     int rv = BCM_E_NONE;
   2766     int idx = 0;
   2767     soc_mem_t mem = L3_DEFIPm;
   2768 
   2769     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_LEVEL1m)) {
   2770         mem = L3_DEFIP_LEVEL1m;
   2771     }
   2772     /* Do the following 
   2773      * 1. Find the smallest 64BV6 prefix
   2774      * 2. if 64BV6 entry not found, find the smallest V4 prefix
   2775      * 3. Try to add it to the unpaired tcam
   2776      * 4. If adding to the unpaired tcam is successful, 
   2777      *    then delete the entry from paired TCAM
   2778      */
   2779     sal_memcpy(e, soc_mem_entry_null(unit, mem),
   2780                soc_mem_entry_words(unit,mem) * 4);
   2781     sal_memcpy(eupr, soc_mem_entry_null(unit, mem),
   2782                soc_mem_entry_words(unit,mem) * 4);
   2783     ipv6 = 1; 
   2784     rv = _bcm_fb_lpm128_get_smallest_movable_prefix(unit, ipv6, e, eupr, &index,
   2785                                                     &pfx_len, &count); 
   2786     if (BCM_FAILURE(rv)) {
   2787         if (rv == BCM_E_NOT_FOUND) {
   2788             ipv6 = 0; 
   2789             rv = _bcm_fb_lpm128_get_smallest_movable_prefix(unit, ipv6, e,eupr,
   2790                                                             &index, &pfx_len,
   2791                                                             &count);
   2792             if (BCM_FAILURE(rv)) {
   2793                 return BCM_E_NONE;
   2794             }
   2795         } else {
   2796             return rv;
   2797         }
   2798     }
   2799     
   2800     if (ipv6) {
   2801         BCM_IF_ERROR_RETURN(_bcm_fb_lpm128_defip_cfg_get(unit, e, eupr,
   2802                                                       lpm_cfg_array,
   2803                                                       nh_ecmp_idx));
   2804     } else {
   2805         BCM_IF_ERROR_RETURN(_bcm_fb_lpm_defip_cfg_get(unit, ipv6, e,
   2806                                                       lpm_cfg_array,
   2807                                                       nh_ecmp_idx));
   2808     }
   2809    for (idx = 0; idx < count; idx++) {
   2810 #ifdef BCM_TOMAHAWK2_SUPPORT
   2811        if (soc_feature(unit, soc_feature_half_of_l3_defip_ipv4_capacity) &&
   2812            !(idx & 1)) {
   2813            continue;
   2814        }
   2815 #endif
   2816        lpm_cfg_array[idx].defip_index = BCM_XGS3_L3_INVALID_INDEX;
   2817        lpm_cfg_array[idx].defip_flags_high = 0;
   2818        rv = _bcm_fb_lpm_add(unit, &lpm_cfg_array[idx], 
   2819                                       nh_ecmp_idx[idx]);
   2820        if (BCM_FAILURE(rv)) {
   2821            return BCM_E_NONE;
   2822        }
   2823        BCM_IF_ERROR_RETURN(_bcm_fb_lpm128_del(unit, &lpm_cfg_array[idx]));
   2824    }
   2825 
   2826    return BCM_E_NONE;
   2827 }
   2828 
   2829 int
   2830 _bcm_l3_lpm_ripple_entries(int unit, _bcm_defip_cfg_t *lpm_cfg,
   2831                            int new_nh_ecmp_idx)
   2832 {
   2833 
   2834     _bcm_defip_cfg_t lpm_cfg_array[2];
   2835     int nh_ecmp_idx[2];
   2836     uint32 e[SOC_MAX_MEM_FIELD_WORDS];
   2837     int index   = 0;
   2838     int pfx_len = 0;
   2839     int count   = 0;
   2840     int ipv6    = 0;
   2841     int do_ripple = 0;
   2842     int rv = BCM_E_NONE;
   2843     int new_is_ipv6 = 0, move_is_ipv6 = 0;
   2844     int new_is_ipmc = 0, move_is_ipmc = 0;
   2845     int idx = 0;
   2846     soc_mem_t mem = L3_DEFIPm;
   2847 
   2848 #ifdef BCM_TOMAHAWK3_SUPPORT
   2849     if (SOC_MEM_IS_VALID(unit, L3_DEFIP_LEVEL1m)) {
   2850         mem = L3_DEFIP_LEVEL1m;
   2851     }
   2852 #endif
   2853 
   2854     /* Do the following 
   2855      * 1. Find the largest V4 prefix
   2856      * 2. if V4 entry not found, find the largest 64B V6 prefix
   2857      * 3. Try to add it to the paired tcam
   2858      * 4. If adding to the paired tcam is successful, 
   2859      *    then delete the entry
   2860      * 5. Add this entry again
   2861      */
   2862     sal_memcpy(e, soc_mem_entry_null(unit, mem),
   2863                soc_mem_entry_words(unit, mem) * 4);
   2864     sal_memset(&lpm_cfg_array[0], 0x0, sizeof(_bcm_defip_cfg_t));
   2865     sal_memset(&lpm_cfg_array[1], 0x0, sizeof(_bcm_defip_cfg_t));
   2866 
   2867     ipv6 = 0; 
   2868     rv = _bcm_fb_get_largest_prefix(unit, ipv6, e, &index, 
   2869                                    &pfx_len, &count); 
   2870     if (BCM_FAILURE(rv)) {
   2871         if (rv == BCM_E_NOT_FOUND) {
   2872             ipv6 = 1; 
   2873             rv = _bcm_fb_get_largest_prefix(unit, ipv6, e,
   2874                                            &index,
   2875                                            &pfx_len, &count);
   2876             if (BCM_FAILURE(rv)) {
   2877                 /* Failure here indicates something fatal */
   2878                 return BCM_E_INTERNAL; 
   2879             }
   2880         } else {
   2881             return BCM_E_FULL;
   2882         }
   2883     }
   2884 
   2885     /*
   2886      * If atomic write is enabled, one free entry is reserved to move
   2887      * the entries during entry update.
   2888      * count == 0 means HW doesn't hold any entry however SW v4 or v6
   2889      * prefix entries still holds a free entry after deleting all
   2890      * the entries in unpaired tcam.
   2891      */
   2892     if (soc_feature(unit, soc_feature_lpm_atomic_write) && (count == 0)) {
   2893        return _bcm_fb_lpm128_add(unit, lpm_cfg, new_nh_ecmp_idx);
   2894     }
   2895 
   2896     BCM_IF_ERROR_RETURN(_bcm_fb_lpm_defip_cfg_get(unit, ipv6, e, lpm_cfg_array,
   2897                                                  nh_ecmp_idx));
   2898     new_is_ipv6 = !!(lpm_cfg->defip_flags & BCM_L3_IP6);
   2899     move_is_ipv6 = !!(lpm_cfg_array[0].defip_flags & BCM_L3_IP6);
   2900     /*
   2901      * move | new
   2902      *------------
   2903      *  v6  | v6    length(move) > length(new)      ripple
   2904      *  v4  | v4    length(move) > length(new)      ripple
   2905      *  v4  | v6    ripple
   2906      *  v6  | v4    add to pair128
   2907  */
   2908     if (soc_feature(unit, soc_feature_td3_lpm_ipmc_war)) {
   2909         new_is_ipmc = !!(lpm_cfg->defip_flags & BCM_L3_IPMC);
   2910         move_is_ipmc = !!(lpm_cfg_array[0].defip_flags & BCM_L3_IPMC);
   2911     }
   2912 
   2913     if (!new_is_ipv6 && move_is_ipv6) {
   2914         do_ripple = 0;
   2915     } else if ((new_is_ipv6 && !move_is_ipv6) ||
   2916         ((move_is_ipmc << 8 | lpm_cfg_array[0].defip_sub_len) >
   2917          (new_is_ipmc << 8 | lpm_cfg->defip_sub_len))) {
   2918         /* Ripple move to pair128 */
   2919         do_ripple = 1;
   2920     }
   2921 
   2922     if (do_ripple) {
   2923         for (idx = 0; idx < count; idx++) {
   2924             lpm_cfg_array[idx].defip_index = BCM_XGS3_L3_INVALID_INDEX;
   2925 #ifdef BCM_TOMAHAWK2_SUPPORT            
   2926             if (soc_feature(unit, soc_feature_half_of_l3_defip_ipv4_capacity) && 
   2927                 !(idx & 1)) {
   2928                 continue;
   2929             }
   2930 #endif            
   2931             rv = _bcm_fb_lpm128_add(unit, &lpm_cfg_array[idx], 
   2932                                            nh_ecmp_idx[idx]);
   2933             lpm_cfg_array[idx].defip_flags_high = 0x0;
   2934             if (BCM_FAILURE(rv)) {
   2935                 return rv;
   2936             }
   2937             BCM_IF_ERROR_RETURN(_bcm_fb_lpm_del(unit, &lpm_cfg_array[idx]));
   2938         }
   2939         return _bcm_fb_lpm_add(unit, lpm_cfg, new_nh_ecmp_idx);
   2940     } else {
   2941         /* Add new to pair128 */
   2942         return _bcm_fb_lpm128_add(unit, lpm_cfg, new_nh_ecmp_idx);
   2943     }
   2944 
   2945    return BCM_E_NONE;
   2946 }
   2947 
   2948 /*
   2949  * Update the LPM entry for L3_DEFIP_DATA_ONLY view during Entry Modify.
   2950  */
   2951 STATIC int
   2952 _bcm_l3_scaled_lpm_data_modify(int unit, _bcm_defip_cfg_t *lpm_cfg, int nh_ecmp_idx)
   2953 {
   2954    uint32 lpm_hit[SOC_MAX_MEM_WORDS];
   2955    uint32 lpm_hit_copy[SOC_MAX_MEM_WORDS];
   2956    uint32 lpm_data[SOC_MAX_MEM_WORDS];
   2957    uint32 lpm_data_copy[SOC_MAX_MEM_WORDS];
   2958    uint32 defip_entry_lwr[SOC_MAX_MEM_WORDS];
   2959    uint32 defip_entry_upr[SOC_MAX_MEM_WORDS];
   2960    uint32 defip_entry[SOC_MAX_MEM_WORDS];
   2961    int defip_change = FALSE;
   2962    int defip_index = lpm_cfg->defip_index;
   2963    int defip_pair_index = -1;
   2964    int ipv6 = (lpm_cfg->defip_flags & BCM_L3_IP6);
   2965    int pfx_len = lpm_cfg->defip_sub_len;
   2966    int rv = BCM_E_NONE;
   2967    int mode;
   2968 
   2969 
   2970    /* Set mode  */
   2971    if (ipv6 == 0) {
   2972       mode = 0;
   2973       defip_index >>= 1;
   2974    } else if (pfx_len > 64 ||
   2975               lpm_cfg->defip_flags_high & BCM_XGS3_L3_ENTRY_IN_DEFIP_PAIR) {
   2976       mode = 3;
   2977    } else {
   2978       mode = 1;
   2979    }
   2980 
   2981    rv = READ_L3_DEFIP_DATA_ONLYm(unit, MEM_BLOCK_ANY,
   2982                                  defip_index, (uint32 *)lpm_data_copy);
   2983    if (BCM_FAILURE(rv)) {
   2984       return rv;
   2985    }
   2986    rv = READ_L3_DEFIP_HIT_ONLYm(unit, MEM_BLOCK_ANY,
   2987                                 defip_index, lpm_hit_copy);
   2988    if (BCM_FAILURE(rv)) {
   2989       return rv;
   2990    }
   2991 
   2992    sal_memcpy(lpm_data, lpm_data_copy, sizeof(lpm_data));
   2993    sal_memcpy(lpm_hit, lpm_hit_copy, sizeof(lpm_hit));
   2994 
   2995    if ((ipv6) || (lpm_cfg->defip_index & 1)) {
   2996       rv = _bcm_fb_lpm_prepare_defip_data(unit, lpm_cfg,
   2997                                           nh_ecmp_idx,
   2998                                           (uint32 *)lpm_data, lpm_hit, 1);
   2999       if (BCM_FAILURE(rv)) {
   3000          return rv;
   3001       }
   3002    }
   3003 
   3004    if ((ipv6) || !(lpm_cfg->defip_index & 1)) {
   3005       rv = _bcm_fb_lpm_prepare_defip_data(unit, lpm_cfg,
   3006                                           nh_ecmp_idx,
   3007                                           (uint32 *)lpm_data, lpm_hit, 0);
   3008    }
   3009 
   3010    if (BCM_FAILURE(rv)) {
   3011       return rv;
   3012    }
   3013    
   3014 
   3015    if (sal_memcmp(lpm_data_copy, lpm_data, sizeof(lpm_data))) {
   3016       rv = WRITE_L3_DEFIP_DATA_ONLYm(unit, MEM_BLOCK_ANY,
   3017                                      defip_index, lpm_data);
   3018       if (BCM_FAILURE(rv)) {
   3019          return rv;
   3020       }
   3021       /* In case of 128 bit entries */
   3022       if (mode == 3) {
   3023          defip_pair_index = defip_index + SOC_CONTROL(unit)->l3_defip_tcam_size;
   3024          rv = WRITE_L3_DEFIP_DATA_ONLYm(unit, MEM_BLOCK_ANY,
   3025                                         defip_pair_index, lpm_data);
   3026          if (BCM_FAILURE(rv)) {
   3027             return rv;
   3028          }
   3029       }
   3030       defip_change = TRUE;
   3031    }
   3032    
   3033    if (sal_memcmp(&lpm_hit_copy, lpm_hit, sizeof(lpm_hit))) {
   3034       rv = WRITE_L3_DEFIP_HIT_ONLYm(unit, MEM_BLOCK_ANY,
   3035                                     defip_index, &lpm_hit);
   3036       if (BCM_FAILURE(rv)) {
   3037          return rv;
   3038       }
   3039       /* In case of 128 bit entries */
   3040       if (mode == 3) {
   3041          defip_pair_index = defip_index + SOC_CONTROL(unit)->l3_defip_tcam_size;
   3042          rv = WRITE_L3_DEFIP_HIT_ONLYm(unit, MEM_BLOCK_ANY,
   3043                                        defip_pair_index, &lpm_hit);
   3044          if (BCM_FAILURE(rv)) {
   3045             return rv;
   3046          }
   3047       }
   3048       defip_change = TRUE;
   3049    }
   3050 
   3051    /* The cache of L3_DEFIP table should be updated if necessary */
   3052    if (defip_change && soc_mem_cache_get(unit, L3_DEFIPm, MEM_BLOCK_ALL)) {
   3053        sal_memset(&defip_entry, 0x0, BCM_XGS3_L3_ENT_SZ(unit, defip));
   3054        rv = _soc_mem_alpm_read_cache(unit, L3_DEFIPm, MEM_BLOCK_ANY,
   3055                                      defip_index, &defip_entry);
   3056        if (SOC_SUCCESS(rv)) {
   3057            sal_memset(&defip_entry_lwr, 0x0, BCM_XGS3_L3_ENT_SZ(unit, defip));
   3058            if (3 == mode) {
   3059                sal_memset(&defip_entry_upr, 0x0,
   3060                           BCM_XGS3_L3_ENT_SZ(unit, defip));
   3061                (void) _bcm_fb_lpm_prepare_defip_entry(
   3062                           unit, lpm_cfg, nh_ecmp_idx,
   3063                           defip_entry_lwr, defip_entry_upr);
   3064 
   3065                _soc_mem_alpm_write_cache(unit, L3_DEFIPm, MEM_BLOCK_ALL,
   3066                                          defip_index, defip_entry_lwr);
   3067                _soc_mem_alpm_write_cache(unit, L3_DEFIPm, MEM_BLOCK_ALL,
   3068                                          defip_index + SOC_L3_DEFIP_TCAM_DEPTH_GET(unit),
   3069                                          defip_entry_upr);
   3070            } else {
   3071                (void) _bcm_fb_lpm_prepare_defip_entry(
   3072                           unit, lpm_cfg, nh_ecmp_idx,
   3073                           defip_entry_lwr, NULL);
   3074                if (!ipv6) {
   3075                    if (lpm_cfg->defip_index & 0x1) {
   3076                        (void) soc_fb_lpm_ip4entry0_to_1(
   3077                                   unit, &defip_entry_lwr,
   3078                                   defip_entry, PRESERVE_HIT);
   3079                    } else {
   3080                        (void) soc_fb_lpm_ip4entry0_to_0(
   3081                                   unit, defip_entry_lwr,
   3082                                   defip_entry, PRESERVE_HIT);
   3083                    }
   3084                }
   3085                _soc_mem_alpm_write_cache(
   3086                    unit, L3_DEFIPm, MEM_BLOCK_ALL, defip_index,
   3087                    ipv6 ? defip_entry_lwr : defip_entry);
   3088            }
   3089        }
   3090    }
   3091 
   3092    return BCM_E_NONE;
   3093 }
   3094 
   3095 /*
   3096  * Update the LPM entry for L3_DEFIP_DATA_ONLY view during Entry Modify.
   3097  */
   3098 STATIC int
   3099 _bcm_l3_scaled_lpm_data_modify_urpf_entry_replicate(int unit, _bcm_defip_cfg_t *lpm_cfg, int nh_ecmp_idx)
   3100 {
   3101     int rv;               /* Return type.                                  */
   3102     int offset = 0;
   3103     int defip_index = lpm_cfg->defip_index;
   3104 
   3105     if(!SOC_URPF_STATUS_GET(unit)) {
   3106         return (SOC_E_NONE);
   3107     }
   3108 
   3109     BCM_IF_ERROR_RETURN(soc_lpm_fb_urpf_entry_replicate_index_offset(unit, &offset));
   3110 
   3111     /* For non-ipv6 multiple by 2, since will be >> by 1 in
   3112      * _bcm_l3_scaled_lpm_data_modify function */
   3113     if (!(lpm_cfg->defip_flags & BCM_L3_IP6)) {
   3114         offset = offset << 1;
   3115     }
   3116 
   3117     /* Update with urpf entry defip index */
   3118     lpm_cfg->defip_index += offset;
   3119 
   3120     /* Update urpf entry with new data */
   3121     rv =  _bcm_l3_scaled_lpm_data_modify(unit, lpm_cfg, nh_ecmp_idx);
   3122 
   3123     /* Restore original defip index */
   3124     lpm_cfg->defip_index = defip_index;
   3125 
   3126     return rv;
   3127 }
   3128 
   3129 int
   3130 _bcm_l3_scaled_lpm_add(int unit, _bcm_defip_cfg_t *lpm_cfg, int nh_ecmp_idx)
   3131 {
   3132     int rv = BCM_E_NONE;
   3133     int defip_table_size = 0;
   3134     int paired_table_size = 0;
   3135 
   3136     if (!soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3137         return BCM_E_UNAVAIL;
   3138     }
   3139 
   3140     /* Input parameters check */
   3141     if (lpm_cfg == NULL) {
   3142        return BCM_E_INTERNAL;
   3143     }
   3144 
   3145     /* Check if Entry is for modification */
   3146     /* Modify only the Data part for the given LPM entry index */
   3147     if ((lpm_cfg->defip_index >= 0) && !SOC_IS_TOMAHAWK3(unit)) {
   3148        BCM_IF_ERROR_RETURN(_bcm_l3_scaled_lpm_data_modify(unit, lpm_cfg, nh_ecmp_idx));
   3149        /* Update Urpf entry when URPF is ON */
   3150        return _bcm_l3_scaled_lpm_data_modify_urpf_entry_replicate(unit, lpm_cfg, nh_ecmp_idx);
   3151     }
   3152 
   3153     BCM_IF_ERROR_RETURN(_bcm_l3_lpm_table_sizes_get(unit, &paired_table_size, 
   3154                                                     &defip_table_size));
   3155 
   3156     if (paired_table_size == 0 && lpm_cfg->defip_sub_len > 64) {
   3157         return BCM_E_FULL;
   3158     }
   3159 
   3160     if ((paired_table_size != 0 && lpm_cfg->defip_sub_len > 64) || 
   3161         (defip_table_size == 0)) {
   3162         return _bcm_fb_lpm128_add(unit, lpm_cfg, nh_ecmp_idx);
   3163     }
   3164 
   3165     rv = _bcm_fb_lpm_add(unit, lpm_cfg, nh_ecmp_idx);
   3166     if ((rv == BCM_E_FULL) && _bcm_l3_is_v4_64b_allowed_in_paired_tcam(unit)) {
   3167         return _bcm_l3_lpm_ripple_entries(unit, lpm_cfg,
   3168                                           nh_ecmp_idx);
   3169     }
   3170     return rv;
   3171 }
   3172 
   3173 /*
   3174  * Function:
   3175  *      _bcm_l3_lpm_add
   3176  * Purpose:
   3177  *      Add an entry to TD2 route table table.
   3178  * Parameters:
   3179  *      unit        - (IN)SOC unit number.
   3180  *      lpm_cfg     - (IN)Buffer to fill defip information. 
   3181  frtu[]*      nh_ecmp_idx - (IN)Next hop or ecmp group index.
   3182  * Returns:
   3183  *      BCM_E_XXX
   3184  */
   3185 int
   3186 _bcm_l3_lpm_add(int unit, _bcm_defip_cfg_t *lpm_cfg, int nh_ecmp_idx)
   3187 {
   3188     int rv;
   3189     soc_mem_t mem = L3_DEFIPm;
   3190 
   3191     /* Input parameters check */
   3192     if (NULL == lpm_cfg) {
   3193         return (BCM_E_PARAM);
   3194     }
   3195 #if defined(BCM_TRIDENT3_SUPPORT)
   3196     if (SOC_IS_TRIDENT3X(unit) && soc_feature(unit, soc_feature_flex_flow)
   3197             && (lpm_cfg->defip_flow_handle != 0)) {
   3198         soc_mem_t view_id;
   3199         soc_flow_db_mem_view_info_t vinfo;
   3200 
   3201         BCM_IF_ERROR_RETURN( soc_flow_db_ffo_to_mem_view_id_get(unit,
   3202                     lpm_cfg->defip_flow_handle,
   3203                     lpm_cfg->defip_flow_option_handle,
   3204                     SOC_FLOW_DB_FUNC_L3_ROUTE_ID,
   3205                     (uint32 *)&view_id));
   3206         BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit, view_id, &vinfo));
   3207         mem = vinfo.mem;
   3208     } else
   3209 #endif
   3210     {
   3211         BCM_IF_ERROR_RETURN(_bcm_l3_defip_mem_get(unit, lpm_cfg->defip_flags,
   3212                     lpm_cfg->defip_sub_len, &mem));
   3213     }
   3214 
   3215     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3216         rv = _bcm_l3_scaled_lpm_add(unit, lpm_cfg, nh_ecmp_idx);
   3217 #ifdef FB_LPM_DEBUG
   3218         BCM_IF_ERROR_RETURN(lpm128_state_verify(unit));
   3219 #endif
   3220         return rv;
   3221     }
   3222     
   3223     switch (mem) {
   3224         case L3_DEFIP_PAIR_128m:
   3225         case L3_DEFIP_PAIR_LEVEL1m:
   3226             if (soc_mem_index_count(unit, mem) > 0) {
   3227                 return _bcm_l3_defip_pair128_add(unit, lpm_cfg, nh_ecmp_idx);
   3228             }
   3229             break; 
   3230         default:
   3231             if (soc_mem_index_count(unit, mem) > 0) {
   3232                 return _bcm_fb_lpm_add(unit, lpm_cfg, nh_ecmp_idx);
   3233             }
   3234             break; 
   3235     }
   3236     return (BCM_E_FULL);
   3237 }
   3238 
   3239 int
   3240 _bcm_l3_scaled_lpm_del(int unit, _bcm_defip_cfg_t *lpm_cfg)
   3241 {
   3242     int rv = BCM_E_NONE;
   3243     int defip_table_size = 0;
   3244     int paired_table_size = 0;
   3245 
   3246     if (!soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3247         return BCM_E_UNAVAIL;
   3248     }
   3249 
   3250    BCM_IF_ERROR_RETURN(_bcm_l3_lpm_table_sizes_get(unit, &paired_table_size,
   3251                                                    &defip_table_size));
   3252 
   3253     if ((paired_table_size != 0) && (lpm_cfg->defip_sub_len > 64 ||
   3254         (defip_table_size == 0) ||
   3255         lpm_cfg->defip_flags_high & BCM_XGS3_L3_ENTRY_IN_DEFIP_PAIR)) {
   3256         return _bcm_fb_lpm128_del(unit, lpm_cfg);
   3257     }
   3258 
   3259     if (paired_table_size == 0 && lpm_cfg->defip_sub_len > 64) {
   3260         return BCM_E_NOT_FOUND;
   3261     }
   3262 
   3263     lpm_cfg->defip_flags_high = 0;
   3264 
   3265     rv = _bcm_fb_lpm_del(unit, lpm_cfg);
   3266     if (BCM_SUCCESS(rv) && _bcm_l3_is_v4_64b_allowed_in_paired_tcam(unit)) {
   3267             return _bcm_l3_lpm128_ripple_entries(unit);
   3268     }
   3269     return rv;
   3270 }
   3271 
   3272 /*
   3273  * Function:
   3274  *      _bcm_l3_lpm_del
   3275  * Purpose:
   3276  *      Delete an entry from the route table.
   3277  * Parameters:
   3278  *      unit    - (IN)SOC unit number.
   3279  *      lpm_cfg - (IN)Buffer to fill defip information. 
   3280  * Returns:
   3281  *      BCM_E_XXX
   3282  */
   3283 int
   3284 _bcm_l3_lpm_del(int unit, _bcm_defip_cfg_t *lpm_cfg)
   3285 {
   3286     soc_mem_t mem = L3_DEFIPm;
   3287     uint32 max_v6_entries = BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit); 
   3288     int rv = BCM_E_NONE;
   3289 
   3290     /* Input parameters check */
   3291     if (NULL == lpm_cfg) {
   3292         return (BCM_E_PARAM);
   3293     }
   3294     if (!SOC_MEM_IS_VALID(unit, L3_DEFIPm)) {
   3295          mem = L3_DEFIP_LEVEL1m;
   3296     }
   3297 #if defined(BCM_TRIDENT3_SUPPORT)
   3298     if (SOC_IS_TRIDENT3X(unit) && soc_feature(unit, soc_feature_flex_flow)
   3299             && (lpm_cfg->defip_flow_handle != 0)) {
   3300         soc_mem_t view_id;
   3301         soc_flow_db_mem_view_info_t vinfo;
   3302 
   3303         BCM_IF_ERROR_RETURN( soc_flow_db_ffo_to_mem_view_id_get(unit,
   3304                     lpm_cfg->defip_flow_handle,
   3305                     lpm_cfg->defip_flow_option_handle,
   3306                     SOC_FLOW_DB_FUNC_L3_ROUTE_ID,
   3307                     (uint32 *)&view_id));
   3308         BCM_IF_ERROR_RETURN(soc_flow_db_mem_view_info_get(unit, view_id, &vinfo));
   3309         mem = vinfo.mem;
   3310     } else
   3311 #endif
   3312     {
   3313         BCM_IF_ERROR_RETURN(_bcm_l3_defip_mem_get(unit, lpm_cfg->defip_flags,
   3314                     lpm_cfg->defip_sub_len, &mem));
   3315     }
   3316     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3317         rv = _bcm_l3_scaled_lpm_del(unit, lpm_cfg);
   3318 #ifdef FB_LPM_DEBUG
   3319         BCM_IF_ERROR_RETURN(lpm128_state_verify(unit));
   3320 #endif
   3321         return rv;
   3322     }
   3323 
   3324     switch (mem) {
   3325         case L3_DEFIP_PAIR_128m:
   3326 #ifdef BCM_TOMAHAWK3_SUPPORT
   3327         case L3_DEFIP_PAIR_LEVEL1m:
   3328 #endif
   3329             if (max_v6_entries > 0) {    
   3330                 return _bcm_l3_defip_pair128_del(unit, lpm_cfg);
   3331             }   
   3332             break;  
   3333         default: 
   3334             if (soc_mem_index_count(unit, mem) > 0) {
   3335                 return _bcm_fb_lpm_del(unit, lpm_cfg);
   3336             } 
   3337             break;  
   3338     }
   3339 
   3340     return (rv);
   3341 }
   3342 
   3343 int _bcm_l3_scaled_lpm_update_match(int unit, _bcm_l3_trvrs_data_t *trv_data)
   3344 {
   3345     int rv1 = BCM_E_NONE;
   3346     int rv2 = BCM_E_NONE;
   3347     int defip_table_size = 0;
   3348     int paired_table_size = 0;
   3349 
   3350     if (!soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3351         return BCM_E_UNAVAIL;
   3352     }
   3353 
   3354     BCM_IF_ERROR_RETURN(_bcm_l3_lpm_table_sizes_get(unit, &paired_table_size,
   3355                                                     &defip_table_size));
   3356     
   3357     if (paired_table_size != 0) {
   3358         rv1 = _bcm_fb_lpm128_update_match(unit, trv_data);
   3359     }
   3360    
   3361     if (defip_table_size != 0) {
   3362         rv2 = _bcm_fb_lpm_update_match(unit, trv_data);
   3363     }
   3364    
   3365     BCM_IF_ERROR_RETURN(rv1);
   3366     BCM_IF_ERROR_RETURN(rv2);
   3367 
   3368     return (BCM_E_NONE);
   3369 }
   3370 
   3371 /*
   3372  * Function:
   3373  *      _bcm_l3_lpm_update_match
   3374  * Purpose:
   3375  *      Update/Delete all entries in defip table matching a certain rule.
   3376  * Parameters:
   3377  *      unit     - (IN)SOC unit number.
   3378  *      trv_data - (IN)Delete pattern + compare,act,notify routines.  
   3379  * Returns:
   3380  *      BCM_E_XXX
   3381  */
   3382 int
   3383 _bcm_l3_lpm_update_match(int unit, _bcm_l3_trvrs_data_t *trv_data)
   3384 {
   3385     int rv1 = BCM_E_NONE; 
   3386     int rv2 = BCM_E_NONE; 
   3387     uint32 max_v6_entries = BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit);
   3388     soc_mem_t mem = L3_DEFIPm;
   3389 
   3390     if (!SOC_MEM_IS_VALID(unit, L3_DEFIPm)) {
   3391         mem = L3_DEFIP_LEVEL1m;
   3392     }
   3393 
   3394     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3395         return _bcm_l3_scaled_lpm_update_match(unit, trv_data);
   3396     }
   3397 
   3398     if ((trv_data->flags & BCM_L3_IP6) && (max_v6_entries > 0)) {
   3399         rv2 = _bcm_l3_defip_pair128_update_match(unit, trv_data);
   3400     }
   3401 
   3402     if (soc_mem_index_count(unit, mem) > 0) {
   3403         rv1 = _bcm_fb_lpm_update_match(unit, trv_data);
   3404     }
   3405     BCM_IF_ERROR_RETURN(rv1);
   3406     BCM_IF_ERROR_RETURN(rv2);
   3407 
   3408     return (BCM_E_NONE);
   3409 }
   3410 
   3411 /*
   3412  * Function:
   3413  *      _bcm_l3_defip_urpf_enable
   3414  * Purpose:
   3415  *      Configure TD2 internal route table for URPF mode
   3416  * Parameters:
   3417  *      unit     - (IN)SOC unit number.
   3418  * Returns:
   3419  *      BCM_E_XXX
   3420  */
   3421 int
   3422 _bcm_l3_defip_urpf_enable(int unit, int enable)
   3423 {
   3424     int ipv6_64_depth = 0;
   3425     int ipv6_128_dip_offset = 0, ipv6_128_depth = 0;
   3426     int num_ipv6_128b_entries;
   3427     int tcam_pair_count = 0;
   3428     int tcam_depth = SOC_L3_DEFIP_TCAM_DEPTH_GET(unit);
   3429     int start_index = 0;
   3430 #ifdef ALPM_ENABLE
   3431     if (soc_feature(unit, soc_feature_alpm) &&
   3432         soc_property_get(unit, spn_L3_ALPM_ENABLE, 0)) {
   3433         return SOC_E_NONE;
   3434     }
   3435 #endif
   3436     num_ipv6_128b_entries =  SOC_L3_DEFIP_MAX_128B_ENTRIES(unit);
   3437     SOC_IF_ERROR_RETURN(soc_fb_lpm_tcam_pair_count_get(unit, &tcam_pair_count));
   3438 
   3439     if (enable) {
   3440         /* All CAMs in URPF mode */
   3441         switch (tcam_pair_count) {
   3442             case 0:
   3443                 /* No pairing of tcams */
   3444                 ipv6_64_depth = 4 * tcam_depth;
   3445                 break;
   3446             case 1:
   3447             case 2:
   3448                 if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3449                     ipv6_64_depth = 2 * tcam_depth;
   3450                 }
   3451                 break;
   3452             default:
   3453                 if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3454                     ipv6_64_depth = 0;
   3455                 }
   3456                 break;
   3457         }
   3458 
   3459         if (!soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3460             ipv6_128_dip_offset = num_ipv6_128b_entries / 2;
   3461             ipv6_128_depth      = num_ipv6_128b_entries / 2;
   3462             ipv6_64_depth       = soc_mem_index_count(unit, L3_DEFIPm) / 2;
   3463         }
   3464     } else { /* Disable case */
   3465         ipv6_64_depth       = soc_mem_index_count(unit, L3_DEFIPm);
   3466         ipv6_128_dip_offset = 0;
   3467         ipv6_128_depth      = num_ipv6_128b_entries;
   3468         if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3469             ipv6_64_depth -= (tcam_pair_count * tcam_depth * 2);
   3470         }
   3471     }
   3472 
   3473     SOC_LPM_STATE_FENT(unit, (MAX_PFX_INDEX(unit)))  = ipv6_64_depth;
   3474     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3475         if (!enable) {
   3476             start_index = (tcam_pair_count * tcam_depth * 2);
   3477         } else {
   3478             switch (tcam_pair_count) {
   3479                 case 1:
   3480                 case 2:
   3481                     start_index = 2 * tcam_depth;
   3482                     break;
   3483                 case 3:
   3484                 case 4:
   3485                     start_index = 4 * tcam_depth;
   3486                     break;
   3487                 default:
   3488                     start_index = 0;
   3489                     break;
   3490             }
   3491         }
   3492         /* reinit the lpm128 logic to get the correct size for table */ 
   3493         SOC_IF_ERROR_RETURN(soc_fb_lpm_stat_init(unit));
   3494         SOC_IF_ERROR_RETURN(soc_fb_lpm128_deinit(unit));
   3495         SOC_IF_ERROR_RETURN(soc_fb_lpm128_init(unit));
   3496     } else {
   3497         BCM_DEFIP_PAIR128_URPF_OFFSET(unit)    = ipv6_128_dip_offset;
   3498         BCM_DEFIP_PAIR128_IDX_MAX(unit)        = ipv6_128_depth - 1;
   3499         BCM_DEFIP_PAIR128_TOTAL(unit)          = ipv6_128_depth;
   3500         SOC_IF_ERROR_RETURN(soc_fb_lpm_stat_init(unit));
   3501     }
   3502     SOC_LPM_STATE_START(unit, (MAX_PFX_INDEX(unit))) = start_index;
   3503     SOC_LPM_STATE_END(unit, (MAX_PFX_INDEX(unit)))   = start_index - 1;
   3504 
   3505     BCM_IF_ERROR_RETURN(soc_fb_lpm_state_config(unit, ipv6_64_depth, 
   3506                                                 start_index));
   3507 
   3508     BCM_IF_ERROR_RETURN(
   3509         _bcm_l3_defip_key_sel_set(unit, enable, tcam_pair_count));
   3510     return BCM_E_NONE;
   3511 }
   3512 
   3513 #if defined(BCM_KATANA2_SUPPORT) 
   3514 
   3515 #define URPF_OFFSET 0
   3516 /*
   3517  * Function:
   3518  *      _bcm_kt2_l3_defip_mem_get
   3519  * Purpose:
   3520  *      Resolve route table memory for a given route entry.
   3521  * Parameters:
   3522  *      unit       - (IN)SOC unit number.
   3523  *      flags      - (IN)IPv6/IPv4 route.
   3524  *      plen       - (IN)Prefix length.
   3525  *      mem        - (OUT)Route table memory.
   3526  * Returns:
   3527  *      BCM_E_XXX
   3528  */
   3529 STATIC int
   3530 _bcm_kt2_l3_defip_mem_get(int unit, uint32 flags, int plen, soc_mem_t *mem)
   3531 {
   3532     *mem = ((flags & BCM_L3_IP6) && (plen > 64)) ?
   3533                L3_DEFIP_PAIR_128m : L3_DEFIPm ;
   3534 
   3535     return BCM_E_NONE;
   3536 }
   3537 
   3538 /*
   3539  * Function:
   3540  *      _bcm_kt2_defip_pair128_init
   3541  * Purpose:
   3542  *      Initialize sw image for L3_DEFIP_PAIR_128 internal tcam.
   3543  * Parameters:
   3544  *      unit        - (IN)SOC unit number.
   3545  * Returns:
   3546  *      BCM_E_XXX
   3547  */
   3548 STATIC int
   3549 _bcm_kt2_defip_pair128_init(int unit)
   3550 {
   3551     int rv;
   3552     int mem_sz;
   3553     int defip_config;
   3554     int ipv6_128_depth;
   3555     int ipv6_default_depth = 1024;
   3556 
   3557 #ifdef  BCM_METROLITE_SUPPORT
   3558     if (SOC_IS_METROLITE(unit)) {
   3559         ipv6_default_depth = 256;
   3560     }
   3561 #endif
   3562 
   3563     /* De-allocate any existing structures. */
   3564     if (BCM_DEFIP_PAIR128(unit) != NULL) {
   3565         BCM_IF_ERROR_RETURN(_bcm_defip_pair128_deinit(unit));
   3566     }
   3567 
   3568     /* Allocate CAM control structure. */
   3569     mem_sz = sizeof(_bcm_defip_pair128_table_t);
   3570     BCM_DEFIP_PAIR128(unit) = sal_alloc(mem_sz, "kt2_l3_defip_pair128");
   3571     if (BCM_DEFIP_PAIR128(unit) == NULL) {
   3572         return (BCM_E_MEMORY);
   3573     }
   3574 
   3575     /* Reset CAM control structure. */
   3576     sal_memset(BCM_DEFIP_PAIR128(unit), 0, mem_sz);
   3577 
   3578     defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE,1);
   3579     ipv6_128_depth = soc_property_get(unit, spn_NUM_IPV6_LPM_128B_ENTRIES,
   3580                                       (defip_config ? ipv6_default_depth : 0));
   3581 
   3582     BCM_DEFIP_PAIR128_TOTAL(unit) = ipv6_128_depth;
   3583     BCM_DEFIP_PAIR128_URPF_OFFSET(unit) = URPF_OFFSET;
   3584     BCM_DEFIP_PAIR128_IDX_MAX(unit) = ipv6_128_depth - 1;
   3585     BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit) = ipv6_128_depth;
   3586     if (ipv6_128_depth) {
   3587         mem_sz = ipv6_128_depth * sizeof(_bcm_defip_pair128_entry_t);
   3588         BCM_DEFIP_PAIR128_ARR(unit) = 
   3589             sal_alloc(mem_sz, "kt2_l3_defip_pair128_entry_array");
   3590         if (BCM_DEFIP_PAIR128_ARR(unit) == NULL) {
   3591             BCM_IF_ERROR_RETURN(_bcm_defip_pair128_deinit(unit));
   3592             return (BCM_E_MEMORY);
   3593         }
   3594         sal_memset(BCM_DEFIP_PAIR128_ARR(unit), 0, mem_sz);
   3595     }
   3596     rv = _bcm_defip_pair128_field_cache_init(unit);
   3597     if (BCM_FAILURE(rv)) {
   3598         BCM_IF_ERROR_RETURN(_bcm_defip_pair128_deinit(unit));
   3599         return rv;
   3600     }
   3601     return (BCM_E_NONE);
   3602 }
   3603 
   3604 /*
   3605  * Function:
   3606  *      _bcm_kt2_l3_defip_init
   3607  * Purpose:
   3608  *      Configure KT2 internal route table as per soc properties.
   3609  *      (TCAM pairing for IPv4, 64/128 bit IPV6 prefixes)
   3610  * Parameters:
   3611  *      unit     - (IN)SOC unit number.
   3612  * Returns:
   3613  *      BCM_E_XXX
   3614  */
   3615 int
   3616 _bcm_kt2_l3_defip_init(int unit)
   3617 {
   3618     int defip_config;
   3619     uint32 defip_key_sel_val = 0;
   3620     int mem_v4, mem_v6, mem_v6_128; /* Route table memories */
   3621     int ipv6_64_depth = 0;
   3622     int num_ipv6_128b_entries;
   3623     int start_index = 0;
   3624     int tcam_pair_count = 0;
   3625     int tcam_depth = SOC_L3_DEFIP_TCAM_DEPTH_GET(unit);
   3626 
   3627     defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1);
   3628     num_ipv6_128b_entries =
   3629         soc_property_get(unit, spn_NUM_IPV6_LPM_128B_ENTRIES,
   3630             (defip_config ?(SOC_IS_METROLITE(unit) ? 256:1024) : 0));
   3631 
   3632     if (num_ipv6_128b_entries) {
   3633         tcam_pair_count = (num_ipv6_128b_entries / tcam_depth) +
   3634                           ((num_ipv6_128b_entries % tcam_depth) ? 1 : 0);
   3635     }
   3636 
   3637     BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit) = 
   3638                                        SOC_L3_DEFIP_MAX_128B_ENTRIES(unit);
   3639 
   3640     switch (tcam_pair_count) {
   3641         case 8:
   3642             soc_reg_field_set(unit, L3_DEFIP_KEY_SELr, &defip_key_sel_val,
   3643                               V6_KEY_SEL_CAM14_15f, 0x1);
   3644         case 7:
   3645             soc_reg_field_set(unit, L3_DEFIP_KEY_SELr, &defip_key_sel_val,
   3646                               V6_KEY_SEL_CAM12_13f, 0x1);
   3647         case 6:
   3648             soc_reg_field_set(unit, L3_DEFIP_KEY_SELr, &defip_key_sel_val,
   3649                               V6_KEY_SEL_CAM10_11f, 0x1);
   3650         case 5:
   3651             soc_reg_field_set(unit, L3_DEFIP_KEY_SELr, &defip_key_sel_val,
   3652                               V6_KEY_SEL_CAM8_9f, 0x1);
   3653         case 4:
   3654             soc_reg_field_set(unit, L3_DEFIP_KEY_SELr, &defip_key_sel_val,
   3655                               V6_KEY_SEL_CAM6_7f, 0x1);
   3656         case 3:
   3657             soc_reg_field_set(unit, L3_DEFIP_KEY_SELr, &defip_key_sel_val,
   3658                               V6_KEY_SEL_CAM4_5f, 0x1);
   3659         case 2:
   3660             soc_reg_field_set(unit, L3_DEFIP_KEY_SELr, &defip_key_sel_val,
   3661                               V6_KEY_SEL_CAM2_3f, 0x1);
   3662         case 1:
   3663             soc_reg_field_set(unit, L3_DEFIP_KEY_SELr, &defip_key_sel_val,
   3664                               V6_KEY_SEL_CAM0_1f, 0x1);
   3665             break;
   3666         default:
   3667             break;
   3668     }
   3669     ipv6_64_depth = soc_mem_index_count(unit, L3_DEFIPm); 
   3670 
   3671     BCM_IF_ERROR_RETURN(WRITE_L3_DEFIP_KEY_SELr(unit, defip_key_sel_val));
   3672 
   3673     /* Get memory for IPv4 entries. */
   3674     BCM_IF_ERROR_RETURN(_bcm_kt2_l3_defip_mem_get(unit, 0, 0, &mem_v4));
   3675 
   3676     /* Initialize IPv4 entries lookup engine. */
   3677     BCM_IF_ERROR_RETURN(soc_fb_lpm_init(unit));
   3678 
   3679     /* Get memory for IPv6 entries. */
   3680     BCM_IF_ERROR_RETURN
   3681         (_bcm_kt2_l3_defip_mem_get(unit, BCM_L3_IP6, 0, &mem_v6));
   3682 
   3683     /* Initialize IPv6 entries lookup engine. */
   3684     if (mem_v4 != mem_v6) {
   3685         BCM_IF_ERROR_RETURN(soc_fb_lpm_init(unit));
   3686     }
   3687     /* Overriding defaults set during lpm init */
   3688     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3689         BCM_IF_ERROR_RETURN(soc_fb_lpm128_init(unit));
   3690         ipv6_64_depth -= (tcam_pair_count * tcam_depth * 2);
   3691         start_index = (tcam_pair_count * tcam_depth * 2);
   3692     } else {
   3693         start_index = 0;
   3694     }
   3695 
   3696     SOC_LPM_STATE_START(unit, (MAX_PFX_INDEX(unit))) = start_index;
   3697     SOC_LPM_STATE_END(unit, (MAX_PFX_INDEX(unit))) = start_index - 1;
   3698     SOC_LPM_STATE_FENT(unit, (MAX_PFX_INDEX(unit))) = ipv6_64_depth;
   3699     BCM_IF_ERROR_RETURN(soc_fb_lpm_state_config(unit, ipv6_64_depth, 
   3700                                                 start_index));
   3701 
   3702     /* Get memory for IPv6 entries with prefix length > 64. */
   3703     BCM_IF_ERROR_RETURN
   3704         (_bcm_kt2_l3_defip_mem_get(unit, BCM_L3_IP6,
   3705                                   BCM_XGS3_L3_IPV6_PREFIX_LEN,
   3706                                   &mem_v6_128));
   3707 
   3708     /* Initialize IPv6 entries lookup engine. */
   3709     if (mem_v6 != mem_v6_128) {
   3710         if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3711             return soc_fb_lpm128_init(unit);
   3712         } else {
   3713             BCM_IF_ERROR_RETURN(_bcm_kt2_defip_pair128_init(unit));
   3714         }
   3715     }
   3716 
   3717     return BCM_E_NONE;
   3718 }
   3719 
   3720 /*
   3721  * Function:
   3722  *      _bcm_kt2_l3_defip_deinit
   3723  * Purpose:
   3724  *      De-initialize route table for katana2 devices.
   3725  * Parameters:
   3726  *      unit - (IN)  SOC unit number.
   3727  * Returns:
   3728  *      BCM_E_XXX
   3729  */
   3730 int 
   3731 _bcm_kt2_l3_defip_deinit(int unit)
   3732 {
   3733     soc_mem_t mem_v4;      /* IPv4 Route table memory.             */
   3734     soc_mem_t mem_v6;      /* IPv6 Route table memory.             */
   3735     soc_mem_t mem_v6_128;  /* IPv6 full prefix route table memory. */
   3736 
   3737     /* Get memory for IPv4 entries. */
   3738     BCM_IF_ERROR_RETURN(_bcm_kt2_l3_defip_mem_get(unit, 0, 0, &mem_v4));
   3739 
   3740     /* Deinitialize IPv4 entries lookup engine. */
   3741     BCM_IF_ERROR_RETURN(soc_fb_lpm_deinit(unit));
   3742 
   3743     /* Get memory for IPv6 entries. */
   3744     BCM_IF_ERROR_RETURN
   3745         (_bcm_kt2_l3_defip_mem_get(unit, BCM_L3_IP6, 0, &mem_v6));
   3746 
   3747     /* Deinitialize IPv6 entries lookup engine. */
   3748     if (mem_v4 != mem_v6) {
   3749         BCM_IF_ERROR_RETURN(soc_fb_lpm_deinit(unit));
   3750     }
   3751 
   3752     /* Get memory for IPv6 entries with prefix length > 64. */
   3753     BCM_IF_ERROR_RETURN
   3754         (_bcm_kt2_l3_defip_mem_get(unit, BCM_L3_IP6,
   3755                                   BCM_XGS3_L3_IPV6_PREFIX_LEN,
   3756                                   &mem_v6_128));
   3757 
   3758     /* Deinitialize IPv6 entries lookup engine. */
   3759     if (mem_v6 != mem_v6_128) {
   3760          if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3761              BCM_IF_ERROR_RETURN(soc_fb_lpm128_deinit(unit));
   3762          } else {
   3763              BCM_IF_ERROR_RETURN(_bcm_defip_pair128_deinit(unit));
   3764          }
   3765     }
   3766     return (BCM_E_NONE);
   3767 
   3768 }
   3769 
   3770 /*
   3771  * Function:
   3772  *      _bcm_kt2_l3_lpm_get
   3773  * Purpose:
   3774  *      Get an entry from the route table.
   3775  * Parameters:
   3776  *      unit        - (IN)SOC unit number.
   3777  *      lpm_cfg     - (IN)Buffer to fill defip information. 
   3778  *      nh_ecmp_idx - (IN)Next hop or ecmp group index
   3779  * Returns:
   3780  *      BCM_E_XXX
   3781  */
   3782 int
   3783 _bcm_kt2_l3_lpm_get(int unit, _bcm_defip_cfg_t *lpm_cfg, int *nh_ecmp_idx)
   3784 {
   3785     soc_mem_t mem = L3_DEFIPm;
   3786     uint32 max_v6_entries = BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit);
   3787 
   3788     /* Input parameters check */
   3789     if (NULL == lpm_cfg) {
   3790         return (BCM_E_PARAM);
   3791     }
   3792 
   3793     BCM_IF_ERROR_RETURN(_bcm_kt2_l3_defip_mem_get(unit, lpm_cfg->defip_flags,
   3794                                               lpm_cfg->defip_sub_len, &mem));
   3795 
   3796     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3797         if (mem == L3_DEFIPm || mem == L3_DEFIP_PAIR_128m) {
   3798             return _bcm_l3_scaled_lpm_get(unit, lpm_cfg, nh_ecmp_idx);
   3799         }
   3800     }
   3801 
   3802     switch (mem) {
   3803         case L3_DEFIP_PAIR_128m:
   3804             if (max_v6_entries > 0) {
   3805                 return _bcm_l3_defip_pair128_get(unit, lpm_cfg, nh_ecmp_idx);
   3806             }
   3807             break;
   3808         default:
   3809             if (soc_mem_index_count(unit, L3_DEFIPm) > 0) {
   3810                 return _bcm_fb_lpm_get(unit, lpm_cfg, nh_ecmp_idx);
   3811             }
   3812             break;
   3813     }
   3814 
   3815     return (BCM_E_NOT_FOUND);
   3816 }
   3817 
   3818 /*
   3819  * Function:
   3820  *      _bcm_kt2_l3_lpm_add
   3821  * Purpose:
   3822  *      Add an entry to KT2 route table table.
   3823  * Parameters:
   3824  *      unit        - (IN)SOC unit number.
   3825  *      lpm_cfg     - (IN)Buffer to fill defip information. 
   3826  *      nh_ecmp_idx - (IN)Next hop or ecmp group index.
   3827  * Returns:
   3828  *      BCM_E_XXX
   3829  */
   3830 int
   3831 _bcm_kt2_l3_lpm_add(int unit, _bcm_defip_cfg_t *lpm_cfg, int nh_ecmp_idx)
   3832 {
   3833     soc_mem_t mem = L3_DEFIPm;
   3834 
   3835     /* Input parameters check */
   3836     if (NULL == lpm_cfg) {
   3837         return (BCM_E_PARAM);
   3838     }
   3839 
   3840     BCM_IF_ERROR_RETURN(_bcm_kt2_l3_defip_mem_get(unit, lpm_cfg->defip_flags,
   3841                                               lpm_cfg->defip_sub_len, &mem));
   3842 
   3843     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3844         if (mem == L3_DEFIPm || mem == L3_DEFIP_PAIR_128m) {
   3845             return _bcm_l3_scaled_lpm_add(unit, lpm_cfg, nh_ecmp_idx);
   3846         }
   3847     }
   3848 
   3849     switch (mem) {
   3850         case L3_DEFIP_PAIR_128m:
   3851             if (soc_mem_index_count(unit, L3_DEFIP_PAIR_128m) > 0) {
   3852                 return _bcm_l3_defip_pair128_add(unit, lpm_cfg, nh_ecmp_idx);
   3853             }
   3854             break;
   3855         default:
   3856             if (soc_mem_index_count(unit, L3_DEFIPm) > 0) {
   3857                 return _bcm_fb_lpm_add(unit, lpm_cfg, nh_ecmp_idx);
   3858             }
   3859             break;
   3860     }
   3861 
   3862     return (BCM_E_FULL);
   3863 }
   3864 
   3865 /*
   3866  * Function:
   3867  *      _bcm_kt2_l3_lpm_del
   3868  * Purpose:
   3869  *      Delete an entry from the route table.
   3870  * Parameters:
   3871  *      unit    - (IN)SOC unit number.
   3872  *      lpm_cfg - (IN)Buffer to fill defip information. 
   3873  * Returns:
   3874  *      BCM_E_XXX
   3875  */
   3876 int
   3877 _bcm_kt2_l3_lpm_del(int unit, _bcm_defip_cfg_t *lpm_cfg)
   3878 {
   3879     soc_mem_t mem = L3_DEFIPm;
   3880     uint32 max_v6_entries = BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit);
   3881 
   3882     /* Input parameters check */
   3883     if (NULL == lpm_cfg) {
   3884         return (BCM_E_PARAM);
   3885     }
   3886 
   3887     BCM_IF_ERROR_RETURN(_bcm_kt2_l3_defip_mem_get(unit, lpm_cfg->defip_flags,
   3888                                               lpm_cfg->defip_sub_len, &mem));
   3889 
   3890     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3891         if (mem == L3_DEFIPm || mem == L3_DEFIP_PAIR_128m) {
   3892             return _bcm_l3_scaled_lpm_del(unit, lpm_cfg);
   3893         }
   3894     }
   3895 
   3896     switch (mem) {
   3897         case L3_DEFIP_PAIR_128m:
   3898             if (max_v6_entries > 0) {
   3899                 return _bcm_l3_defip_pair128_del(unit, lpm_cfg);
   3900             }
   3901             break;
   3902         default: 
   3903             if (soc_mem_index_count(unit, L3_DEFIPm) > 0) {
   3904                 return _bcm_fb_lpm_del(unit, lpm_cfg);
   3905             }
   3906             break;
   3907     }
   3908 
   3909     return (BCM_E_NOT_FOUND);
   3910 }
   3911 
   3912 /*
   3913  * Function:
   3914  *      _bcm_kt2_l3_lpm_update_match
   3915  * Purpose:
   3916  *      Update/Delete all entries in defip table matching a certain rule.
   3917  * Parameters:
   3918  *      unit     - (IN)SOC unit number.
   3919  *      trv_data - (IN)Delete pattern + compare,act,notify routines.  
   3920  * Returns:
   3921  *      BCM_E_XXX
   3922  */
   3923 int
   3924 _bcm_kt2_l3_lpm_update_match(int unit, _bcm_l3_trvrs_data_t *trv_data)
   3925 {
   3926     int rv1 = BCM_E_NONE;
   3927     int rv2 = BCM_E_NONE;
   3928     uint32 max_v6_entries = BCM_XGS3_L3_IP6_MAX_128B_ENTRIES(unit);
   3929 
   3930     if (NULL == trv_data) {
   3931         return (BCM_E_PARAM);
   3932     }
   3933 
   3934     if (soc_feature(unit, soc_feature_l3_lpm_scaling_enable)) {
   3935         return _bcm_l3_scaled_lpm_update_match(unit, trv_data);
   3936     }
   3937 
   3938     if ((trv_data->flags & BCM_L3_IP6) && (max_v6_entries > 0)) {
   3939         rv2 = _bcm_l3_defip_pair128_update_match(unit, trv_data);
   3940     }
   3941 
   3942     if (soc_mem_index_count(unit, L3_DEFIPm) > 0) {
   3943         rv1 = _bcm_fb_lpm_update_match(unit, trv_data);
   3944     }
   3945     BCM_IF_ERROR_RETURN(rv1);
   3946     BCM_IF_ERROR_RETURN(rv2);
   3947 
   3948     return (BCM_E_NONE);
   3949 }
   3950 #endif /* BCM_KATANA2_SUPPORT  */
   3951 #endif /* INCLUDE_L3  */