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

l2.c (75504B)


      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:    l2.c
      8  * Purpose: Trident3 L2 functions implementation
      9  */
     10 
     11 #include <shared/bsl.h>
     12 
     13 #include <soc/defs.h>
     14 
     15 #include <assert.h>
     16 
     17 #include <sal/core/libc.h>
     18 #if defined(BCM_TRIDENT3_SUPPORT)
     19 
     20 #include <soc/mem.h>
     21 #include <soc/cm.h>
     22 #include <soc/drv.h>
     23 #include <soc/register.h>
     24 #include <soc/memory.h>
     25 #include <soc/hash.h>
     26 #include <soc/l2x.h>
     27 #include <soc/triumph.h>
     28 #include <soc/trident2.h>
     29 #include <soc/trident3.h>
     30 #include <soc/format.h>
     31 #include <soc/esw/flow_db.h>
     32 
     33 #include <bcm/l2.h>
     34 #include <bcm/error.h>
     35 
     36 #include <bcm_int/esw/mbcm.h>
     37 #include <bcm_int/esw/l2.h>
     38 #include <bcm_int/esw/firebolt.h>
     39 #include <bcm_int/esw/trx.h>
     40 #include <bcm_int/esw/triumph.h>
     41 #include <bcm_int/esw/mpls.h>
     42 #include <bcm_int/esw/mim.h>
     43 #include <bcm_int/esw/stack.h>
     44 #include <bcm_int/esw/trunk.h>
     45 #include <bcm_int/common/multicast.h>
     46 #include <bcm_int/esw/multicast.h>
     47 #include <bcm_int/esw/virtual.h>
     48 #include <bcm_int/esw_dispatch.h>
     49 #include <bcm_int/esw/trident.h>
     50 #include <bcm_int/esw/switch.h>
     51 #include <bcm_int/esw/triumph3.h>
     52 #include <bcm_int/esw/trident2.h>
     53 #include <bcm_int/esw/trident3.h>
     54 #include <bcm_int/esw/flow.h>
     55 
     56 extern int
     57 _bcm_td3_evxlt_entry_valid( int unit, soc_mem_t mem, uint32 *entry, int *valid);
     58 
     59 #define DEST_TYPE_INVALID  0
     60 #define DEST_TYPE0_DVP  1
     61 #define DEST_TYPE0_DGPP 2
     62 #define DEST_TYPE1_L2MC 2
     63 #define DEST_TYPE1_IPMC 3
     64 #define DEST_TYPE2_LAG  1
     65 #define DEST_TYPE3_MY_STATION 3
     66 
     67 /* just need to clear SRC or DES hit bit. Customers may call API bcm_esw_l2_replace
     68 *  with parameter *match_addr which value is NULL */
     69 #define _CLEAR_ALL_ENTRIES_SRC_OR_DES_HIT_BIT(flag) \
     70                   (!(flag & (BCM_L2_REPLACE_MATCH_VLAN |\
     71                              BCM_L2_REPLACE_MATCH_MAC |\
     72                              BCM_L2_REPLACE_MATCH_DEST)) &&\
     73                    (flag & (BCM_L2_REPLACE_DES_HIT_CLEAR |\
     74                             BCM_L2_REPLACE_SRC_HIT_CLEAR)))
     75 
     76 #define EXTRACT_MAC_DA_27_0(da)     ((da)[0] & 0x0fffffff)
     77 #define EXTRACT_MAC_DA_47_28(da) \
     78     ((((da)[1]<<4) | (((da)[0]>>28) & 0xf)) & 0xfffff)
     79 
     80 #define COMBINE_MAC_DA_32_0(da)     ((da)[0] | (((da)[1] & 0xf)<<28))
     81 #define COMBINE_MAC_DA_47_32(da)    ((da)[1]>>4)
     82 
     83 #define _BCM_TD3_EXLATE_CHANGE_L2_FIELDS_KEY_TYPE 0x11
     84 #define _BCM_TD3_EXLATE_CHANGE_L2_FIELDS_DATA_TYPE 0x16
     85 
     86 /*
     87  * Function:
     88  *      _bcm_td3_flex_l2_to_l2x
     89  * Purpose:
     90  *      Convert an L2 API data structure to a Trident3 L2 flex-view entry
     91  * Parameters:
     92  *      unit        Unit number
     93  *      l2x_entry   (OUT) Trident3 L2X entry
     94  *      l2addr      L2 API data structure
     95  *      key_only    Only construct key portion
     96  */
     97 int
     98 _bcm_td3_flex_l2_to_l2x(int unit, l2x_entry_t *l2x_entry, bcm_l2_addr_t *l2addr, int key_only)
     99 {
    100     int vfi;
    101     int tid_is_vp_lag;
    102     bcm_cos_t cos_dst = l2addr->cos_dst;
    103     int group = l2addr->group;
    104     int my_station_config = 0;
    105     int i;
    106     int rv = BCM_E_NONE;
    107     uint32  view_id;
    108     uint32  field_array[128];
    109     uint32  field_count;
    110     uint32  opaque_array[16];
    111     uint32  opaque_count;
    112     bcm_flow_logical_field_t* user_fields;
    113     int j;
    114 
    115     uint32 action_set = 0;
    116     uint8 process_table_management = 0;
    117     uint8 process_fixed = 0;
    118     uint8 process_fwd_attributes = 0;
    119     uint8 process_qos = 0;
    120     uint8 process_class_id = 0;
    121     uint8 process_destination = 0;
    122     uint8 process_vlan=0;
    123     uint8 process_vfi=0;
    124     uint8 process_mac=0;
    125 
    126     /* Get view id corresponding to the specified flow. */
    127     rv = soc_flow_db_ffo_to_mem_view_id_get(unit,
    128                           l2addr->flow_handle,
    129                           l2addr->flow_option_handle,
    130                           SOC_FLOW_DB_FUNC_L2_SWITCH_ID,
    131                           &view_id);
    132     BCM_IF_ERROR_RETURN(rv);
    133 
    134     /* Initialize control field list for this view id. */
    135     rv = soc_flow_db_mem_view_entry_init(unit, view_id, (uint32*) l2x_entry);
    136 
    137     /* Get logical KEY field list for this view id. */
    138     rv = soc_flow_db_mem_view_field_list_get(unit,
    139                             view_id,
    140                             SOC_FLOW_DB_FIELD_TYPE_LOGICAL_KEY,
    141                             16,
    142                             opaque_array,
    143                             &opaque_count);
    144     BCM_IF_ERROR_RETURN(rv);
    145 
    146     user_fields = l2addr->logical_fields;
    147 
    148     for (i=0; i<opaque_count; i++) {
    149         for (j = 0; j < l2addr->num_of_fields; j++) {
    150             if (user_fields[j].id == opaque_array[i]) {
    151                 soc_mem_field32_set(unit, view_id, l2x_entry, user_fields[j].id,
    152                                 user_fields[j].value);
    153                 break;
    154             }
    155         }
    156     }
    157 
    158 
    159     /* Get KEY field list corresponding to the view id. */
    160     rv = soc_flow_db_mem_view_field_list_get(unit,
    161                             view_id,
    162                             SOC_FLOW_DB_FIELD_TYPE_KEY,
    163                             128,
    164                             field_array,
    165                             &field_count);
    166     BCM_IF_ERROR_RETURN(rv);
    167  
    168     for (i=0; i<field_count; i++) {
    169         switch (field_array[i]) {
    170             case VFIf:
    171                 process_vfi = 1;
    172                 break;
    173             case MAC_DAf:
    174                 process_mac = 1;
    175                 break;
    176             case VLAN_IDf:
    177                 process_vlan = 1;
    178                 break;
    179             default:
    180                 break;
    181         }
    182     }
    183 
    184     if (_BCM_VPN_VFI_IS_SET(l2addr->vid)) {
    185         if (!process_vfi)  {
    186             return BCM_E_PARAM;
    187         }
    188         _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, l2addr->vid);
    189         soc_mem_field32_set(unit, view_id, l2x_entry, VFIf, vfi);
    190     } else {
    191          if (!_BCM_MPLS_VPN_IS_VPWS(l2addr->vid)) {
    192              if (process_vlan)  {
    193                 VLAN_CHK_ID(unit, l2addr->vid);
    194                 soc_mem_field32_set(unit, view_id, l2x_entry, VLAN_IDf, l2addr->vid);
    195              }
    196          }
    197     }
    198 
    199     if (process_mac) {
    200         soc_mem_mac_addr_set(unit, view_id, l2x_entry, MAC_DAf, l2addr->mac);
    201     }
    202 
    203     if (key_only) {
    204         return BCM_E_NONE;
    205     }
    206 
    207     /* Get logical PDD field list for this view id. */
    208     rv = soc_flow_db_mem_view_field_list_get(unit,
    209                             view_id,
    210                             SOC_FLOW_DB_FIELD_TYPE_LOGICAL_POLICY_DATA,
    211                             16,
    212                             opaque_array,
    213                             &opaque_count);
    214     BCM_IF_ERROR_RETURN(rv);
    215 
    216     user_fields = l2addr->logical_fields;
    217 
    218     for (i=0; i<opaque_count; i++) {
    219         if (user_fields[i].id == opaque_array[i]) {
    220             soc_mem_field32_set(unit, view_id, &l2x_entry, user_fields[i].id,
    221                                 user_fields[i].value);
    222         }
    223     }
    224 
    225     /* Get PDD field list corresponding to the view id. */
    226     rv = soc_flow_db_mem_view_field_list_get(unit,
    227                             view_id,
    228                             SOC_FLOW_DB_FIELD_TYPE_POLICY_DATA,
    229                             128,
    230                             field_array,
    231                             &field_count);
    232     BCM_IF_ERROR_RETURN(rv);
    233 
    234     for (i=0; i<field_count; i++) {
    235         switch (field_array[i]) {
    236             case DESTINATION_ACTION_SETf:
    237                 process_destination = 1;
    238                 break;
    239             case CLASS_ID_ACTION_SETf:
    240                 process_class_id = 1;
    241                 break;
    242             case QOS_ACTION_SETf:
    243                 process_qos = 1;
    244                 break;
    245             case FWD_ATTRIBUTES_ACTION_SETf:
    246                 process_fwd_attributes = 1;
    247                 break;
    248             case FIXED_ACTION_SETf:
    249                 process_fixed = 1;
    250                 break;
    251             case TABLE_MANAGEMENT_ACTION_SETf:
    252                 process_table_management = 1;
    253                 break;
    254             default:
    255                 return BCM_E_INTERNAL;
    256         }
    257     }
    258 
    259     if (!process_destination) {
    260         return BCM_E_INTERNAL;
    261     }
    262 
    263     if (BCM_MAC_IS_MCAST(l2addr->mac)) {
    264         if (l2addr->l2mc_group < 0) {
    265             return BCM_E_PARAM;
    266         }
    267 
    268         action_set = 0;
    269 
    270         if (_BCM_MULTICAST_IS_FLOW(l2addr->l2mc_group)) {
    271             soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    272                                &action_set, DEST_TYPE1f, DEST_TYPE1_IPMC);
    273         }
    274         else {
    275             soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    276                                &action_set, DEST_TYPE1f, DEST_TYPE1_L2MC);
    277         }
    278         soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    279                                &action_set, L2MC_GROUPf,
    280                                _BCM_MULTICAST_ID_GET(l2addr->l2mc_group));
    281 
    282         soc_mem_field32_set(unit, view_id, l2x_entry,
    283                             DESTINATION_ACTION_SETf, action_set);
    284     } else {
    285         bcm_port_t      port = -1;
    286         bcm_trunk_t     tgid = BCM_TRUNK_INVALID;
    287         bcm_module_t    modid = -1;
    288         int             gport_id = -1;
    289 
    290         if (BCM_GPORT_IS_SET(l2addr->port)) {
    291             _bcm_l2_gport_params_t  g_params;
    292 
    293             if (BCM_GPORT_IS_BLACK_HOLE(l2addr->port)) {
    294                 if (!process_fwd_attributes) {
    295                     return BCM_E_PARAM;
    296                 }
    297                 action_set = 0;
    298                 soc_format_field32_set(unit, FWD_ATTRIBUTES_ACTION_SETfmt,
    299                                &action_set, SRC_DISCARDf, 1);
    300                 soc_mem_field32_set(unit, view_id, l2x_entry,
    301                                  FWD_ATTRIBUTES_ACTION_SETf, action_set);
    302             } else {
    303                 /*soc_L2Xm_field32_set(unit, l2x_entry, SRC_DISCARDf, 0);*/
    304                 BCM_IF_ERROR_RETURN(
    305                         _bcm_esw_l2_gport_parse(unit, l2addr, &g_params));
    306 
    307                 switch (g_params.type) {
    308                     case _SHR_GPORT_TYPE_TRUNK:
    309                         tgid = g_params.param0;
    310                         break;
    311                     case  _SHR_GPORT_TYPE_MODPORT:
    312                         port = g_params.param0;
    313                         modid = g_params.param1;
    314                         break;
    315                     case _SHR_GPORT_TYPE_LOCAL_CPU:
    316                         port = g_params.param0;
    317                         BCM_IF_ERROR_RETURN(
    318                                 bcm_esw_stk_my_modid_get(unit, &modid));
    319                         break;
    320                     case _SHR_GPORT_TYPE_SUBPORT_GROUP:
    321                         gport_id = g_params.param0;
    322                         break;
    323                     case _SHR_GPORT_TYPE_SUBPORT_PORT:
    324                         gport_id = g_params.param0;
    325                     break;
    326                     case _SHR_GPORT_TYPE_MPLS_PORT:
    327                     gport_id = g_params.param0;
    328                     break;
    329                     case _SHR_GPORT_TYPE_MIM_PORT:
    330                     case _SHR_GPORT_TYPE_WLAN_PORT:
    331                     case _SHR_GPORT_TYPE_VLAN_PORT:
    332                     case _SHR_GPORT_TYPE_NIV_PORT:
    333                     case _SHR_GPORT_TYPE_EXTENDER_PORT:
    334                         gport_id = g_params.param0;
    335                         break;
    336                     case _SHR_GPORT_TYPE_TRILL_PORT:
    337                     case _SHR_GPORT_TYPE_L2GRE_PORT:
    338                     case _SHR_GPORT_TYPE_VXLAN_PORT:
    339                     case _SHR_GPORT_TYPE_FLOW_PORT:
    340 
    341                         gport_id = g_params.param0;
    342                         break;
    343                     default:
    344                         return BCM_E_PORT;
    345                 }
    346             }
    347         } else if (l2addr->flags & BCM_L2_TRUNK_MEMBER) {
    348             tgid = l2addr->tgid;
    349 
    350         } else {
    351             if ((NUM_MODID(unit) > 1) && (l2addr->port > SOC_MODPORT_MAX(unit))) {
    352                 bcm_module_t my_modid;
    353                 int          isLocal;
    354                 BCM_IF_ERROR_RETURN (bcm_esw_stk_my_modid_get(unit, &my_modid));
    355                 if (BCM_MODID_INVALID != my_modid) {
    356                    BCM_IF_ERROR_RETURN
    357                     (_bcm_esw_modid_is_local(unit, l2addr->modid, &isLocal));
    358                    if (isLocal) {
    359                       l2addr->port %= (SOC_MODPORT_MAX(unit) + 1);
    360                     }
    361                 }
    362 	    }
    363             BCM_IF_ERROR_RETURN(
    364                 _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
    365                                        l2addr->modid, l2addr->port,
    366                                        &modid, &port));
    367             /* Check parameters */
    368             if (!SOC_MODID_ADDRESSABLE(unit, modid)) {
    369                 return BCM_E_BADID;
    370             }
    371             if (!SOC_PORT_ADDRESSABLE(unit, port)) {
    372                 return BCM_E_PORT;
    373             }
    374         }
    375 
    376         action_set = 0;
    377         /* Setting l2x_entry fields according to parameters */
    378         if ( BCM_TRUNK_INVALID != tgid) {
    379             BCM_IF_ERROR_RETURN(_bcm_esw_trunk_id_is_vp_lag(unit, tgid,
    380                             &tid_is_vp_lag));
    381             if (tid_is_vp_lag) {
    382                 if (soc_feature(unit, soc_feature_vp_lag)) {
    383                     int vp_lag_vp;
    384                     /* Get the VP value representing VP LAG */
    385                     BCM_IF_ERROR_RETURN(_bcm_esw_trunk_tid_to_vp_lag_vp(unit,
    386                                 tgid, &vp_lag_vp));
    387                     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    388                                        &action_set, DEST_TYPE0f, DEST_TYPE0_DVP);
    389                     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    390                                        &action_set, DVPf, vp_lag_vp);
    391                 } else {
    392                     return BCM_E_PORT;
    393                 }
    394             } else {
    395                     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    396                                        &action_set, DEST_TYPE2f, DEST_TYPE2_LAG);
    397                     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    398                                        &action_set, LAGf, tgid);
    399             }
    400         } else if (-1 != port) {
    401             soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    402                                &action_set, DEST_TYPE0f, DEST_TYPE0_DGPP);
    403             soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    404                                &action_set, DGPPf, 
    405                                modid << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | port);
    406         } else if (-1 != gport_id) {
    407             soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    408                                    &action_set, DEST_TYPE0f, DEST_TYPE0_DVP);
    409             soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    410                                    &action_set, DVPf, gport_id);
    411         }
    412         soc_mem_field32_set(unit, view_id, l2x_entry,
    413                             DESTINATION_ACTION_SETf, action_set);
    414     }
    415 
    416 /* not support in flex views */
    417 #if 0
    418     if (SOC_MEM_FIELD_VALID(unit, L2Xm, L3f)) {
    419         if (l2addr->flags & BCM_L2_L3LOOKUP) {
    420             soc_L2Xm_field32_set(unit, l2x_entry, L3f, 1);
    421         }
    422     }
    423 #endif
    424 
    425     if (SOC_L2X_GROUP_ENABLE_GET(unit)) {
    426         if (soc_feature(unit, soc_feature_overlaid_address_class) &&
    427             !BCM_L2_PRE_SET(l2addr->flags)) {
    428             if ((l2addr->group > SOC_OVERLAID_ADDR_CLASS_MAX(unit)) ||
    429                 (l2addr->group < 0)) {
    430                 return BCM_E_PARAM;
    431             }
    432             cos_dst = (l2addr->group & 0x3C0) >> 6;
    433             group = l2addr->group & 0x3F;
    434         }
    435     }
    436 
    437     if (SOC_CONTROL(unit)->l2x_group_enable && process_class_id) {
    438         soc_mem_field32_set(unit, view_id, l2x_entry,
    439                          CLASS_ID_ACTION_SETf, group);
    440     }
    441 
    442     action_set = 0;
    443     soc_format_field32_set(unit, FORWARDING_1_QOS_ACTION_SETfmt,
    444                            &action_set, PRIf, cos_dst);
    445     if (l2addr->flags & BCM_L2_SETPRI) {
    446         if (!process_qos) {
    447             return BCM_E_PARAM;
    448         }
    449         soc_format_field32_set(unit, FORWARDING_1_QOS_ACTION_SETfmt,
    450                                &action_set, RPEf, 1);
    451     }
    452     if (l2addr->flags & BCM_L2_COS_SRC_PRI) {
    453         if (!process_qos) {
    454             return BCM_E_PARAM;
    455         }
    456         soc_format_field32_set(unit, FORWARDING_1_QOS_ACTION_SETfmt,
    457                                &action_set, SCPf, 1);
    458     }
    459 
    460     if (process_qos) {
    461         soc_mem_field32_set(unit, view_id, l2x_entry,
    462                         QOS_ACTION_SETf, action_set);
    463     }
    464 
    465     action_set = 0;
    466     if (l2addr->flags & BCM_L2_COPY_TO_CPU) {
    467         if (!process_fwd_attributes) {
    468             return BCM_E_PARAM;
    469         }
    470         soc_format_field32_set(unit, FWD_ATTRIBUTES_ACTION_SETfmt,
    471                                &action_set, CPUf, 1);
    472     }
    473 
    474     if (l2addr->flags & BCM_L2_DISCARD_DST) {
    475         if (!process_fwd_attributes) {
    476             return BCM_E_PARAM;
    477         }
    478         soc_format_field32_set(unit, FWD_ATTRIBUTES_ACTION_SETfmt,
    479                                &action_set, DST_DISCARDf, 1);
    480     }
    481 
    482     if (l2addr->flags & BCM_L2_DISCARD_SRC) {
    483         if (!process_fwd_attributes) {
    484             return BCM_E_PARAM;
    485         }
    486         soc_format_field32_set(unit, FWD_ATTRIBUTES_ACTION_SETfmt,
    487                                &action_set, SRC_DISCARDf, 1);
    488     }
    489 
    490     if (process_fwd_attributes) {
    491         soc_mem_field32_set(unit, view_id, l2x_entry,
    492                             FWD_ATTRIBUTES_ACTION_SETf, action_set);
    493     }
    494 
    495     if (l2addr->flags & BCM_L2_PENDING) {
    496         if (!process_table_management) {
    497             return BCM_E_PARAM;
    498         }
    499         action_set = 0;
    500         soc_format_field32_set(unit, TABLE_MANAGEMENT_ACTION_SETfmt,
    501                                &action_set, PENDINGf, 1);
    502         soc_mem_field32_set(unit, view_id, l2x_entry,
    503                             TABLE_MANAGEMENT_ACTION_SETf, action_set);
    504     }
    505 
    506     if (l2addr->flags & BCM_L2_STATIC) {
    507         if (!process_fixed) {
    508             return BCM_E_PARAM;
    509         }
    510         /* STATIC_BITf */
    511         soc_mem_field32_set(unit, view_id, l2x_entry,
    512                             FIXED_ACTION_SETf, 1);
    513     }
    514 
    515     if ((l2addr->flags & BCM_L2_DES_HIT) ||
    516         (l2addr->flags & BCM_L2_HIT)) {
    517         soc_mem_field32_set(unit, view_id, l2x_entry, HITDAf, 1);
    518     }
    519 
    520     if ((l2addr->flags & BCM_L2_SRC_HIT) ||
    521         (l2addr->flags & BCM_L2_HIT)) {
    522         soc_mem_field32_set(unit, view_id, l2x_entry, HITSAf, 1);
    523     }
    524 
    525     if (SOC_MEM_FIELD_VALID(unit, view_id, LOCAL_SAf)) {
    526         if (l2addr->flags & BCM_L2_NATIVE) {
    527             soc_mem_field32_set(unit, view_id, l2x_entry, LOCAL_SAf, 1);
    528         }
    529     }
    530 
    531     my_station_config = soc_property_get(unit, spn_L2_ENTRY_USED_AS_MY_STATION, 0);
    532     if (soc_feature(unit, soc_feature_l2_entry_used_as_my_station)
    533         && my_station_config) {
    534         if (soc_feature(unit, soc_feature_mysta_profile)) {
    535             uint32 mysta_profile_id;
    536             bcm_l2_station_t station;
    537             my_station_profile_1_entry_t entry;
    538             sal_memset(&station, 0, sizeof(bcm_l2_station_t));
    539             sal_memset(&entry, 0, sizeof(entry));
    540             station.flags = l2addr->station_flags;
    541             if (l2addr->station_flags != 0) {
    542                 _bcm_l2_mysta_station_to_entry(unit, &station, MY_STATION_PROFILE_1m, &entry);
    543                 BCM_IF_ERROR_RETURN(
    544                     _bcm_l2_mysta_profile_entry_add(unit, &entry, 0,
    545                     &mysta_profile_id));
    546                 action_set = 0;
    547                 soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    548                                        &action_set, DEST_TYPE3f,
    549                                        DEST_TYPE3_MY_STATION);
    550                 soc_format_field32_set(unit, DESTINATION_FORMATfmt,
    551                                        &action_set, MY_STATION_PROFILE_IDXf,
    552                                        mysta_profile_id);
    553                 soc_mem_field32_set(unit, view_id, l2x_entry,
    554                                     DESTINATION_ACTION_SETf, action_set);
    555             }
    556         }
    557     } else {
    558         if (l2addr->station_flags & BCM_L2_STATION_IPV4
    559            || l2addr->station_flags & BCM_L2_STATION_IPV6
    560            || l2addr->station_flags & BCM_L2_STATION_ARP_RARP
    561            || l2addr->station_flags & BCM_L2_STATION_OAM
    562            || l2addr->station_flags & BCM_L2_STATION_FCOE
    563            || l2addr->station_flags & BCM_L2_STATION_IPV4_MCAST
    564            || l2addr->station_flags & BCM_L2_STATION_IPV6_MCAST) {
    565            return BCM_E_UNAVAIL;
    566         }
    567     }
    568 
    569     return BCM_E_NONE;
    570 }
    571 
    572 /*
    573  * Function:
    574  *      _bcm_td3_flex_l2_from_l2x
    575  * Purpose:
    576  *      Convert a Trident3 Flex L2X entry to an L2 API data structure
    577  * Parameters:
    578  *      unit        Unit number
    579  *      l2addr      (OUT) L2 API data structure
    580  *      l2x_entry   Trident3 L2X entry
    581  */
    582 int
    583 _bcm_td3_flex_l2_from_l2x(int unit, bcm_l2_addr_t *l2addr, l2x_entry_t *l2x_entry, int *mb_index)
    584 {
    585     int l2mc_index, vfi, rval;
    586     int my_station_config = 0;
    587     int i;
    588     int rv = BCM_E_NONE;
    589     uint32 action_set = 0;
    590 
    591     uint8 process_table_management = 0;
    592     uint8 process_fixed = 0;
    593     uint8 process_fwd_attributes = 0;
    594     uint8 process_qos = 0;
    595     uint8 process_class_id = 0;
    596     uint8 process_destination = 0;
    597     uint8 process_mac_block = 0;
    598     uint8 process_vlan = 0;
    599     uint8 process_vfi = 0;
    600     uint8 process_mac = 0;
    601 
    602     uint32 key_type;
    603     uint32 view_id=0;
    604     uint32 flex_data_array[128];
    605     uint32 flex_data_count;
    606     uint32 flex_key_array[64];
    607     uint32 flex_key_count;
    608     uint32 opaque_array[16];
    609     uint32 opaque_count;
    610     bcm_flow_logical_field_t* user_fields;
    611 
    612     key_type = soc_mem_field32_get(unit, L2Xm, l2x_entry, KEY_TYPEf);
    613 
    614     /* Get view id corresponding to key type */
    615     rv = soc_flow_db_mem_to_view_id_get(unit,
    616                                    L2_ENTRY_SINGLEm,
    617                                    key_type,
    618                                    SOC_FLOW_DB_DATA_TYPE_INVALID,
    619                                    0,
    620                                    NULL,
    621                                    &view_id);
    622 
    623     BCM_IF_ERROR_RETURN(rv);
    624 
    625     /* Get logical KEY field list corresponding to the view id. */
    626     rv = soc_flow_db_mem_view_field_list_get(unit,
    627                             view_id,
    628                             SOC_FLOW_DB_FIELD_TYPE_LOGICAL_KEY,
    629                             16,
    630                             opaque_array,
    631                             &opaque_count);
    632     BCM_IF_ERROR_RETURN(rv);
    633 
    634     user_fields = l2addr->logical_fields;
    635 
    636     for (i=0; i<opaque_count; i++) {
    637         user_fields[i].id = opaque_array[i];
    638         user_fields[i].value = soc_mem_field32_get(unit, view_id, l2x_entry,
    639                            opaque_array[i]);
    640     }
    641 
    642     user_fields = &l2addr->logical_fields[opaque_count];
    643 
    644      /* Get logical Data field list corresponding to the view id. */
    645     rv = soc_flow_db_mem_view_field_list_get(unit,
    646                             view_id,
    647                             SOC_FLOW_DB_FIELD_TYPE_LOGICAL_POLICY_DATA,
    648                             16,
    649                             opaque_array,
    650                             &opaque_count);
    651     BCM_IF_ERROR_RETURN(rv);
    652 
    653     for (i=0; i<opaque_count; i++) {
    654         user_fields[i].id = opaque_array[i];
    655         user_fields[i].value = soc_mem_field32_get(unit, view_id, l2x_entry,
    656                            opaque_array[i]);
    657     }
    658  
    659     /* Get KEY field list corresponding to the view id. */
    660     rv = soc_flow_db_mem_view_field_list_get(unit,
    661                             view_id,
    662                             SOC_FLOW_DB_FIELD_TYPE_KEY,
    663                             64,
    664                             flex_key_array,
    665                             &flex_key_count);
    666     BCM_IF_ERROR_RETURN(rv);
    667  
    668     for (i=0; i<flex_key_count; i++) {
    669         switch (flex_key_array[i]) {
    670             case VFIf:
    671                 process_vfi = 1;
    672                 break;
    673             case MAC_DAf:
    674                 process_mac = 1;
    675                 break;
    676             case VLAN_IDf:
    677                 process_vlan = 1;
    678                 break;
    679             default:
    680                 break;
    681         }
    682     }
    683 
    684     /* Get PDD field list corresponding to the view id. */
    685     rv = soc_flow_db_mem_view_field_list_get(unit,
    686                             view_id,
    687                             SOC_FLOW_DB_FIELD_TYPE_POLICY_DATA,
    688                             128,
    689                             flex_data_array,
    690                             &flex_data_count);
    691     BCM_IF_ERROR_RETURN(rv);
    692 
    693     for (i=0; i<flex_data_count; i++) {
    694         switch (flex_data_array[i]) {
    695             case DESTINATION_ACTION_SETf:
    696                 process_destination = 1;
    697                 break;
    698             case CLASS_ID_ACTION_SETf:
    699                 process_class_id = 1;
    700                 break;
    701             case QOS_ACTION_SETf:
    702                 process_qos = 1;
    703                 break;
    704             case FWD_ATTRIBUTES_ACTION_SETf:
    705                 process_fwd_attributes = 1;
    706                 break;
    707             case FIXED_ACTION_SETf:
    708                 process_fixed = 1;
    709                 break;
    710             case TABLE_MANAGEMENT_ACTION_SETf:
    711                 process_table_management = 1;
    712                 break;
    713             case MAC_BLOCK_ACTION_SETf:
    714                 process_mac_block = 1;
    715                 break;
    716             default:
    717                 break;
    718         }
    719     }
    720 
    721     if (!process_destination) {
    722         return BCM_E_INTERNAL;
    723     }
    724     if (process_mac) {
    725         soc_mem_mac_addr_get(unit, view_id, l2x_entry, MAC_DAf, l2addr->mac);
    726     }
    727 
    728     if (process_vfi) {
    729         vfi = soc_mem_field32_get(unit, view_id, l2x_entry, VFIf);
    730         COMPILER_REFERENCE(vfi);
    731         /* VPLS or MIM VPN */
    732 #if defined(INCLUDE_L3)
    733         if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMpls)) {
    734             _BCM_MPLS_VPN_SET(l2addr->vid, _BCM_MPLS_VPN_TYPE_VPLS, vfi);
    735         } else if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeMim)) {
    736             _BCM_MIM_VPN_SET(l2addr->vid, _BCM_MIM_VPN_TYPE_MIM, vfi);
    737         } else  if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeL2Gre)) {
    738                 if (soc_feature(unit, soc_feature_l2gre)) {
    739                     BCM_IF_ERROR_RETURN
    740                         (_bcm_tr3_l2gre_vpn_get(unit, vfi, &l2addr->vid));
    741                 }
    742         } else if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeVxlan)) {
    743                 if (soc_feature(unit, soc_feature_vxlan)) {
    744                     BCM_IF_ERROR_RETURN(
    745                       _bcm_td2_vxlan_vpn_get(unit, vfi, &l2addr->vid));
    746                 }
    747         } else if (_bcm_vfi_used_get(unit, vfi, _bcmVfiTypeFlow)) {
    748                 if (soc_feature(unit, soc_feature_flex_flow)) {
    749                     BCM_IF_ERROR_RETURN(
    750                       bcmi_esw_flow_vpnid_get(unit, vfi, &l2addr->vid));
    751                 }
    752         }
    753 #endif /* INCLUDE_L3 */
    754     } else if (process_vlan) {
    755         l2addr->vid = soc_mem_field32_get(unit, view_id, l2x_entry, VLAN_IDf);
    756     }
    757 
    758     if (process_mac && BCM_MAC_IS_MCAST(l2addr->mac)) {
    759             uint32 dest_type1 = DEST_TYPE_INVALID;
    760             l2addr->flags |= BCM_L2_MCAST;
    761             action_set = soc_mem_field32_get(unit, view_id, l2x_entry,
    762                                DESTINATION_ACTION_SETf);
    763             l2mc_index = soc_format_field32_get(unit, DESTINATION_FORMATfmt,
    764                                 &action_set, L2MC_GROUPf);
    765             dest_type1 = soc_format_field32_get(unit, DESTINATION_FORMATfmt,
    766                                 &action_set, DEST_TYPE1f);
    767             if (dest_type1 != DEST_TYPE1_L2MC) {
    768                 l2mc_index = 0;
    769             }
    770             l2addr->l2mc_group = l2mc_index;
    771             /* Translate l2mc index */
    772             BCM_IF_ERROR_RETURN(
    773                 bcm_esw_switch_control_get(unit, bcmSwitchL2McIdxRetType, &rval));
    774             if (rval) {
    775                _BCM_MULTICAST_GROUP_SET(l2addr->l2mc_group, _BCM_MULTICAST_TYPE_L2,
    776                                                                     l2addr->l2mc_group);
    777             }
    778     } else {
    779         _bcm_gport_dest_t       dest;
    780         int                     dest_type_is_trunk = 0;
    781         int                     isGport = 0;
    782 #if defined(INCLUDE_L3)
    783         int                     dest_type_is_dvp = 0;
    784         uint32 dest_type0 = DEST_TYPE_INVALID;
    785         uint32 dest_type2 = DEST_TYPE_INVALID;
    786 #endif
    787         uint32 dest_value = 0;
    788 
    789         _bcm_gport_dest_t_init(&dest);
    790 #if defined(INCLUDE_L3)
    791         action_set = soc_mem_field32_get(unit, view_id, l2x_entry,
    792                            DESTINATION_ACTION_SETf);
    793         dest_type0 = soc_format_field32_get(unit, DESTINATION_FORMATfmt,
    794                             &action_set, DEST_TYPE0f);
    795         dest_type2 = soc_format_field32_get(unit, DESTINATION_FORMATfmt,
    796                             &action_set, DEST_TYPE2f);
    797         if (dest_type0 == DEST_TYPE0_DVP) {
    798             dest_type_is_dvp = 1;
    799         } else if (dest_type2 == DEST_TYPE2_LAG) {
    800             dest_type_is_trunk = 1;
    801         }
    802 
    803         if (dest_type_is_dvp) {
    804             int vp;
    805             vp = soc_format_field32_get(unit, DESTINATION_FORMATfmt,
    806                                 &action_set, DVPf);
    807 
    808             /* MPLS/MiM virtual port unicast */
    809             if (_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) {
    810                 dest.mpls_id = vp;
    811                 dest.gport_type = _SHR_GPORT_TYPE_MPLS_PORT;
    812                 isGport=1;
    813             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) {
    814                 dest.mim_id = vp;
    815                 dest.gport_type = _SHR_GPORT_TYPE_MIM_PORT;
    816                 isGport=1;
    817             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) {
    818                 dest.vxlan_id  = vp;
    819                 dest.gport_type = _SHR_GPORT_TYPE_VXLAN_PORT;
    820                 isGport=1;
    821             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeFlow)) {
    822                 dest.flow_id  = vp;
    823                 dest.gport_type = _SHR_GPORT_TYPE_FLOW_PORT;
    824                 isGport=1;
    825             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) {
    826                 dest.l2gre_id  = vp;
    827                 dest.gport_type = _SHR_GPORT_TYPE_L2GRE_PORT;
    828                 isGport=1;
    829             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeSubport)) {
    830             /* Subport/WLAN unicast */
    831                     dest.subport_id = vp;
    832                     dest.gport_type = _SHR_GPORT_TYPE_SUBPORT_GROUP;
    833                     isGport=1;
    834             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) {
    835                 dest.wlan_id = vp;
    836                 dest.gport_type = _SHR_GPORT_TYPE_WLAN_PORT;
    837                 isGport=1;
    838             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) {
    839                 dest.vlan_vp_id = vp;
    840                 dest.gport_type = _SHR_GPORT_TYPE_VLAN_PORT;
    841                 isGport=1;
    842             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) {
    843                 dest.niv_id = vp;
    844                 dest.gport_type = _SHR_GPORT_TYPE_NIV_PORT;
    845                 isGport=1;
    846             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeTrill)) {
    847                 dest.trill_id  = vp;
    848                 dest.gport_type = _SHR_GPORT_TYPE_TRILL_PORT;
    849                 isGport=1;
    850             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) {
    851                 dest.extender_id = vp;
    852                 dest.gport_type = _SHR_GPORT_TYPE_EXTENDER_PORT;
    853                 isGport=1;
    854             } else if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) {
    855                 l2addr->flags |= BCM_L2_TRUNK_MEMBER;
    856                 BCM_IF_ERROR_RETURN(_bcm_esw_trunk_vp_lag_vp_to_tid(unit,
    857                             vp, &l2addr->tgid));
    858                 dest.tgid = l2addr->tgid;
    859                 dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
    860                 BCM_IF_ERROR_RETURN(bcm_esw_switch_control_get(unit,
    861                             bcmSwitchUseGport, &isGport));
    862             } else {
    863                 /* L2 entries with Stale Gport */
    864                 dest.gport_type = BCM_GPORT_INVALID;
    865                 isGport=0;
    866             }
    867         } else
    868 #endif /* INCLUDE_L3 */
    869         if (dest_type_is_trunk) {
    870             /* Trunk group */
    871             l2addr->flags |= BCM_L2_TRUNK_MEMBER;
    872             dest_value = soc_format_field32_get(unit, DESTINATION_FORMATfmt,
    873                                 &action_set, DVPf);
    874             l2addr->tgid = dest_value & SOC_MEM_FIF_DGPP_TGID_MASK;
    875 
    876             dest.tgid = l2addr->tgid;
    877             dest.gport_type = _SHR_GPORT_TYPE_TRUNK;
    878             BCM_IF_ERROR_RETURN(
    879                 bcm_esw_switch_control_get(unit, bcmSwitchUseGport, &isGport));
    880         } else {
    881             bcm_module_t    mod_in, mod_out;
    882             bcm_port_t      port_in, port_out;
    883 
    884             dest_value = soc_format_field32_get(unit, DESTINATION_FORMATfmt,
    885                                 &action_set, DGPPf);
    886             port_in = dest_value & SOC_MEM_FIF_DGPP_PORT_MASK;
    887             mod_in = (dest_value & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >>
    888                             SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS;
    889 
    890             BCM_IF_ERROR_RETURN
    891                 (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET,
    892                                         mod_in, port_in, &mod_out, &port_out));
    893             l2addr->modid = mod_out;
    894             l2addr->port = port_out;
    895             dest.port = l2addr->port;
    896             dest.modid = l2addr->modid;
    897             dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
    898             BCM_IF_ERROR_RETURN(
    899                 bcm_esw_switch_control_get(unit, bcmSwitchUseGport, &isGport));
    900         }
    901 
    902         if (isGport) {
    903             BCM_IF_ERROR_RETURN(
    904                 _bcm_esw_gport_construct(unit, &dest, &(l2addr->port)));
    905         }
    906     }
    907 
    908     if (SOC_CONTROL(unit)->l2x_group_enable && process_class_id) {
    909         l2addr->group = soc_mem_field32_get(unit, view_id, l2x_entry,
    910                                            CLASS_ID_ACTION_SETf);
    911     } else if (process_mac_block) {
    912         action_set = soc_mem_field32_get(unit, view_id, l2x_entry,
    913                                MAC_BLOCK_ACTION_SETf);
    914         *mb_index = soc_format_field32_get(unit, MAC_BLOCK_ACTION_SETfmt,
    915                                 &action_set, MAC_BLOCK_INDEXf);
    916     }
    917 
    918     if (process_qos) {
    919         action_set = soc_mem_field32_get(unit, view_id, l2x_entry,
    920                                QOS_ACTION_SETf);
    921         if (soc_format_field32_get(unit, FORWARDING_1_QOS_ACTION_SETfmt,
    922                                 &action_set, RPEf)) {
    923             l2addr->flags |= BCM_L2_SETPRI;
    924         }
    925         if (soc_format_field32_get(unit, FORWARDING_1_QOS_ACTION_SETfmt,
    926                                 &action_set, SCPf)) {
    927             l2addr->flags |= BCM_L2_COS_SRC_PRI;
    928         }
    929 
    930         l2addr->cos_dst = soc_format_field32_get(unit,
    931                              FORWARDING_1_QOS_ACTION_SETfmt,&action_set, PRIf);
    932         l2addr->cos_src = soc_format_field32_get(unit,
    933                              FORWARDING_1_QOS_ACTION_SETfmt,&action_set, PRIf);
    934     }
    935 
    936     if (SOC_CONTROL(unit)->l2x_group_enable) {
    937         if (soc_feature(unit, soc_feature_overlaid_address_class) &&
    938             !BCM_L2_PRE_SET(l2addr->flags)) {
    939             l2addr->group |= (l2addr->cos_dst & 0xF) << 6;
    940         }
    941     } 
    942 
    943     if (process_fwd_attributes) {
    944         action_set = soc_mem_field32_get(unit, view_id, l2x_entry,
    945                                FWD_ATTRIBUTES_ACTION_SETf);
    946         if (soc_format_field32_get(unit, FORWARDING_1_QOS_ACTION_SETfmt,
    947                                 &action_set, CPUf)) {
    948             l2addr->flags |= BCM_L2_COPY_TO_CPU;
    949         }
    950 
    951         if (soc_format_field32_get(unit, FORWARDING_1_QOS_ACTION_SETfmt,
    952                                 &action_set, DST_DISCARDf)) {
    953             l2addr->flags |= BCM_L2_DISCARD_DST;
    954         }
    955 
    956         if (soc_format_field32_get(unit, FORWARDING_1_QOS_ACTION_SETfmt,
    957                                 &action_set, SRC_DISCARDf)) {
    958             l2addr->flags |= BCM_L2_DISCARD_SRC;
    959         }
    960     }
    961 
    962     if (process_fixed) {
    963         if (soc_mem_field32_get(unit, view_id, l2x_entry, STATIC_BITf)) {
    964             l2addr->flags |= BCM_L2_STATIC;
    965         }
    966     }
    967 
    968     if (process_table_management) {
    969         action_set = soc_mem_field32_get(unit, view_id, l2x_entry,
    970                                TABLE_MANAGEMENT_ACTION_SETf);
    971         if (soc_format_field32_get(unit, TABLE_MANAGEMENT_ACTION_SETfmt,
    972                                 &action_set, PENDINGf)) {
    973             l2addr->flags |= BCM_L2_PENDING;
    974         }
    975     }
    976 
    977     if (soc_mem_field_valid(unit, view_id, HITDAf)) {
    978         if (soc_mem_field32_get(unit, view_id, l2x_entry, HITDAf)) {
    979             l2addr->flags |= BCM_L2_DES_HIT;
    980             l2addr->flags |= BCM_L2_HIT;
    981         }
    982     }
    983 
    984     if (soc_mem_field_valid(unit, view_id, HITSAf)) {
    985         if (soc_mem_field32_get(unit, view_id, l2x_entry, HITSAf)) {
    986             l2addr->flags |= BCM_L2_SRC_HIT;
    987             l2addr->flags |= BCM_L2_HIT;
    988         }
    989     }
    990 
    991     if (soc_mem_field_valid(unit, view_id, LOCAL_SAf)) {
    992         if (soc_mem_field32_get(unit, view_id, l2x_entry, LOCAL_SAf)) {
    993             l2addr->flags |= BCM_L2_NATIVE;
    994         }
    995     }
    996 
    997     my_station_config = soc_property_get(unit, spn_L2_ENTRY_USED_AS_MY_STATION, 0);
    998     if (soc_feature(unit, soc_feature_l2_entry_used_as_my_station)
    999         && my_station_config) {
   1000          if (soc_feature(unit, soc_feature_mysta_profile)) {
   1001               bcm_l2_station_t station;
   1002               uint32 mysta_prof_id = 0;
   1003               uint32 dest_type3 = DEST_TYPE_INVALID;
   1004               my_station_profile_1_entry_t entry_prof;
   1005 
   1006               sal_memset(&station, 0, sizeof(bcm_l2_station_t));
   1007 
   1008               action_set = soc_mem_field32_get(unit, view_id, l2x_entry,
   1009                                DESTINATION_ACTION_SETf);
   1010               dest_type3 = soc_format_field32_get(unit, DESTINATION_FORMATfmt,
   1011                             &action_set, DEST_TYPE3f);
   1012               mysta_prof_id = soc_format_field32_get(unit, DESTINATION_FORMATfmt,
   1013                             &action_set, MY_STATION_PROFILE_IDXf);
   1014               if (dest_type3 == DEST_TYPE3_MY_STATION) {
   1015                   _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, 0, mysta_prof_id);
   1016                   _bcm_l2_mysta_entry_to_station(unit, &entry_prof, MY_STATION_PROFILE_1m, &station);
   1017                   l2addr->station_flags = station.flags;
   1018               } else {
   1019                   l2addr->station_flags = 0;
   1020               }
   1021           }
   1022     }
   1023 
   1024     return BCM_E_NONE;
   1025 }
   1026 
   1027 /*
   1028  * Function:
   1029  *      _bcm_td3_flex_l2_replace_data_mask_setup
   1030  * Purpose:
   1031  *      Setup the replace data structure with the data and mask of field
   1032  *      being replaced/deleted
   1033  * Parameters:
   1034  *      unit        Unit number
   1035  *      rep         Replacement data structure
   1036  */
   1037 
   1038 int
   1039 _bcm_td3_flex_l2_replace_data_mask_setup(int unit, _bcm_l2_replace_t *rep)
   1040 {
   1041     bcm_mac_t mac_mask;
   1042     bcm_mac_t mac_data;
   1043     int field_len;
   1044     int i;
   1045     uint32 view_id;
   1046     int rv = BCM_E_NONE;
   1047     uint32 action_set = 0;
   1048 
   1049     uint32  flex_key_array[64];
   1050     uint32  flex_key_count;
   1051 
   1052     uint8 process_vlan = 0;
   1053     uint8 process_vfi = 0;
   1054     uint8 process_mac = 0;
   1055 
   1056     sal_memset(&rep->match_mask, 0, sizeof(l2x_entry_t));
   1057     sal_memset(&rep->match_data, 0, sizeof(l2x_entry_t));
   1058     sal_memset(&rep->new_mask, 0, sizeof(l2x_entry_t));
   1059     sal_memset(&rep->new_data, 0, sizeof(l2x_entry_t));
   1060 
   1061     view_id = rep->view_id;
   1062     /* Initialize control field list for this view id. */
   1063     rv = soc_flow_db_mem_view_entry_init(unit, view_id, (uint32*) &rep->match_data);
   1064     BCM_IF_ERROR_RETURN(rv);
   1065 
   1066     field_len = soc_mem_field_length(unit, view_id, BASE_VALIDf);
   1067     soc_mem_field32_set(unit, view_id, &rep->match_mask, BASE_VALIDf,
   1068                         (1 << field_len) - 1);
   1069 
   1070     field_len = soc_mem_field_length(unit, view_id, KEY_TYPEf);
   1071     soc_mem_field32_set(unit, view_id, &rep->match_mask, KEY_TYPEf,
   1072                         (1 << field_len) - 1);
   1073 
   1074     field_len = soc_mem_field_length(unit, view_id, DATA_TYPEf);
   1075     soc_mem_field32_set(unit, view_id, &rep->match_mask, DATA_TYPEf,
   1076                         (1 << field_len) - 1);
   1077 
   1078     /* Get KEY field list corresponding to the view id. */
   1079     rv = soc_flow_db_mem_view_field_list_get(unit,
   1080                             view_id,
   1081                             SOC_FLOW_DB_FIELD_TYPE_KEY,
   1082                             128,
   1083                             flex_key_array,
   1084                             &flex_key_count);
   1085     BCM_IF_ERROR_RETURN(rv);
   1086 
   1087     for (i=0; i<flex_key_count; i++) {
   1088         switch (flex_key_array[i]) {
   1089             case VFIf:
   1090                 process_vfi = 1;
   1091                 break;
   1092             case MAC_DAf:
   1093                 process_mac = 1;
   1094                 break;
   1095             case VLAN_IDf:
   1096                 process_vlan = 1;
   1097                 break;
   1098             default:
   1099                 break;
   1100         }
   1101     }
   1102 
   1103     if (!SOC_MEM_FIELD_VALID(unit, view_id, DESTINATION_ACTION_SETf)) {
   1104         return BCM_E_INTERNAL;
   1105     }
   1106     if (rep->flags & BCM_L2_REPLACE_MATCH_VLAN) {
   1107         if (rep->key_vfi != -1) {
   1108             if (!process_vfi) return BCM_E_PARAM;
   1109             field_len = soc_mem_field_length(unit, view_id, VFIf);
   1110             soc_mem_field32_set(unit, view_id, &rep->match_mask, VFIf,
   1111                                 (1 << field_len) - 1);
   1112             soc_mem_field32_set(unit, view_id, &rep->match_data, VFIf,
   1113                                 rep->key_vfi);
   1114         } else {
   1115             if (!process_vlan) return BCM_E_PARAM;
   1116             soc_mem_field32_set(unit, view_id, &rep->match_mask, VLAN_IDf, 0xfff);
   1117             soc_mem_field32_set(unit, view_id, &rep->match_data, VLAN_IDf,
   1118                                 rep->key_vlan);
   1119         }
   1120     }
   1121 
   1122     if (rep->flags & BCM_L2_REPLACE_MATCH_MAC) {
   1123         if (!process_mac) return BCM_E_PARAM;
   1124         sal_memset(&mac_mask, 0xff, sizeof(mac_mask));
   1125         soc_mem_mac_addr_set(unit, view_id, &rep->match_mask, MAC_DAf,
   1126                              mac_mask);
   1127         soc_mem_mac_addr_set(unit, view_id, &rep->match_data, MAC_DAf,
   1128                              rep->key_mac);
   1129     }
   1130 
   1131     if ((rep->flags & BCM_L2_REPLACE_MATCH_UC) && 
   1132         !(rep->flags & BCM_L2_REPLACE_MATCH_MC)) {
   1133 
   1134         if (!process_mac) return BCM_E_PARAM;
   1135         /* The 40th bit of Unicast must be 0 */
   1136         sal_memset(&mac_mask, 0x00, sizeof(mac_mask));
   1137         mac_mask[0] = 0x01;
   1138         sal_memset(&mac_data, 0x00, sizeof(mac_data));
   1139         soc_mem_mac_addr_set(unit, view_id, &rep->match_mask, MAC_DAf,
   1140                              mac_mask);
   1141         soc_mem_mac_addr_set(unit, view_id, &rep->match_data, MAC_DAf,
   1142                              mac_data);
   1143     } else if ((rep->flags & BCM_L2_REPLACE_MATCH_MC) &&
   1144         !(rep->flags & BCM_L2_REPLACE_MATCH_UC)) {
   1145         /* The 40th bit of Multicast must be 1 */
   1146         if (!process_mac) return BCM_E_PARAM;
   1147 
   1148         sal_memset(&mac_mask, 0x00, sizeof(mac_mask));
   1149         mac_mask[0] = 0x01;
   1150         sal_memset(&mac_data, 0x00, sizeof(mac_data));
   1151         mac_data[0] = 0x01;
   1152         soc_mem_mac_addr_set(unit, view_id, &rep->match_mask, MAC_DAf,
   1153                              mac_mask);
   1154         soc_mem_mac_addr_set(unit, view_id, &rep->match_data, MAC_DAf,
   1155                              mac_data);
   1156     }
   1157 
   1158     if (rep->flags & BCM_L2_REPLACE_MATCH_DEST) {
   1159         if (rep->match_dest.vp != -1) {
   1160             action_set = 0;
   1161             field_len = soc_mem_field_length(unit, view_id, DESTINATION_ACTION_SETf);
   1162             soc_mem_field32_set(unit, view_id, &rep->match_mask, DESTINATION_ACTION_SETf, 
   1163                                 (1 << field_len) - 1);
   1164 
   1165             soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1166                                    &action_set, DEST_TYPE0f, DEST_TYPE0_DVP);
   1167             soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1168                                    &action_set, DVPf, rep->match_dest.vp);
   1169             soc_mem_field32_set(unit, view_id, &rep->match_data, 
   1170                                 DESTINATION_ACTION_SETf, action_set);
   1171         } else {
   1172             action_set = 0;
   1173             soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1174                     &action_set, DGPPf,
   1175                     SOC_MEM_FIF_DGPP_MOD_ID_MASK | SOC_MEM_FIF_DGPP_PORT_MASK);
   1176             soc_mem_field32_set(unit, view_id, &rep->match_mask,
   1177                                 DESTINATION_ACTION_SETf, action_set);
   1178             action_set = 0;
   1179             if (rep->match_dest.trunk != -1) {
   1180                 soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1181                                    &action_set, DEST_TYPE2f, DEST_TYPE2_LAG);
   1182                 soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1183                                    &action_set, LAGf, rep->match_dest.trunk);
   1184                 soc_mem_field32_set(unit, view_id, &rep->match_data, 
   1185                             DESTINATION_ACTION_SETf, action_set);
   1186             } else {
   1187                 soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1188                        &action_set, DEST_TYPE0f, DEST_TYPE0_DGPP);
   1189                 soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1190                        &action_set, DGPPf, 
   1191                        rep->match_dest.module << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS |
   1192                      rep->match_dest.port);
   1193                 soc_mem_field32_set(unit, view_id, &rep->match_data, 
   1194                             DESTINATION_ACTION_SETf, action_set);
   1195                 /* Ignore multicast mac from bulk delete */
   1196                 mac_mask[0] = 0x01;
   1197                 mac_mask[1] = mac_mask[2] = mac_mask[3] = 
   1198                               mac_mask[4] = mac_mask[5] = 0x00;
   1199                 soc_mem_mac_addr_set(unit, view_id, &rep->match_mask, 
   1200                     MAC_DAf, mac_mask);
   1201             }
   1202         }
   1203     }
   1204     
   1205     /* BCM_L2_REPLACE_MATCH_STATIC means to replace static as well as
   1206     * non-static entries */
   1207     if (!(rep->flags & BCM_L2_REPLACE_MATCH_STATIC) &&
   1208          (SOC_MEM_FIELD_VALID(unit, view_id, STATIC_BITf))) {
   1209         if (rep->int_flags & _BCM_L2_REPLACE_INT_MATCH_ONLY_STATIC) {
   1210             soc_mem_field32_set(unit, view_id, &rep->match_mask, STATIC_BITf, 1);
   1211             soc_mem_field32_set(unit, view_id, &rep->match_data, STATIC_BITf, 1);
   1212         } else {
   1213             soc_mem_field32_set(unit, view_id, &rep->match_mask, STATIC_BITf, 1);
   1214             /* STATIC_BIT field in data is 0 */
   1215         }
   1216     }
   1217     /* STATIC_BIT field in mask is 0 */ 
   1218 
   1219     if (SOC_MEM_FIELD_VALID(unit, view_id, TABLE_MANAGEMENT_ACTION_SETf)) {
   1220         action_set = 0;
   1221         soc_format_field32_set(unit, TABLE_MANAGEMENT_ACTION_SETfmt,
   1222                                &action_set, PENDINGf, 1);
   1223         soc_mem_field32_set(unit, view_id, &rep->match_mask, 
   1224                             TABLE_MANAGEMENT_ACTION_SETf, action_set);
   1225         if (rep->flags & BCM_L2_REPLACE_PENDING) {
   1226             soc_mem_field32_set(unit, view_id, &rep->match_data, 
   1227                             TABLE_MANAGEMENT_ACTION_SETf, action_set);
   1228         }
   1229     }
   1230 
   1231     if (rep->int_flags & _BCM_L2_REPLACE_INT_MATCH_DISCARD_SRC) {
   1232         if (!SOC_MEM_FIELD_VALID(unit, view_id, FWD_ATTRIBUTES_ACTION_SETf)) {
   1233             return BCM_E_PARAM;
   1234         }
   1235         action_set = 0;
   1236         soc_format_field32_set(unit, FWD_ATTRIBUTES_ACTION_SETfmt,
   1237                                    &action_set, SRC_DISCARDf, 1);
   1238         soc_mem_field32_set(unit, view_id, &rep->match_mask, 
   1239                             FWD_ATTRIBUTES_ACTION_SETf, action_set);
   1240         if (rep->key_l2_flags & BCM_L2_DISCARD_SRC) {
   1241             soc_mem_field32_set(unit, view_id, &rep->match_data, 
   1242                                 FWD_ATTRIBUTES_ACTION_SETf, action_set);
   1243         }
   1244     }
   1245 
   1246     if (rep->int_flags & _BCM_L2_REPLACE_INT_MATCH_SRC_HIT) {
   1247         if (!SOC_MEM_FIELD_VALID(unit, view_id, HITSAf)) {
   1248             return BCM_E_PARAM;
   1249         }
   1250         soc_mem_field32_set(unit, view_id, &rep->match_mask, HITSAf, 1);
   1251         if (rep->key_l2_flags & BCM_L2_SRC_HIT) {
   1252             soc_mem_field32_set(unit, view_id, &rep->match_data, HITSAf, 1);
   1253         }
   1254     }
   1255     if (rep->int_flags & _BCM_L2_REPLACE_INT_MATCH_DES_HIT) {
   1256         if (!SOC_MEM_FIELD_VALID(unit, view_id, HITDAf)) {
   1257             return BCM_E_PARAM;
   1258         }
   1259         soc_mem_field32_set(unit, view_id, &rep->match_mask, HITDAf, 1);
   1260         if (rep->key_l2_flags & BCM_L2_DES_HIT) {
   1261             soc_mem_field32_set(unit, view_id, &rep->match_data, HITDAf, 1);
   1262         }
   1263     }
   1264     if (SOC_MEM_FIELD_VALID(unit, view_id, LOCAL_SAf)) {
   1265         if (rep->int_flags & _BCM_L2_REPLACE_INT_MATCH_NATIVE) {
   1266             soc_mem_field32_set(unit, view_id, &rep->match_mask, LOCAL_SAf, 1);
   1267             if (rep->key_l2_flags & BCM_L2_NATIVE) {
   1268                 soc_mem_field32_set(unit, view_id, &rep->match_data, LOCAL_SAf,
   1269                                     1);
   1270             }
   1271         }
   1272     }
   1273     if (_CLEAR_ALL_ENTRIES_SRC_OR_DES_HIT_BIT(rep->flags)) {
   1274         if (rep->flags & BCM_L2_REPLACE_DES_HIT_CLEAR) {
   1275             if (!SOC_MEM_FIELD_VALID(unit, view_id, HITDAf)) {
   1276                 return BCM_E_PARAM;
   1277             }
   1278             soc_mem_field32_set(unit, view_id, &rep->match_mask, HITDAf, 1);
   1279             soc_mem_field32_set(unit, view_id, &rep->match_data, HITDAf, 1);
   1280         }
   1281         if (rep->flags & BCM_L2_REPLACE_SRC_HIT_CLEAR) {
   1282             if (!SOC_MEM_FIELD_VALID(unit, view_id, HITSAf)) {
   1283                 return BCM_E_PARAM;
   1284             }
   1285             soc_mem_field32_set(unit, view_id, &rep->match_mask, HITSAf, 1);
   1286             soc_mem_field32_set(unit, view_id, &rep->match_data, HITSAf, 1);
   1287         }
   1288     }
   1289     if (!(rep->flags & (BCM_L2_REPLACE_DELETE | BCM_L2_REPLACE_AGE))) {
   1290         if (!_CLEAR_ALL_ENTRIES_SRC_OR_DES_HIT_BIT(rep->flags)) {
   1291             if (rep->new_dest.vp != -1) {
   1292                 action_set = 0;
   1293                 field_len = soc_mem_field_length(unit, view_id, DESTINATION_ACTION_SETf);
   1294                 soc_mem_field32_set(unit, view_id, &rep->new_mask, DESTINATION_ACTION_SETf, 
   1295                                     (1 << field_len) - 1);
   1296                 soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1297                                        &action_set, DEST_TYPE0f, DEST_TYPE0_DVP);
   1298                 soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1299                                        &action_set, DVPf, rep->new_dest.vp);
   1300                 soc_mem_field32_set(unit, view_id, &rep->new_data, 
   1301                                     DESTINATION_ACTION_SETf, action_set);
   1302             } else {
   1303                 action_set = 0;
   1304                 field_len = soc_mem_field_length(unit, view_id, DESTINATION_ACTION_SETf);
   1305                 soc_mem_field32_set(unit, view_id, &rep->new_mask, DESTINATION_ACTION_SETf,
   1306                                             (1 << field_len) - 1);
   1307                 if (rep->new_dest.trunk != -1) {
   1308                     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1309                                        &action_set, DEST_TYPE2f, DEST_TYPE2_LAG);
   1310                     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1311                                        &action_set, LAGf, rep->new_dest.trunk);
   1312                     soc_mem_field32_set(unit, view_id, &rep->new_data, 
   1313                                 DESTINATION_ACTION_SETf, action_set);
   1314                 } else {
   1315                     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1316                                 &action_set, DEST_TYPE0f, DEST_TYPE0_DGPP);
   1317                     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1318                                &action_set, DGPPf, 
   1319                                 rep->new_dest.module << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS |
   1320                                 rep->new_dest.port);
   1321                     soc_mem_field32_set(unit, view_id, &rep->new_data, 
   1322                             DESTINATION_ACTION_SETf, action_set);
   1323                 }
   1324             }
   1325         }
   1326         if (rep->flags & BCM_L2_REPLACE_DES_HIT_CLEAR) {
   1327             if (!SOC_MEM_FIELD_VALID(unit, view_id, HITDAf)) {
   1328                 return BCM_E_PARAM;
   1329             }
   1330             soc_mem_field32_set(unit, view_id, &rep->new_mask, HITDAf, 1);
   1331         }
   1332         if (rep->flags & BCM_L2_REPLACE_SRC_HIT_CLEAR) {
   1333             if (!SOC_MEM_FIELD_VALID(unit, view_id, HITSAf)) {
   1334                 return BCM_E_PARAM;
   1335             }
   1336             soc_mem_field32_set(unit, view_id, &rep->new_mask, HITSAf, 1);
   1337         }
   1338     }
   1339 
   1340     return BCM_E_NONE;
   1341 }
   1342 /*
   1343  *     _bcm_td3_flex_l2_bulk_replace_modport
   1344  * Description:
   1345  *     Match Flex L2 entries with these fields: DEST_TYPE + MODULE_ID + PORT_NUM 
   1346  *     Replace with one of following:
   1347  *         DEST_TYPE = 0, new MODULE_ID, new PORT_NUM 
   1348  *         DEST_TYPE = 1, new TGID
   1349  * Parameters:
   1350  *     unit         device number
   1351  *     rep_st       structure with match/replace information
   1352  * Return:
   1353  *     BCM_E_XXX
   1354  */
   1355 int 
   1356 _bcm_td3_flex_l2_bulk_replace_modport(int unit, _bcm_l2_replace_t *rep_st)
   1357 {
   1358     l2_bulk_entry_t match_mask;
   1359     l2_bulk_entry_t match_data;
   1360     l2_bulk_entry_t repl_mask;
   1361     l2_bulk_entry_t repl_data;
   1362     int field_len;
   1363     int rv;
   1364     uint32 view_id;
   1365     uint32 action_set=0;
   1366 
   1367     sal_memset(&match_mask, 0, sizeof(match_mask));
   1368     sal_memset(&match_data, 0, sizeof(match_data));
   1369     sal_memset(&repl_mask, 0, sizeof(repl_mask));
   1370     sal_memset(&repl_data, 0, sizeof(repl_data));
   1371 
   1372     view_id = rep_st->view_id;
   1373     /* Initialize control field list for this view id. */
   1374     rv = soc_flow_db_mem_view_entry_init(unit, view_id, (uint32*) &match_data);
   1375     BCM_IF_ERROR_RETURN(rv);
   1376 
   1377     soc_mem_field32_set(unit, view_id, &match_mask, BASE_VALIDf, 1);
   1378     soc_mem_field32_set(unit, view_id, &match_mask, VALIDf, 1);
   1379 
   1380     field_len = soc_mem_field_length(unit, view_id, KEY_TYPEf);
   1381     soc_mem_field32_set(unit, view_id, &match_mask, KEY_TYPEf,
   1382                         (1 << field_len) - 1);
   1383 
   1384     field_len = soc_mem_field_length(unit, view_id, DATA_TYPEf);
   1385     soc_mem_field32_set(unit, view_id, &match_mask, DATA_TYPEf,
   1386                         (1 << field_len) - 1);
   1387 
   1388     action_set = 0;
   1389     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1390             &action_set, DGPPf,
   1391             SOC_MEM_FIF_DGPP_MOD_ID_MASK | SOC_MEM_FIF_DGPP_PORT_MASK);
   1392     soc_mem_field32_set(unit, view_id, &match_mask,
   1393                         DESTINATION_ACTION_SETf, action_set);
   1394     action_set = 0;
   1395     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1396         &action_set, DEST_TYPE0f, DEST_TYPE0_DGPP);
   1397     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1398         &action_set, DGPPf, 
   1399         rep_st->match_dest.module << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | 
   1400         rep_st->match_dest.port);
   1401     soc_mem_field32_set(unit, view_id, &match_data,
   1402                         DESTINATION_ACTION_SETf, action_set);
   1403 
   1404     if (!(rep_st->flags & BCM_L2_REPLACE_MATCH_STATIC)) {
   1405         soc_mem_field32_set(unit, view_id, &match_mask,
   1406                             STATIC_BITf, 1);
   1407         /* STATIC_BIT field in data is 0 */
   1408     }
   1409 
   1410     if (rep_st->flags & BCM_L2_REPLACE_PENDING) {
   1411         if (!soc_mem_field_valid(unit, view_id, TABLE_MANAGEMENT_ACTION_SETf)) {
   1412             return BCM_E_PARAM;
   1413         }
   1414         action_set = 0;
   1415         soc_format_field32_set(unit, TABLE_MANAGEMENT_ACTION_SETfmt,
   1416                                &action_set, PENDINGf, 1);
   1417         soc_mem_field32_set(unit, view_id, &match_mask, 
   1418                             TABLE_MANAGEMENT_ACTION_SETf, action_set);
   1419         soc_mem_field32_set(unit, view_id, &match_data, 
   1420                             TABLE_MANAGEMENT_ACTION_SETf, action_set);
   1421     }
   1422 
   1423     soc_mem_field32_set(unit, view_id, &match_mask, EVEN_PARITYf,
   1424                         1);
   1425 
   1426     BCM_IF_ERROR_RETURN
   1427         (WRITE_L2_BULKm(unit, MEM_BLOCK_ALL, _BCM_L2_BULK_MATCH_MASK_INX, 
   1428                         &match_mask));
   1429 
   1430     field_len = soc_mem_field_length(unit, L2_BULKm, DEST_TYPEf);
   1431     soc_mem_field32_set(unit, L2_BULKm, &repl_mask, DEST_TYPEf,
   1432                         (1 << field_len) - 1);
   1433 
   1434     action_set = 0;
   1435     soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1436             &action_set, DGPPf,
   1437             SOC_MEM_FIF_DGPP_MOD_ID_MASK | SOC_MEM_FIF_DGPP_PORT_MASK);
   1438     soc_mem_field32_set(unit, view_id, &repl_mask,
   1439                         DESTINATION_ACTION_SETf, action_set);
   1440     action_set = 0;
   1441     if (rep_st->new_dest.trunk != -1) {
   1442         soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1443             &action_set, DEST_TYPE2f, DEST_TYPE2_LAG);
   1444         soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1445             &action_set, LAGf, 
   1446             rep_st->new_dest.trunk);
   1447     } else {
   1448         soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1449             &action_set, DEST_TYPE0f, DEST_TYPE0_DGPP);
   1450         soc_format_field32_set(unit, DESTINATION_FORMATfmt,
   1451             &action_set, DGPPf, 
   1452             rep_st->new_dest.module << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | 
   1453             rep_st->new_dest.port);
   1454     }
   1455     soc_mem_field32_set(unit, view_id, &repl_data,
   1456                         DESTINATION_ACTION_SETf, action_set);
   1457 
   1458     soc_mem_field32_set(unit, L2_BULKm, &repl_mask, EVEN_PARITYf,
   1459                         1);
   1460     BCM_IF_ERROR_RETURN
   1461         (WRITE_L2_BULKm(unit, MEM_BLOCK_ALL, _BCM_L2_BULK_REPLACE_MASK_INX, 
   1462                         &repl_mask));
   1463 
   1464     BCM_IF_ERROR_RETURN
   1465         (soc_reg_field32_modify(unit, L2_BULK_CONTROLr, REG_PORT_ANY, ACTIONf,
   1466                                 2));
   1467     BCM_IF_ERROR_RETURN
   1468         (soc_reg_field32_modify(unit, L2_BULK_CONTROLr, REG_PORT_ANY,
   1469                             NUM_ENTRIESf, soc_mem_index_count(unit, view_id)));
   1470 
   1471     /* Replace all entries having EVEN_PARITY == 0 */
   1472     /* EVEN_PARITY field in data is 0 */
   1473     BCM_IF_ERROR_RETURN
   1474         (WRITE_L2_BULKm(unit, MEM_BLOCK_ALL, _BCM_L2_BULK_MATCH_DATA_INX, 
   1475                         &match_data));
   1476 
   1477     soc_mem_field32_set(unit, L2_BULKm, &repl_data, EVEN_PARITYf,
   1478                         1);
   1479     BCM_IF_ERROR_RETURN
   1480         (WRITE_L2_BULKm(unit, MEM_BLOCK_ALL, _BCM_L2_BULK_REPLACE_DATA_INX, 
   1481                         &repl_data));
   1482 
   1483     BCM_IF_ERROR_RETURN(soc_l2x_port_age(unit, L2_BULK_CONTROLr, INVALIDr));
   1484 
   1485     /* Replace all entries having EVEN_PARITY == 1 */
   1486     soc_mem_field32_set(unit, L2_BULKm, &match_data, EVEN_PARITYf,
   1487                         1);
   1488     BCM_IF_ERROR_RETURN
   1489         (WRITE_L2_BULKm(unit, MEM_BLOCK_ALL, _BCM_L2_BULK_MATCH_DATA_INX, 
   1490                         &match_data));
   1491 
   1492     soc_mem_field32_set(unit, L2_BULKm, &repl_data, EVEN_PARITYf,
   1493                         0);
   1494     BCM_IF_ERROR_RETURN
   1495         (WRITE_L2_BULKm(unit, MEM_BLOCK_ALL, _BCM_L2_BULK_REPLACE_DATA_INX,
   1496                         &repl_data));
   1497 
   1498     BCM_IF_ERROR_RETURN(soc_l2x_port_age(unit, L2_BULK_CONTROLr, INVALIDr));
   1499 
   1500     return BCM_E_NONE;
   1501 }
   1502 
   1503 #if defined(INCLUDE_L3)
   1504 int
   1505 _bcm_td3_l2_change_fields_egress_key_set(
   1506     int unit,
   1507     soc_mem_t mem,
   1508     bcm_l2_change_fields_t *l2_info,
   1509     uint32 *entry)
   1510 {
   1511     int rv = BCM_E_NONE;
   1512 
   1513     if (soc_mem_field_valid(unit, mem, BASE_VALIDf)) {
   1514         soc_mem_field32_set(unit, mem, entry, BASE_VALIDf, 1);
   1515     } else {
   1516         soc_mem_field32_set(unit, mem, entry, BASE_VALID_0f, 3);
   1517         soc_mem_field32_set(unit, mem, entry, BASE_VALID_1f, 7);
   1518     }
   1519 
   1520     soc_mem_field32_set(unit, mem, entry, KEY_TYPEf,
   1521         _BCM_TD3_EXLATE_CHANGE_L2_FIELDS_KEY_TYPE);
   1522     soc_mem_field32_set(unit, mem, entry, DATA_TYPEf,
   1523         _BCM_TD3_EXLATE_CHANGE_L2_FIELDS_DATA_TYPE);
   1524 
   1525     soc_mem_field32_set(unit, mem, entry,
   1526              CHANGE_L2_FIELDS__OPAQUE_3f, l2_info->change_l2_fields_class_id);
   1527 
   1528     if (l2_info->flags & BCM_L2_CHANGE_FIELDS_DVP) {
   1529         uint32 dvp;
   1530         /* validate DVP */
   1531         if (BCM_GPORT_IS_VXLAN_PORT(l2_info->dvp)) {
   1532             dvp = BCM_GPORT_VXLAN_PORT_ID_GET(l2_info->dvp);
   1533         }
   1534         else if (BCM_GPORT_IS_FLOW_PORT(l2_info->dvp)) {
   1535             dvp = BCM_GPORT_FLOW_PORT_ID_GET(l2_info->dvp);
   1536         }
   1537         else if (BCM_GPORT_IS_L2GRE_PORT(l2_info->dvp)) {
   1538             dvp = BCM_GPORT_L2GRE_PORT_ID_GET(l2_info->dvp);
   1539         }
   1540         else if (BCM_GPORT_IS_MIM_PORT(l2_info->dvp)) {
   1541             dvp = BCM_GPORT_MIM_PORT_ID_GET(l2_info->dvp);
   1542         }
   1543         else if (BCM_GPORT_IS_MPLS_PORT(l2_info->dvp)) {
   1544             dvp = BCM_GPORT_MPLS_PORT_ID_GET(l2_info->dvp);
   1545         }
   1546         else {
   1547             /* unregonized gport */
   1548             return BCM_E_PARAM;
   1549         }
   1550         soc_mem_field32_set(unit, mem, entry,
   1551              CHANGE_L2_FIELDS__DVPf, dvp);
   1552     }
   1553 
   1554     return rv;
   1555 }
   1556 
   1557 STATIC int
   1558 _bcm_td3_l2_change_fields_tag_set(
   1559         int unit,
   1560         bcm_l2_change_fields_t *info,
   1561         soc_mem_t mem,
   1562         uint32 *entry,
   1563         int *tpid_index)
   1564 {
   1565     int action_present = 0;
   1566     int action_not_present = 0;
   1567     int sd_tag_remark_cfi_set = 0;
   1568     int old_tpid_inx = 0;
   1569     uint32 profile_index = 0;
   1570     soc_field_t vlan_f = CHANGE_L2_FIELDS__VIDf;
   1571     soc_field_t pri_f = CHANGE_L2_FIELDS__PCPf;
   1572     soc_field_t cfi_f = CHANGE_L2_FIELDS__DEf;
   1573     soc_field_t pri_cfi_sel_f = CHANGE_L2_FIELDS__PCP_DE_SELf;
   1574     soc_field_t tag_act_f = CHANGE_L2_FIELDS__TAG_ACTION_PROFILE_PTRf;
   1575     soc_field_t tpid_f = CHANGE_L2_FIELDS__TPID_INDEXf;
   1576 
   1577     if (info->vlan >= BCM_VLAN_INVALID) {
   1578         return  BCM_E_PARAM;
   1579     }
   1580     soc_mem_field32_set(unit, mem, entry, vlan_f, info->vlan);
   1581 
   1582     if (info->pri > BCM_PRIO_MAX) {
   1583         return  BCM_E_PARAM;
   1584     }
   1585     soc_mem_field32_set(unit, mem, entry, pri_f, info->pri);
   1586 
   1587     if (info->cfi > 1) {
   1588        return  BCM_E_PARAM;
   1589     }
   1590     soc_mem_field32_set(unit, mem, entry, cfi_f, info->cfi);
   1591 
   1592     if (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_ADD) {
   1593         sd_tag_remark_cfi_set = TRUE;
   1594         action_not_present = 0x1;  /* ADD */
   1595     }
   1596 
   1597     if (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_TPID_REPLACE) {
   1598         action_present = 0x1; /* REPLACE_VID_TPID */
   1599 
   1600     } else if (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_REPLACE) {
   1601         action_present = 0x2;  /* REPLACE_VID_ONLY */
   1602 
   1603     } else if (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_DELETE) {
   1604         action_present = 0x3;  /* DELETE */
   1605 
   1606     } else if (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_PRI_TPID_REPLACE) {
   1607         sd_tag_remark_cfi_set = TRUE;
   1608         action_present = 0x4;  /* REPLACE_VID_PRI_TPID */
   1609 
   1610     } else if (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_PRI_REPLACE){
   1611         sd_tag_remark_cfi_set = TRUE;
   1612         action_present = 0x5;  /* REPLACE_VID_PRI */
   1613 
   1614     } else if (info->flags & BCM_L2_CHANGE_FIELDS_PRI_REPLACE ) {
   1615         sd_tag_remark_cfi_set = TRUE;
   1616         action_present = 0x6;  /*  REPLACE_PRI_ONLY */
   1617 
   1618     } else if (info->flags & BCM_L2_CHANGE_FIELDS_TPID_REPLACE) {
   1619         action_present = 0x7;  /* REPLACE_TPID_ONLY */
   1620     }
   1621 
   1622     soc_mem_field32_set(unit, mem, entry, pri_cfi_sel_f, sd_tag_remark_cfi_set);
   1623     profile_index = soc_mem_field32_get(unit, mem, entry, tag_act_f);
   1624 
   1625     _bcm_td3_sd_tag_action_profile_get(unit, action_present,
   1626             action_not_present, &profile_index);
   1627 
   1628     soc_mem_field32_set(unit, mem, entry, tag_act_f, profile_index);
   1629 
   1630     if ((info->flags & BCM_L2_CHANGE_FIELDS_VLAN_ADD) ||
   1631         (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_TPID_REPLACE) ||
   1632         (info->flags & BCM_L2_CHANGE_FIELDS_TPID_REPLACE) ||
   1633         (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_PRI_TPID_REPLACE)) {
   1634         if (info->flags & BCM_L2_CHANGE_FIELDS_REPLACE) {
   1635             old_tpid_inx = soc_mem_field32_get(unit, mem, entry, tpid_f);
   1636             BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_entry_delete(unit,
   1637                                 old_tpid_inx));
   1638         }
   1639 
   1640         /* TPID value is used */
   1641         BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_entry_add(unit, info->tpid,
   1642                              tpid_index));
   1643         soc_mem_field32_set(unit, mem, entry, tpid_f, *tpid_index);
   1644     }
   1645     return  BCM_E_NONE;
   1646 }
   1647 
   1648 STATIC void
   1649 _bcm_td3_l2_change_fields_tag_get(
   1650         int unit,
   1651         bcm_l2_change_fields_t *info,
   1652         soc_mem_t mem,
   1653         uint32 *entry,
   1654         int  *tpid_idx)
   1655 {
   1656     int action_present = 0;
   1657     int action_not_present = 0;
   1658     int tpid_index = 0;
   1659     uint32 profile_index = 0;
   1660     int rv = BCM_E_NONE;
   1661     soc_field_t vlan_f = CHANGE_L2_FIELDS__VIDf;
   1662     soc_field_t pri_f = CHANGE_L2_FIELDS__PCPf;
   1663     soc_field_t cfi_f = CHANGE_L2_FIELDS__DEf;
   1664     soc_field_t tag_act_f = CHANGE_L2_FIELDS__TAG_ACTION_PROFILE_PTRf;
   1665     soc_field_t tpid_f = CHANGE_L2_FIELDS__TPID_INDEXf;
   1666 
   1667     info->vlan = soc_mem_field32_get(unit, mem, entry, vlan_f);
   1668     info->pri = soc_mem_field32_get(unit, mem, entry, pri_f);
   1669     info->cfi = soc_mem_field32_get(unit, mem, entry, cfi_f);
   1670 
   1671     profile_index = soc_mem_field32_get(unit, mem, entry, tag_act_f);
   1672 
   1673     (void)_bcm_td3_sd_tag_action_get(unit, profile_index, &action_present,
   1674                     &action_not_present);
   1675 
   1676     if (action_not_present) {
   1677         info->flags |= BCM_L2_CHANGE_FIELDS_VLAN_ADD;
   1678     }
   1679 
   1680     if (action_present == 0x1) {
   1681         info->flags |= BCM_L2_CHANGE_FIELDS_VLAN_TPID_REPLACE;
   1682 
   1683     } else if (action_present == 0x2) {
   1684         info->flags |= BCM_L2_CHANGE_FIELDS_VLAN_REPLACE;
   1685 
   1686     } else if (action_present == 0x3) {
   1687         info->flags |= BCM_L2_CHANGE_FIELDS_VLAN_DELETE;
   1688 
   1689     } else if (action_present == 0x4) {
   1690         info->flags |= BCM_L2_CHANGE_FIELDS_VLAN_PRI_TPID_REPLACE;
   1691 
   1692     } else if (action_present == 0x5) {
   1693         info->flags |= BCM_L2_CHANGE_FIELDS_VLAN_PRI_REPLACE;
   1694 
   1695     } else if (action_present == 0x6) {
   1696         info->flags |= BCM_L2_CHANGE_FIELDS_PRI_REPLACE;
   1697 
   1698     } else if (action_present == 0x7) {
   1699         info->flags |= BCM_L2_CHANGE_FIELDS_TPID_REPLACE;
   1700     }
   1701 
   1702     if ((info->flags & BCM_L2_CHANGE_FIELDS_VLAN_ADD) ||
   1703         (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_TPID_REPLACE) ||
   1704         (info->flags & BCM_L2_CHANGE_FIELDS_TPID_REPLACE) ||
   1705         (info->flags & BCM_L2_CHANGE_FIELDS_VLAN_PRI_TPID_REPLACE)) {
   1706         tpid_index = soc_mem_field32_get(unit, mem, entry, tpid_f);
   1707 
   1708         rv = _bcm_fb2_outer_tpid_entry_get(unit, &info->tpid, tpid_index);
   1709         if (BCM_FAILURE(rv)) {
   1710             info->tpid = tpid_index;
   1711         }
   1712         if (tpid_idx != NULL) {
   1713             *tpid_idx = tpid_index;
   1714         }
   1715     }
   1716 }
   1717 
   1718 STATIC int
   1719 _bcm_td3_l2_change_fields_egress_entry_set(
   1720     int unit,
   1721     soc_mem_t mem,
   1722     bcm_l2_change_fields_t *l2_info,
   1723     uint32 *entry)
   1724 {
   1725     int rv = BCM_E_NONE;
   1726     int index = -1;
   1727     uint32 return_entry[SOC_MAX_MEM_WORDS];
   1728     int new_entry_add = FALSE;
   1729     uint32   mac_da_field[2];
   1730     int tpid_index = -1;
   1731 
   1732     rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index, entry,
   1733                         return_entry, 0);
   1734 
   1735     if (BCM_E_NONE == rv) {
   1736         /* found memory entry */
   1737         if (l2_info->flags & BCM_L2_CHANGE_FIELDS_REPLACE) {
   1738             sal_memcpy(entry,return_entry,SOC_MAX_MEM_WORDS * 4);
   1739         } else {
   1740             return BCM_E_EXISTS;
   1741         }
   1742     } else if (BCM_E_NOT_FOUND == rv) {
   1743         if (l2_info->flags & BCM_L2_CHANGE_FIELDS_REPLACE) {
   1744             return BCM_E_NOT_FOUND;
   1745         } else {
   1746             new_entry_add = TRUE;
   1747         }
   1748     } else {
   1749         return rv;
   1750     }
   1751 
   1752     soc_mem_mac_addr_set(unit, mem, entry,
   1753         CHANGE_L2_FIELDS__MAC_SAf, l2_info->macsa);
   1754 
   1755     SAL_MAC_ADDR_TO_UINT32(l2_info->macda, mac_da_field);
   1756 
   1757     soc_mem_field32_set(unit, mem, entry,
   1758        CHANGE_L2_FIELDS__MAC_DA_27_0f, EXTRACT_MAC_DA_27_0(mac_da_field));
   1759 
   1760     soc_mem_field32_set(unit, mem, entry,
   1761         CHANGE_L2_FIELDS__MAC_DA_47_28f, EXTRACT_MAC_DA_47_28(mac_da_field));
   1762 
   1763     BCM_IF_ERROR_RETURN(
   1764         _bcm_td3_l2_change_fields_tag_set(
   1765             unit,
   1766             l2_info,
   1767             mem,
   1768             entry,
   1769             &tpid_index));
   1770 
   1771     if (new_entry_add) {
   1772         rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, entry);
   1773     } else { /* replace action */
   1774         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry);
   1775     }
   1776 
   1777     if (SOC_FAILURE(rv)) {
   1778         goto cleanup;
   1779     }
   1780     return rv;
   1781 
   1782 cleanup:
   1783     if (tpid_index != -1) {
   1784         (void) _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index);
   1785     }
   1786     return rv;
   1787 }
   1788 
   1789 int
   1790 _bcm_td3_l2_change_fields_add(
   1791     int unit,
   1792     bcm_l2_change_fields_t *l2_info)
   1793 {
   1794     soc_mem_t mem = EGR_VLAN_XLATE_2_DOUBLEm;
   1795     uint32 entry[SOC_MAX_MEM_WORDS];
   1796     int rv;
   1797 
   1798     sal_memset(entry, 0, sizeof(entry));
   1799 
   1800     BCM_IF_ERROR_RETURN(
   1801         _bcm_td3_l2_change_fields_egress_key_set(unit,
   1802              mem, l2_info, entry));
   1803 
   1804     soc_mem_lock(unit,mem);
   1805 
   1806     /* set the match object and attributes and write to memory */
   1807     rv = _bcm_td3_l2_change_fields_egress_entry_set(unit, mem,
   1808                         l2_info, entry);
   1809 
   1810     soc_mem_unlock(unit,mem);
   1811 
   1812     return rv;
   1813 }
   1814 
   1815 STATIC void
   1816 _bcm_td3_l2_change_fields_egress_data_get(
   1817     int unit,
   1818     soc_mem_t mem,
   1819     uint32* entry,
   1820     bcm_l2_change_fields_t *l2_info)
   1821 {
   1822     uint32   mac_da_field[2];
   1823 
   1824     soc_mem_mac_addr_get(unit, mem, entry, CHANGE_L2_FIELDS__MAC_SAf, l2_info->macsa);
   1825 
   1826     mac_da_field[0] = soc_mem_field32_get(unit, mem, entry,
   1827          CHANGE_L2_FIELDS__MAC_DA_27_0f);
   1828 
   1829     mac_da_field[1] = soc_mem_field32_get(unit, mem, entry,
   1830          CHANGE_L2_FIELDS__MAC_DA_47_28f);
   1831 
   1832     mac_da_field[0] = COMBINE_MAC_DA_32_0(mac_da_field);
   1833     mac_da_field[1] = COMBINE_MAC_DA_47_32(mac_da_field);
   1834 
   1835     SAL_MAC_ADDR_FROM_UINT32(l2_info->macda, mac_da_field);
   1836 
   1837     _bcm_td3_l2_change_fields_tag_get(unit,
   1838         l2_info, mem, entry, NULL);
   1839 }
   1840 
   1841 int
   1842 _bcm_td3_l2_change_fields_egress_entry_get(
   1843     int unit,
   1844     soc_mem_t mem,
   1845     uint32* entry,
   1846     bcm_l2_change_fields_t *l2_info)
   1847 {
   1848     int index = -1;
   1849     uint32 return_entry[SOC_MAX_MEM_WORDS];
   1850 
   1851     SOC_IF_ERROR_RETURN(soc_mem_search(unit, mem, MEM_BLOCK_ANY, &index,
   1852               entry, return_entry, 0));
   1853 
   1854     _bcm_td3_l2_change_fields_egress_data_get(unit,
   1855          mem, return_entry, l2_info);
   1856 
   1857     return BCM_E_NONE;
   1858 }
   1859 
   1860 STATIC int
   1861 _bcm_td3_change_l2_fields_entry_parse(
   1862     int unit,
   1863     soc_mem_t mem,
   1864     uint32 *entry,
   1865     bcm_l2_change_fields_t *l2_info)
   1866 {
   1867     uint32 key_type;
   1868     uint32 dvp;
   1869 
   1870     key_type = soc_mem_field32_get(unit, mem, entry, KEY_TYPEf);
   1871 
   1872     if (key_type != 0x11) {
   1873         return BCM_E_NOT_FOUND;
   1874     }
   1875 
   1876     l2_info->change_l2_fields_class_id = soc_mem_field32_get(unit,
   1877         mem, entry, CHANGE_L2_FIELDS__OPAQUE_3f);
   1878 
   1879     dvp = soc_mem_field32_get(unit, mem, entry, CHANGE_L2_FIELDS__DVPf);
   1880 
   1881     if (_bcm_vp_used_get(unit, dvp, _bcmVpTypeVxlan)) {
   1882         BCM_GPORT_VXLAN_PORT_ID_SET(l2_info->dvp, dvp);
   1883         l2_info->flags |= BCM_L2_CHANGE_FIELDS_DVP;
   1884     } else if (_bcm_vp_used_get(unit, dvp, _bcmVpTypeFlow)) {
   1885         BCM_GPORT_FLOW_PORT_ID_SET(l2_info->dvp, dvp);
   1886         l2_info->flags |= BCM_L2_CHANGE_FIELDS_DVP;
   1887     } else if (_bcm_vp_used_get(unit, dvp, _bcmVpTypeL2Gre)) {
   1888         BCM_GPORT_L2GRE_PORT_ID_SET(l2_info->dvp, dvp);
   1889         l2_info->flags |= BCM_L2_CHANGE_FIELDS_DVP;
   1890     } else if (_bcm_vp_used_get(unit, dvp, _bcmVpTypeMim)) {
   1891         BCM_GPORT_MIM_PORT_ID_SET(l2_info->dvp, dvp);
   1892         l2_info->flags |= BCM_L2_CHANGE_FIELDS_DVP;
   1893     } else if (_bcm_vp_used_get(unit, dvp, _bcmVpTypeMpls)) {
   1894         BCM_GPORT_MPLS_PORT_ID_SET(l2_info->dvp, dvp);
   1895         l2_info->flags |= BCM_L2_CHANGE_FIELDS_DVP;
   1896     }
   1897 
   1898     _bcm_td3_l2_change_fields_egress_data_get(unit,
   1899         mem, entry, l2_info);
   1900 
   1901     return BCM_E_NONE;
   1902 }
   1903 
   1904 int _bcm_td3_change_l2_fields_entry_traverse(
   1905     int unit,
   1906     soc_mem_t mem,
   1907     bcm_l2_change_fields_traverse_cb cb,
   1908     void *user_data)
   1909 {
   1910 
   1911     /* Indexes to iterate over memories, chunks and entries */
   1912     int             chnk_idx, ent_idx, chnk_idx_max, mem_idx_max;
   1913     int             buf_size, chunksize, chnk_end;
   1914     /* Buffer to store chunk of table we currently work on */
   1915     uint32          *ls_tbl_chnk;
   1916     uint32          *entry;
   1917     int             valid, rv = BCM_E_NONE;
   1918     bcm_l2_change_fields_t l2_info;
   1919 
   1920     if (INVALIDm == mem) {
   1921         return BCM_E_MEMORY;
   1922     }
   1923     if (!soc_mem_index_count(unit, mem)) {
   1924         return BCM_E_NONE;
   1925     }
   1926 
   1927     chunksize = 256;
   1928 
   1929     buf_size = 4 * SOC_MAX_MEM_FIELD_WORDS * chunksize;
   1930     ls_tbl_chnk = soc_cm_salloc(unit, buf_size, "change l2 fields traverse");
   1931     if (NULL == ls_tbl_chnk) {
   1932         return BCM_E_MEMORY;
   1933     }
   1934 
   1935     mem_idx_max = soc_mem_index_max(unit, mem);
   1936     for (chnk_idx = soc_mem_index_min(unit, mem);
   1937          chnk_idx <= mem_idx_max;
   1938          chnk_idx += chunksize) {
   1939         sal_memset((void *)ls_tbl_chnk, 0, buf_size);
   1940 
   1941         chnk_idx_max =
   1942             ((chnk_idx + chunksize) <= mem_idx_max) ?
   1943             chnk_idx + chunksize - 1: mem_idx_max;
   1944 
   1945         rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY,
   1946                                 chnk_idx, chnk_idx_max, ls_tbl_chnk);
   1947         if (SOC_FAILURE(rv)) {
   1948             break;
   1949         }
   1950         chnk_end = (chnk_idx_max - chnk_idx);
   1951         for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) {
   1952             entry =
   1953                 soc_mem_table_idx_to_pointer(unit, mem, uint32 *,
   1954                                              ls_tbl_chnk, ent_idx);
   1955             rv = _bcm_td3_evxlt_entry_valid(unit, mem, entry, &valid);
   1956             if (BCM_FAILURE(rv)) {
   1957                 break;
   1958             }
   1959             if (!valid) {
   1960                 continue;
   1961             }
   1962 
   1963             bcm_l2_change_fields_t_init(&l2_info);
   1964 
   1965             rv =_bcm_td3_change_l2_fields_entry_parse(unit, mem, entry, &l2_info);
   1966             if (rv == BCM_E_NOT_FOUND) { /* not a large scale nat entry */
   1967                 continue;
   1968             } else if (BCM_FAILURE(rv)) {
   1969                 break;
   1970             }
   1971             rv = cb(unit, &l2_info, user_data);
   1972             if (BCM_FAILURE(rv)) {
   1973                 break;
   1974             }
   1975         }
   1976     }
   1977     soc_cm_sfree(unit, ls_tbl_chnk);
   1978     return rv;
   1979 }
   1980 #ifdef BCM_WARM_BOOT_SUPPORT
   1981 int
   1982 _bcm_td3_l2_change_fields_reinit(int unit)
   1983 {
   1984     /*
   1985      * Recover VLAN Tag Action Profile and TPID ref counts from
   1986      * EGR_VLAN_XLATE_2_DOUBLE::CHANGE_L2_FIELDS view.
   1987      */
   1988     int rv = BCM_E_NONE;
   1989     char   *egr_xlate_buf = NULL;
   1990     int i, index_min, index_max;
   1991     uint32 entry_type = 0;
   1992     egr_vlan_xlate_2_double_entry_t *egr_xlate_entry;
   1993     soc_mem_t egr_mem = EGR_VLAN_XLATE_2_DOUBLEm;
   1994     int profile_index, tpid_idx;
   1995 
   1996     egr_xlate_buf = soc_cm_salloc(unit,
   1997             SOC_MEM_TABLE_BYTES(unit, EGR_VLAN_XLATE_2_DOUBLEm), "EGR VLAN XLATE buffer");
   1998 
   1999     if (NULL == egr_xlate_buf) {
   2000         rv = BCM_E_MEMORY;
   2001         goto cleanup;
   2002     }
   2003     index_min = soc_mem_index_min(unit, egr_mem);
   2004     index_max = soc_mem_index_max(unit, egr_mem);
   2005     rv = soc_mem_read_range(unit, egr_mem, MEM_BLOCK_ANY,
   2006             index_min, index_max, egr_xlate_buf);
   2007 
   2008     if (SOC_FAILURE(rv)) {
   2009         goto cleanup;
   2010     }
   2011 
   2012     for (i = index_min; i <= index_max; i++) {
   2013         egr_xlate_entry = soc_mem_table_idx_to_pointer(unit, egr_mem,
   2014                 egr_vlan_xlate_2_double_entry_t *, egr_xlate_buf, i);
   2015 
   2016         /* Check entry type */
   2017         entry_type = soc_mem_field32_get(unit, egr_mem, egr_xlate_entry,
   2018                 DATA_TYPEf);
   2019 
   2020         if (entry_type == _BCM_TD3_EXLATE_CHANGE_L2_FIELDS_DATA_TYPE) {
   2021             profile_index = soc_mem_field32_get(unit, egr_mem, egr_xlate_entry,
   2022                   CHANGE_L2_FIELDS__TAG_ACTION_PROFILE_PTRf);
   2023 
   2024             if (profile_index != 0) {
   2025                 _bcm_trx_egr_vlan_action_profile_entry_increment(unit,
   2026                     profile_index);
   2027             }
   2028             tpid_idx = soc_mem_field32_get(unit, egr_mem,
   2029                 egr_xlate_entry, CHANGE_L2_FIELDS__TPID_INDEXf);
   2030 
   2031             rv = _bcm_fb2_outer_tpid_tab_ref_count_add(unit,tpid_idx,1);
   2032             if (BCM_FAILURE(rv)) {
   2033                 goto cleanup;
   2034             }
   2035         }
   2036     }
   2037 cleanup:
   2038     if (egr_xlate_buf) {
   2039         soc_cm_sfree(unit, egr_xlate_buf);
   2040     }
   2041     return rv;
   2042 }
   2043 #endif /* BCM_WARM_BOOT_SUPPORT */
   2044 #endif /* INCLUDE_L3 */
   2045 
   2046 #endif /* BCM_TRIDENT3_SUPPORT */