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

instrumentation.c (36049B)


      1 /*
      2  * 
      3  *
      4  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      5  * 
      6  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      7  *
      8  * Tomahawk Instrumentation API
      9  */
     10 
     11 #include <soc/drv.h>
     12 
     13 #ifdef BCM_INSTRUMENTATION_SUPPORT
     14 
     15 #include <soc/mem.h>
     16 #include <soc/util.h>
     17 #include <soc/debug.h>
     18 #include <soc/loopback.h>
     19 #include <bcm/types.h>
     20 #include <bcm/error.h>
     21 #include <bcm/switch.h>
     22 #include <bcm_int/esw/instrumentation.h>
     23 #include <bcm/l2.h>
     24 #include <bcm_int/esw_dispatch.h>
     25 #include <bcm_int/esw/port.h>
     26 #include <bcm_int/esw/stack.h>
     27 #include <bcm_int/esw/switch.h>
     28 #include <bcm_int/esw/firebolt.h>
     29 #include <bcm_int/esw/virtual.h>
     30 #include <bcm_int/common/multicast.h>
     31 #include <shared/bsl.h>
     32 #include <shared/types.h>
     33 #include <shared/bitop.h>
     34 /* when visibility packet is sent
     35    following datastructure will be set */
     36 STATIC _bcm_switch_pkt_trace_port_info_t pkt_trace_port_info[BCM_MAX_NUM_UNITS];
     37 STATIC uint8 cpu_pkt_profile_id[BCM_MAX_NUM_UNITS];
     38 
     39 #define TH_MAX_PKT_TRACE_CPU_PROFILE_INDEX 0x7
     40 
     41 static uint32 ivp_raw_data[BCM_MAX_NUM_UNITS][4];     /* packet trace ivp process result data */
     42 static uint32 isw1_raw_data[BCM_MAX_NUM_UNITS][8];    /* packet trace isw1 process result data */
     43 static uint32 isw2_raw_data[BCM_MAX_NUM_UNITS][16];   /* packet trace isw2 process result data */
     44 
     45 /*
     46  * Function:
     47  *      bcm_th_pkt_trace_hw_reset
     48  * Purpose:
     49  *      clean PTR_RESULTS_BUFFER_IVP/ISW1/ISW2 registers
     50  *      call this functio before sending a 
     51  *      visibilty packet
     52  * Parameters:
     53  *      IN :  unit
     54  * Returns:
     55  *      BCM_E_XXX
     56  */
     57 int _bcm_th_pkt_trace_hw_reset(int unit)
     58 {
     59     uint32                          result_index;
     60     ptr_results_buffer_ivp_entry_t  ivp_entry;
     61     ptr_results_buffer_isw1_entry_t isw1_entry;
     62     ptr_results_buffer_isw2_entry_t isw2_entry;
     63 
     64     memset(&ivp_entry,  0x0, sizeof(ptr_results_buffer_ivp_entry_t));
     65     memset(&isw1_entry, 0x0, sizeof(ptr_results_buffer_isw1_entry_t));
     66     memset(&isw2_entry, 0x0, sizeof(ptr_results_buffer_isw2_entry_t));
     67      
     68     for (result_index = 0; result_index < TH_PTR_RESULTS_IVP_MAX_INDEX; result_index++) {  
     69         WRITE_PTR_RESULTS_BUFFER_IVPm(unit, MEM_BLOCK_ALL, result_index, &ivp_entry);
     70     }
     71 
     72     for (result_index = 0; result_index < TH_PTR_RESULTS_ISW1_MAX_INDEX; result_index++) {  
     73         WRITE_PTR_RESULTS_BUFFER_ISW1m(unit, MEM_BLOCK_ALL, result_index,&isw1_entry);
     74     }
     75 
     76     for (result_index = 0; result_index < TH_PTR_RESULTS_ISW2_MAX_INDEX; result_index++) {  
     77         WRITE_PTR_RESULTS_BUFFER_ISW2m(unit, MEM_BLOCK_ALL, result_index,&isw2_entry);
     78     }
     79     return BCM_E_NONE;
     80 }
     81 
     82 /*
     83  * Function:
     84  *      _bcm_th_pkt_trace_src_port_set 
     85  * Purpose:
     86  *      set the source port of 
     87  *      visiblity packet
     88  *      this must be called before visibilty packet 
     89  *      is sent to set the pipe to read the resuls 
     90  * Parameters:
     91  *      IN :  unit
     92  *      IN : logical_src_port
     93  * Returns:
     94  *      BCM_E_XXX
     95  */
     96 int _bcm_th_pkt_trace_src_port_set(int unit, uint32 logical_src_port) 
     97 {
     98     soc_info_t  *si;
     99     si = &SOC_INFO(unit);
    100 
    101     pkt_trace_port_info[unit].pkt_trace_src_logical_port = logical_src_port;
    102     pkt_trace_port_info[unit].pkt_trace_src_pipe =  
    103                                       si->port_pipe[logical_src_port];
    104 
    105     return 0;
    106 }
    107 
    108 /*
    109  * Function:
    110  *      _bcm_th_pkt_trace_src_port_get 
    111  * Purpose:
    112  *      get the source port of 
    113  *      visiblity packet
    114  * Parameters:
    115  *      IN :  unit
    116  *      IN : logical_src_port
    117  * Returns:
    118  *      BCM_E_XXX
    119  */
    120 
    121 int _bcm_th_pkt_trace_src_port_get(int unit) 
    122 {
    123     return pkt_trace_port_info[unit].pkt_trace_src_logical_port;
    124 }
    125 
    126 /*
    127  * Function:
    128  *      _bcm_th_pkt_trace_src_pipe_get 
    129  * Purpose:
    130  *      get the ingress pipe of
    131  *      visiblity packet
    132  * Parameters:
    133  *      IN :  unit
    134  *      IN : logical_src_port
    135  * Returns:
    136  *      BCM_E_XXX
    137  */
    138 int _bcm_th_pkt_trace_src_pipe_get(int unit) 
    139 {
    140     return pkt_trace_port_info[unit].pkt_trace_src_pipe;
    141 }
    142 
    143 /*
    144  * Function:
    145  *      _bcm_th_pkt_trace_stp_state_get
    146  * Purpose:
    147  *      change bit mapping of stp state 
    148  *      and assign to sw stp state 
    149  * Parameters:
    150  *      unit - (IN) Unit number.
    151  *      entry - (IN) BCM field entry id.
    152  *      stp_state (INOUT) stp state output.
    153  *      hw_stp_date (IN). hw stp state bits
    154  :* Returns:
    155  *      BCM_E_XXX
    156  * Notes:
    157  */
    158 int
    159 _bcm_th_pkt_trace_stp_state_get(int unit,
    160                                 uint32 *stp_state,
    161                                 uint32  hw_stp_data)
    162 {
    163     /* Input parameters check. */
    164     if ((NULL == stp_state)) {
    165         return (BCM_E_PARAM);
    166     }
    167 
    168     switch (hw_stp_data) {
    169       case 0:
    170           *stp_state = BCM_STG_STP_DISABLE;
    171           break;
    172       case 1:
    173           *stp_state = BCM_STG_STP_BLOCK;
    174           break;
    175       case 2:
    176           *stp_state = BCM_STG_STP_LEARN;
    177           break;
    178       case 3:
    179           *stp_state = BCM_STG_STP_FORWARD;
    180           break;
    181       default:
    182           return (BCM_E_INTERNAL);
    183     }
    184     return (BCM_E_NONE);
    185 }
    186 
    187 /*
    188  * Function:
    189  *      _bcm_th_pkt_trace_drop_reason_abstract
    190  * Purpose:
    191  *      abstract visibility packet drop reason,
    192  * Parameters:
    193  *      unit - (IN) Unit number.
    194  *      drop_reason - (OUT) packet drop reason.
    195  * Returns:
    196  *      BCM_E_XXX
    197  */
    198 static
    199 int _bcm_th_pkt_trace_drop_reason_abstract(int unit,
    200                                            uint32* drop_reason)
    201 {
    202     typedef struct drop_reason_map_s {
    203         int32  reason;
    204         int32  offset;
    205     } drop_reason_map_t;
    206 
    207     static drop_reason_map_t drop_reason_map[] = {
    208         {bcmSwitchPktTraceDropReasonVlanNotValid,                 27},
    209         {bcmSwitchPktTraceDropReasonIngressPortNotInVlanMember,   28},
    210         {bcmSwitchPktTraceDropReasonTpidMismatch,                 29},
    211         {bcmSwitchPktTraceDropReasonControlFrame,                 30},
    212         {bcmSwitchPktTraceDropReasonIpv4ProtocolError,            31},
    213         {bcmSwitchPktTraceDropReasonHigigLoopback,                32},
    214         {bcmSwitchPktTraceDropReasonHigigMirrorOnly,              33},
    215         {bcmSwitchPktTraceDropReasonHigigUnknownHeader,           34},
    216         {bcmSwitchPktTraceDropReasonHigigUnknownOpcode,           35},
    217         {bcmSwitchPktTraceDropReasonLagFailLoopback,              37},
    218         {bcmSwitchPktTraceDropReasonL2SrcEqualL2Dst,              38},
    219         {bcmSwitchPktTraceDropReasonIpv6ProtocolError,            39},
    220         {bcmSwitchPktTraceDropReasonNivDot1p,                     42},
    221         {bcmSwitchPktTraceDropReasonNivVntagPresent,              43},
    222         {bcmSwitchPktTraceDropReasonNivVntagNotPresent,           44},
    223         {bcmSwitchPktTraceDropReasonNivVntagFormat,               45},
    224         {bcmSwitchPktTraceDropReasonTrillErrorFrame,              46},
    225         {bcmSwitchPktTraceDropReasonMplsLabelLookupMiss,          48},
    226         {bcmSwitchPktTraceDropReasonMplsInvalidAction,            49},
    227         {bcmSwitchPktTraceDropReasonMplsInvalidPayload,           50},
    228         {bcmSwitchPktTraceDropReasonMplsTtlCheckFail,             51},
    229         {bcmSwitchPktTraceDropReasonMplsInvalidControlWord,       52},
    230         {bcmSwitchPktTraceDropReasonMplsGalLabel,                 53},
    231         {bcmSwitchPktTraceDropReasonL2greSipLookupMiss,           54},
    232         {bcmSwitchPktTraceDropReasonL2greVpnLookupMiss,           55},
    233         {bcmSwitchPktTraceDropReasonL2greTunnelError,             56},
    234         {bcmSwitchPktTraceDropReasonVxlanSipLookupMiss,           57},
    235         {bcmSwitchPktTraceDropReasonVxlanVnidLookupMiss,          58},
    236         {bcmSwitchPktTraceDropReasonVxlanTunnelError,             59},
    237         {bcmSwitchPktTraceDropReasonBpdu,                         65},
    238         {bcmSwitchPktTraceDropReasonProtocolPkt,                  66},
    239         {bcmSwitchPktTraceDropReasonUnknownSrcMac,                67},
    240         {bcmSwitchPktTraceDropReasonSrcRoute,                     68},
    241         {bcmSwitchPktTraceDropReasonL2SrcDiscard,                 69},
    242         {bcmSwitchPktTraceDropReasonL2SrcStaticMove,              70},
    243         {bcmSwitchPktTraceDropReasonL2DstDiscard,                 71},
    244         {bcmSwitchPktTraceDropReasonHigigHdrError,                76},
    245         {bcmSwitchPktTraceDropReasonSrcMacZero,                   78},
    246         {bcmSwitchPktTraceDropReasonStageLookup,                  79},
    247         {bcmSwitchPktTraceDropReasonL2DstMissOrPbt,               80},
    248         {bcmSwitchPktTraceDropReasonClassBasedStationMove,        81},
    249         {bcmSwitchPktTraceDropReasonTimeSyncPkt,                  84},
    250         {bcmSwitchPktTraceDropReasonMyStation,                    88},
    251         {bcmSwitchPktTraceDropReasonBadUdpChecksum,               89},
    252         {bcmSwitchPktTraceDropReasonPVlanVpEgressFilter,          94},
    253         {bcmSwitchPktTraceDropReasonL3DstDiscard,                 106},
    254         {bcmSwitchPktTraceDropReasonTunnlDecapEcnError,           107},
    255         {bcmSwitchPktTraceDropReasonIpv4HeaderError,              130},
    256         {bcmSwitchPktTraceDropReasonIpv6HeaderError,              134},
    257         {bcmSwitchPktTraceDropReasonStpNotForwarding,             138},
    258         {bcmSwitchPktTraceDropReasonPortTagPresentError,          139},
    259         {bcmSwitchPktTraceDropReasonStageIngress,                 141},
    260         {bcmSwitchPktTraceDropReasonMcastLookupMiss,              142},
    261         {bcmSwitchPktTraceDropReasonPortBitmapZero,               143},
    262         {bcmSwitchPktTraceDropReasonMcastIndexError,              156},
    263         {bcmSwitchPktTraceDropReasonParityError,                  159},
    264         {bcmSwitchPktTraceDropReasonRpfCheckFail,                 162},
    265         {-1,                                                      -1},
    266     };
    267     uint32 drop_reason_tmp[6] = {0,0,0,0,0,0};
    268     uint32 index;
    269 
    270     if(drop_reason == NULL) {
    271         return BCM_E_PARAM;
    272     }
    273 
    274     SHR_BITCOPY_RANGE(&drop_reason_tmp[0], 27, &(isw1_raw_data[unit][6]), 27, 5);
    275     SHR_BITCOPY_RANGE(&drop_reason_tmp[1], 0, &(isw1_raw_data[unit][7]), 0, 32);
    276     SHR_BITCOPY_RANGE(&drop_reason_tmp[2], 0, &(isw2_raw_data[unit][12]), 0, 32);
    277     SHR_BITCOPY_RANGE(&drop_reason_tmp[3], 0, &(isw2_raw_data[unit][13]), 0, 12);
    278 
    279     /* Definition of COUNTER_UPDATE_VECTOR in INSTR_BUFFER_ISW2_DW7
    280      * Bit0:   V4 L3 pkt discarded due to resource
    281      * Bit2:   IPv4 Header Error packets
    282      * Bit4:   V6 L3 pkt discarded due to resource
    283      * Bit6:   IPv6 Header Error packets
    284      * Bit10: pkts dropped as ingress port's SP state is not forwarding
    285      * Bit11: policy discard such as discard tag/untag pkts, disc. based on SA/DA lookup
    286      * Bit13: Pkts dropped by FP
    287      * Bit14: PFM = 2 and M/C Miss
    288      * Bit15: portbitmap zero drop condition
    289      * Bit20: DOS L4 header error pkts, applicable only to 10GE ingress ports
    290      * Bit23: pkts dropped due to MTU check fail
    291      * Bit25: Received Tunnel pkts with Error
    292      * Bit26: packets dropped due to VLAN related errors
    293      * Bit27: packets dropped due to HiGig Hdr errors
    294      * Bit28: packets dropped due to MC/IPMC index error
    295      * Bit31: Pkts dropped due to parity error
    296      * Bit34: packets dropped due to uRPF check failure
    297      * Bit36: packets dropped due to L2/L3 lookup DST_DISCARD bit
    298      * Bit45: drop Non-Trill frame on NW port
    299      * Bit46: drop Trill frame on access port
    300      * Bit55: ECMP not resolved
    301      */
    302     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 0, &(isw2_raw_data[unit][14]), 0, 1);
    303     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 2, &(isw2_raw_data[unit][14]), 2, 1);
    304     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 4, &(isw2_raw_data[unit][14]), 4, 1);
    305     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 6, &(isw2_raw_data[unit][14]), 6, 1);
    306     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 10, &(isw2_raw_data[unit][14]), 10, 2);
    307     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 13, &(isw2_raw_data[unit][14]), 13, 3);
    308     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 20, &(isw2_raw_data[unit][14]), 20, 1);
    309     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 23, &(isw2_raw_data[unit][14]), 23, 1);
    310     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 25, &(isw2_raw_data[unit][14]), 25, 4);
    311     SHR_BITCOPY_RANGE(&drop_reason_tmp[4], 31, &(isw2_raw_data[unit][14]), 31, 1);
    312     SHR_BITCOPY_RANGE(&drop_reason_tmp[5], 2, &(isw2_raw_data[unit][15]), 2, 1);
    313     SHR_BITCOPY_RANGE(&drop_reason_tmp[5], 5, &(isw2_raw_data[unit][15]), 5, 1);
    314     SHR_BITCOPY_RANGE(&drop_reason_tmp[5], 14, &(isw2_raw_data[unit][15]), 14, 2);
    315     SHR_BITCOPY_RANGE(&drop_reason_tmp[5], 24, &(isw2_raw_data[unit][15]), 24, 1);
    316 
    317     SHR_BITSET(drop_reason, bcmSwitchPktTraceNoDrop);
    318     for(index = 0; ; index++) {
    319         if((drop_reason_map[index].offset == -1) || (drop_reason_map[index].reason == -1)) {
    320             break;
    321         }
    322         if(drop_reason_map[index].offset >= (32*6)) {
    323             continue;
    324         }
    325         if((drop_reason_map[index].reason <= bcmSwitchPktTraceDropReasonInternal) ||
    326            (drop_reason_map[index].reason >= bcmSwitchPktTraceDropReasonCount)) {
    327             continue;
    328         }
    329         if(SHR_BITGET(drop_reason_tmp, drop_reason_map[index].offset)) {
    330             SHR_BITSET(drop_reason, drop_reason_map[index].reason);
    331             SHR_BITCLR(drop_reason, bcmSwitchPktTraceNoDrop);
    332             SHR_BITCLR(drop_reason_tmp, drop_reason_map[index].offset);
    333         }
    334     }
    335 
    336     if(drop_reason_tmp[0] || drop_reason_tmp[1] || drop_reason_tmp[2] ||
    337        drop_reason_tmp[3] || drop_reason_tmp[4] || drop_reason_tmp[5]) {
    338         SHR_BITSET(drop_reason, bcmSwitchPktTraceDropReasonInternal);
    339         SHR_BITCLR(drop_reason, bcmSwitchPktTraceNoDrop);
    340     }
    341 
    342     return BCM_E_NONE;
    343 }
    344 
    345 #ifdef INCLUDE_L3
    346 static
    347 int _bcm_th_pkt_trace_fwd_dst_info_get(int unit,
    348                                   bcm_switch_pkt_trace_info_t *pkt_trace_info)
    349 {
    350     bcm_port_t port = 0;
    351     bcm_module_t modid = 0;
    352     uint32 fwd_dst_type = 0;
    353     uint32 fwd_dst_field = 0;
    354     bcm_switch_pkt_trace_fwd_dst_info_t fwd_dst_info = {0};
    355 
    356     SHR_BITCOPY_RANGE(&fwd_dst_type, 0, &(isw2_raw_data[unit][0]), 19, 3);
    357     SHR_BITCOPY_RANGE(&fwd_dst_field, 0, &(isw2_raw_data[unit][0]), 1, 18);
    358 
    359     switch (fwd_dst_type) {
    360         case TH_FWD_DEST_TYPE_NH:
    361             fwd_dst_info.flags = BCM_SWITCH_PKT_TRACE_FWD_DST_NH;
    362             fwd_dst_info.egress_intf = fwd_dst_field + BCM_XGS3_EGRESS_IDX_MIN(unit);
    363             break;
    364 
    365         case TH_FWD_DEST_TYPE_L2MC:
    366             fwd_dst_info.flags = BCM_SWITCH_PKT_TRACE_FWD_DST_L2MC;
    367             _BCM_MULTICAST_GROUP_SET(fwd_dst_info.mc_group,
    368                 _BCM_MULTICAST_TYPE_L2, fwd_dst_field);
    369             break;
    370 
    371         case TH_FWD_DEST_TYPE_IPMC:
    372             fwd_dst_info.flags = BCM_SWITCH_PKT_TRACE_FWD_DST_IPMC;
    373             _BCM_MULTICAST_GROUP_SET(fwd_dst_info.mc_group,
    374                 _BCM_MULTICAST_TYPE_L3, fwd_dst_field);
    375             break;
    376 
    377         case TH_FWD_DEST_TYPE_DVP:
    378             fwd_dst_info.flags = BCM_SWITCH_PKT_TRACE_FWD_DST_DVP;
    379             _bcm_vp_encode_gport(unit, fwd_dst_field, &fwd_dst_info.dvp);
    380             break;
    381 
    382         case TH_FWD_DEST_TYPE_DGLP:
    383             port = fwd_dst_field & TH_FWD_DEST_PORT_MASK;
    384             modid = (fwd_dst_field >> TH_FWD_DEST_PORT_SHIFT) & TH_FWD_DEST_PORT_MASK;
    385             fwd_dst_info.flags = BCM_SWITCH_PKT_TRACE_FWD_DST_DGPP;
    386             BCM_GPORT_MODPORT_SET(fwd_dst_info.port, modid, port);
    387             break;
    388 
    389         default:
    390             break;
    391     }
    392 
    393     pkt_trace_info->pkt_trace_fwd_dst_info = fwd_dst_info;
    394     return BCM_E_NONE;
    395 }
    396 #endif /* INCLUDE_L3 */
    397 
    398 /*
    399  * Function:
    400  *      _bcm_th_pkt_trace_info_abstract
    401  * Purpose: 
    402  *      abstract visibility packet process data from PTR_RESULTS_BUFFER_IVP,
    403  *      ISW1, and ISW2 stored in bcm_switch_pkt_trace_info_s.
    404  * Parameters:
    405  *      IN :  unit
    406  *      IN:   pkt_trace_info
    407  * Returns:
    408  *      BCM_E_XXX
    409  */
    410 static
    411 int _bcm_th_pkt_trace_info_abstract(int unit,
    412                                   bcm_switch_pkt_trace_info_t *pkt_trace_info)
    413 {
    414 #define STP_BIT_POS 4
    415 #define STP_BIT_NUM 2
    416     /* pkt lookup and resolution vars*/
    417     uint32  my_station_index[1] = {0}, my_station_hit[1] = {0},
    418             lookup_status[1] = {0}, pkt_rsl_vector[1] = {0},
    419             ing_stp_state[1] = {0};
    420 
    421 #ifdef INCLUDE_L3
    422     /* hashing information vars */
    423     uint32  ecmp_rsl_done1[1] = {0}, ecmp_rsl_done2[1] = {0}, 
    424             ecmp_hash_val1[1] = {0}, ecmp_hash_val2[1] = {0},
    425             ecmp_group1[1]    = {0}, ecmp_group2[1]    = {0}, 
    426             ecmp_offset1[1]   = {0}, ecmp_offset2[1]   = {0};
    427     uint32  ecmp_index, ecmp_ptr;
    428     int     ecmp_id;
    429     ecmp_count_entry_t      ecmpc_entry;
    430     ecmp_entry_t            ecmp_entry;
    431 #endif
    432     uint32  lag_rsl_done[1]   = {0}, lag_hash_val[1]   = {0},
    433             lag_id[1]         = {0},  
    434             hg_rsl_done[1]    = {0}, hg_trunk_id[1]    = {0}, 
    435             hg_port[1]        = {0}, hg_hash_val[1]    = {0},
    436             hg_offset[1]      = {0}, lag_offset[1]     = {0};
    437     /* hashing cal vars */
    438     int         tgid,  mod_is_local;
    439     uint32      trunk_base, trunk_group_size;
    440     uint32      trunk_index, trunk_member_table_index;
    441     bcm_module_t        mod_id;
    442     bcm_port_t          port_id;
    443     bcm_gport_t         dst_member_port;
    444     _bcm_gport_dest_t   dest;
    445 
    446     trunk_member_entry_t    trunk_member_entry;
    447     trunk_group_entry_t     tg_entry;
    448     hg_trunk_member_entry_t hg_trunk_member_entry;
    449     hg_trunk_group_entry_t  hg_tg_entry;
    450 
    451     bcm_trunk_chip_info_t chip_info;
    452 
    453     /* retrieve my station info */
    454     SHR_BITCOPY_RANGE(my_station_index, 0, &(ivp_raw_data[unit][0]), 17, 10);
    455     SHR_BITCOPY_RANGE(my_station_hit, 0, &(ivp_raw_data[unit][0]), 27, 1);
    456 
    457     /* retrieve lookup status */
    458     SHR_BITCOPY_RANGE(lookup_status, 0, &(isw1_raw_data[unit][6]), 7, 20);
    459 
    460     if (my_station_hit[0]) {
    461         SHR_BITSET(lookup_status, bcmSwitchPktTraceLookupMystationHit);
    462     }
    463 
    464     /* fill ingress stp enum*/
    465     SHR_BITCOPY_RANGE(ing_stp_state, 0, lookup_status, STP_BIT_POS, STP_BIT_NUM);
    466     BCM_IF_ERROR_RETURN(_bcm_th_pkt_trace_stp_state_get(unit, 
    467                               &(pkt_trace_info->pkt_trace_stp_state),
    468                                 ing_stp_state[0]));
    469 
    470     /* clear stp bits from lookup status */
    471     SHR_BITCLR(lookup_status, STP_BIT_POS);
    472     SHR_BITCLR(lookup_status, STP_BIT_POS + STP_BIT_NUM - 1);
    473 
    474     SHR_BITCOPY_RANGE(
    475         (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 0,
    476          lookup_status, 0, 1);
    477 
    478     SHR_BITCOPY_RANGE(
    479         (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 2,
    480          lookup_status, 1, 1);
    481 
    482     SHR_BITCOPY_RANGE(
    483         (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 1,
    484          lookup_status, 2, 1);
    485 
    486     /* fill lookup status enum*/
    487     SHR_BITCOPY_RANGE(
    488         (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 3,
    489          lookup_status, 3, bcmSwitchPktTraceLookupCount-2);
    490   
    491     /* fill packet resolution vector */
    492     SHR_BITCOPY_RANGE(pkt_rsl_vector, 0, &(isw2_raw_data[unit][0]), 22, 6);
    493     pkt_trace_info->pkt_trace_resolution = pkt_rsl_vector[0];
    494 
    495 #ifdef INCLUDE_L3
    496 #if defined(BCM_TOMAHAWK2_SUPPORT)
    497     if (SOC_IS_TOMAHAWK2(unit)) {
    498         /*retrieve hashing information*/
    499          SHR_BITCOPY_RANGE(ecmp_offset2 , 0, &(isw2_raw_data[unit][2]), 2, 10);
    500          SHR_BITCOPY_RANGE(ecmp_group2 , 0, &(isw2_raw_data[unit][2]), 12 , 12);
    501          SHR_BITCOPY_RANGE(ecmp_rsl_done2 , 0, &(isw2_raw_data[unit][2]), 24, 1);
    502 
    503         /* ecmp_hash_val1 = isw2.dw1[26:41] */
    504          SHR_BITCOPY_RANGE(ecmp_hash_val1 , 0, &(isw2_raw_data[unit][2]), 25 , 7);
    505          SHR_BITCOPY_RANGE(ecmp_hash_val1 , 7, &(isw2_raw_data[unit][3]), 0, 9);
    506          SHR_BITCOPY_RANGE(ecmp_offset1, 0, &(isw2_raw_data[unit][3]), 9, 10);
    507          SHR_BITCOPY_RANGE(ecmp_group1 , 0, &(isw2_raw_data[unit][3]), 19, 12);
    508          SHR_BITCOPY_RANGE(ecmp_rsl_done1 , 0, &(isw2_raw_data[unit][3]), 31, 1);
    509          SHR_BITCOPY_RANGE(ecmp_hash_val2 , 0, &(isw2_raw_data[unit][5]), 16, 16);
    510     } else
    511 #endif /* BCM_TOMAHAWK2_SUPPORT */
    512     {
    513         /*retrieve hashing information*/
    514          SHR_BITCOPY_RANGE(ecmp_offset2 , 0, &(isw2_raw_data[unit][2]), 4, 10);
    515          SHR_BITCOPY_RANGE(ecmp_group2 , 0, &(isw2_raw_data[unit][2]), 14 , 11);
    516          SHR_BITCOPY_RANGE(ecmp_rsl_done2 , 0, &(isw2_raw_data[unit][2]), 25, 1);
    517 
    518         /* ecmp_hash_val1 = isw2.dw1[41:26] */
    519          SHR_BITCOPY_RANGE(ecmp_hash_val1 , 0, &(isw2_raw_data[unit][2]), 26 , 6);
    520          SHR_BITCOPY_RANGE(ecmp_hash_val1 , 6, &(isw2_raw_data[unit][3]), 0, 10);
    521          SHR_BITCOPY_RANGE(ecmp_offset1, 0, &(isw2_raw_data[unit][3]), 10, 10);
    522          SHR_BITCOPY_RANGE(ecmp_group1 , 0, &(isw2_raw_data[unit][3]), 20, 11);
    523          SHR_BITCOPY_RANGE(ecmp_rsl_done1 , 0, &(isw2_raw_data[unit][3]), 31, 1);
    524          SHR_BITCOPY_RANGE(ecmp_hash_val2 , 0, &(isw2_raw_data[unit][5]), 16, 16);
    525     }
    526 #endif
    527 
    528     /* isw2.dw2[31:0] */
    529     SHR_BITCOPY_RANGE(lag_offset, 0, &(isw2_raw_data[unit][4]), 1, 10);
    530     SHR_BITCOPY_RANGE(lag_hash_val , 0, &(isw2_raw_data[unit][4]), 11, 10);
    531     SHR_BITCOPY_RANGE(lag_id , 0, &(isw2_raw_data[unit][4]) ,21, 10);
    532     SHR_BITCOPY_RANGE(lag_rsl_done , 0, &(isw2_raw_data[unit][4]), 31, 1);
    533 
    534     /* isw2.dw3[21:0] */
    535     SHR_BITCOPY_RANGE(hg_offset , 0, &(isw2_raw_data[unit][6]), 0, 5);
    536     SHR_BITCOPY_RANGE(hg_port , 0, &(isw2_raw_data[unit][6]), 6, 8);
    537     SHR_BITCOPY_RANGE(hg_trunk_id , 0, &(isw2_raw_data[unit][6]), 14, 7);
    538     SHR_BITCOPY_RANGE(hg_rsl_done , 0, &(isw2_raw_data[unit][6]),21 , 1);
    539 
    540     /* isw2.dw4[63:54] */
    541     SHR_BITCOPY_RANGE(hg_hash_val , 0, &(isw2_raw_data[unit][8]), 22, 10);
    542 
    543 #ifdef INCLUDE_L3
    544     if (ecmp_rsl_done1[0]) {
    545         ecmp_id = ecmp_group1[0];
    546 
    547        SOC_IF_ERROR_RETURN
    548             (READ_L3_ECMP_COUNTm(unit, MEM_BLOCK_ANY, ecmp_id, &ecmpc_entry));
    549 
    550         ecmp_ptr = soc_L3_ECMP_COUNTm_field32_get(unit, &ecmpc_entry,
    551                                                   BASE_PTRf);
    552         ecmp_index = (ecmp_ptr + ecmp_offset1[0]) & (soc_mem_index_count(unit, L3_ECMPm) - 1);
    553     
    554         SOC_IF_ERROR_RETURN
    555             (READ_L3_ECMPm(unit, MEM_BLOCK_ANY, ecmp_index, &ecmp_entry));
    556         pkt_trace_info->pkt_trace_hash_info.ecmp_1_group   = ecmp_id; 
    557         pkt_trace_info->pkt_trace_hash_info.ecmp_1_group  += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    558         
    559         pkt_trace_info->pkt_trace_hash_info.ecmp_1_egress  = 
    560                     soc_L3_ECMPm_field32_get(unit, &ecmp_entry, NEXT_HOP_INDEXf); 
    561         if (ecmp_rsl_done2[0]) {
    562             pkt_trace_info->pkt_trace_hash_info.ecmp_1_egress += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    563         } else {
    564             pkt_trace_info->pkt_trace_hash_info.ecmp_1_egress += BCM_XGS3_EGRESS_IDX_MIN(unit);
    565         }
    566 
    567         pkt_trace_info->pkt_trace_hash_info.flags += BCM_SWITCH_PKT_TRACE_ECMP_1;
    568     }
    569 
    570     if (ecmp_rsl_done2[0]) {
    571         ecmp_id = ecmp_group2[0];
    572 
    573        SOC_IF_ERROR_RETURN
    574             (READ_L3_ECMP_COUNTm(unit, MEM_BLOCK_ANY, ecmp_id, &ecmpc_entry));
    575 
    576         ecmp_ptr = soc_L3_ECMP_COUNTm_field32_get(unit, &ecmpc_entry,
    577                                                   BASE_PTRf);
    578         ecmp_index = (ecmp_ptr + ecmp_offset2[0]) & (soc_mem_index_count(unit, L3_ECMPm) - 1);
    579     
    580         SOC_IF_ERROR_RETURN
    581             (READ_L3_ECMPm(unit, MEM_BLOCK_ANY, ecmp_index, &ecmp_entry));
    582 
    583         pkt_trace_info->pkt_trace_hash_info.ecmp_2_group   = ecmp_id; 
    584         pkt_trace_info->pkt_trace_hash_info.ecmp_2_group  += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit);
    585         
    586         pkt_trace_info->pkt_trace_hash_info.ecmp_2_egress   = 
    587                     soc_L3_ECMPm_field32_get(unit, &ecmp_entry, NEXT_HOP_INDEXf); 
    588         pkt_trace_info->pkt_trace_hash_info.ecmp_2_egress  += BCM_XGS3_EGRESS_IDX_MIN(unit);
    589         pkt_trace_info->pkt_trace_hash_info.flags += BCM_SWITCH_PKT_TRACE_ECMP_2;
    590     }
    591 
    592 #endif        
    593 
    594     if (lag_rsl_done[0]) {
    595         tgid = lag_id[0]; 
    596 
    597         BCM_IF_ERROR_RETURN(READ_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tgid, &tg_entry));
    598 
    599         trunk_group_size    = soc_TRUNK_GROUPm_field32_get(unit, &tg_entry, TG_SIZEf);
    600         trunk_base          = soc_TRUNK_GROUPm_field32_get(unit, &tg_entry, BASE_PTRf);
    601         trunk_index         = lag_hash_val[0] % (trunk_group_size + 1);
    602         trunk_member_table_index = (trunk_base + trunk_index) & 0x7ff;
    603 
    604         BCM_IF_ERROR_RETURN(READ_TRUNK_MEMBERm(unit, MEM_BLOCK_ANY, 
    605                                  trunk_member_table_index, &trunk_member_entry));
    606         mod_id  = soc_TRUNK_MEMBERm_field32_get(unit, &trunk_member_entry,
    607                                                 MODULE_IDf);
    608         port_id = soc_TRUNK_MEMBERm_field32_get(unit, &trunk_member_entry,
    609                                                 PORT_NUMf);
    610        
    611         BCM_IF_ERROR_RETURN
    612             (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, mod_id, port_id,
    613                                             &(dest.modid), &(dest.port)));        
    614         dest.gport_type = _SHR_GPORT_TYPE_MODPORT;
    615 
    616         BCM_IF_ERROR_RETURN
    617             (_bcm_esw_modid_is_local(unit, dest.modid,
    618                                      &mod_is_local));
    619         if (mod_is_local) {
    620             if (IS_ST_PORT(unit, dest.port)) {
    621                 dest.gport_type = _SHR_GPORT_TYPE_DEVPORT;
    622             }
    623         }
    624         BCM_IF_ERROR_RETURN(_bcm_esw_gport_construct(unit, &dest, &dst_member_port));
    625 
    626         pkt_trace_info->pkt_trace_hash_info.trunk        = tgid; 
    627         pkt_trace_info->pkt_trace_hash_info.trunk_member = dst_member_port; 
    628         pkt_trace_info->pkt_trace_hash_info.flags += BCM_SWITCH_PKT_TRACE_TRUNK;
    629 
    630     } /* end lag resolution */
    631 
    632     if (hg_rsl_done[0]) {
    633         tgid = hg_trunk_id[0]; 
    634 
    635         BCM_IF_ERROR_RETURN(READ_HG_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tgid, &hg_tg_entry));
    636 
    637         trunk_group_size    = soc_HG_TRUNK_GROUPm_field32_get(unit, &hg_tg_entry, TG_SIZEf);
    638         trunk_base          = soc_HG_TRUNK_GROUPm_field32_get(unit, &hg_tg_entry, BASE_PTRf);
    639         trunk_index         = hg_hash_val[0] % (trunk_group_size + 1);
    640         trunk_member_table_index = (trunk_base + trunk_index) & 0xff;
    641 
    642         BCM_IF_ERROR_RETURN(READ_HG_TRUNK_MEMBERm(unit, MEM_BLOCK_ANY,
    643                             trunk_member_table_index, &hg_trunk_member_entry));
    644         port_id = soc_HG_TRUNK_MEMBERm_field32_get(unit, 
    645                             &hg_trunk_member_entry, PORT_NUMf);
    646 
    647         if (BCM_FAILURE(bcm_esw_stk_my_modid_get(unit, &mod_id))) {
    648             mod_id = 0;
    649         }
    650     
    651         BCM_IF_ERROR_RETURN
    652                 (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, mod_id, port_id,
    653                                              &(dest.modid), &(dest.port)));
    654         dest.gport_type = _SHR_GPORT_TYPE_DEVPORT;
    655 
    656         BCM_IF_ERROR_RETURN(_bcm_esw_gport_construct(unit, &dest, &dst_member_port));
    657 
    658         BCM_IF_ERROR_RETURN(bcm_esw_trunk_chip_info_get(unit, &chip_info));
    659         pkt_trace_info->pkt_trace_hash_info.fabric_trunk = 
    660                             tgid + chip_info.trunk_fabric_id_min;
    661         pkt_trace_info->pkt_trace_hash_info.fabric_trunk_member = 
    662                             dst_member_port;
    663         pkt_trace_info->pkt_trace_hash_info.flags += 
    664                             BCM_SWITCH_PKT_TRACE_FABRIC_TRUNK;
    665 
    666     } /* end lag resolution */
    667 
    668     BCM_IF_ERROR_RETURN(_bcm_th_pkt_trace_drop_reason_abstract(unit,
    669                         pkt_trace_info->pkt_trace_drop_reason));
    670     return BCM_E_NONE;
    671 }
    672 
    673 /*
    674  * Function:
    675  *      _bcm_th_pkt_trace_info_get
    676  * Purpose:
    677  *      read results ptr buffer for
    678  *      visibility packet process and
    679  *      store into pkt_trace_info
    680  * Parameters:
    681  *      IN :  unit
    682  * Returns:
    683  *      BCM_E_XXX
    684  */
    685 int _bcm_th_pkt_trace_info_get(int unit,
    686                               bcm_switch_pkt_trace_info_t *pkt_trace_info)
    687 {
    688     ptr_results_buffer_ivp_entry_t        ivp_entry;
    689     ptr_results_buffer_isw1_entry_t       isw1_entry; 
    690     ptr_results_buffer_isw2_entry_t       isw2_entry;
    691 
    692     uint8    result_index = 0, prev_index = 0, pipe = 0, trace_result_avail = 0;
    693     uint32   *dw_first, *dw_second;
    694 
    695     soc_mem_t mem;
    696     pipe =  pkt_trace_port_info[unit].pkt_trace_src_pipe;
    697     pkt_trace_info->dest_pipe_num = pipe;
    698 
    699     for (result_index = 0; result_index < TH_PTR_RESULTS_IVP_MAX_INDEX; result_index++) {
    700 
    701         if (SOC_MEM_UNIQUE_ACC(unit, PTR_RESULTS_BUFFER_IVPm) == NULL) {
    702             return BCM_E_INTERNAL;
    703         }
    704         mem = SOC_MEM_UNIQUE_ACC(unit, PTR_RESULTS_BUFFER_IVPm)[pipe];
    705         if (mem == INVALIDm) {
    706             return BCM_E_INTERNAL;
    707         }
    708 
    709         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, result_index, &ivp_entry)); 
    710 
    711         dw_first = (uint32*)&ivp_entry;
    712         dw_second = dw_first+1; 
    713 
    714         sal_memcpy(&(ivp_raw_data[unit][result_index *2]),
    715                    dw_first, sizeof(uint32));
    716         sal_memcpy(&(ivp_raw_data[unit][(result_index *2) + 1]),
    717                    dw_second, sizeof(uint32));
    718 
    719         if ((*dw_first != 0) || (*dw_second != 0)) {
    720             trace_result_avail = 1;
    721         }  
    722 
    723         sal_memcpy(&(pkt_trace_info->raw_data[result_index*8]), 
    724                    (uint8*)&ivp_entry, (sizeof(ivp_entry)));
    725 
    726     }/*end of ivp_parsing*/
    727     prev_index += result_index;
    728  
    729     for (result_index = 0; result_index < TH_PTR_RESULTS_ISW1_MAX_INDEX; result_index++) {
    730 
    731         if (SOC_MEM_UNIQUE_ACC(unit, PTR_RESULTS_BUFFER_ISW1m) == NULL) {
    732             return BCM_E_INTERNAL;
    733         }
    734         mem = SOC_MEM_UNIQUE_ACC(unit, PTR_RESULTS_BUFFER_ISW1m)[pipe];
    735         if (mem == INVALIDm) {
    736             return BCM_E_INTERNAL;
    737         }
    738 
    739         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, result_index, &isw1_entry)); 
    740 
    741         dw_first = (uint32*)&isw1_entry;
    742         dw_second = dw_first+1; 
    743 
    744         sal_memcpy(&(isw1_raw_data[unit][result_index *2]),
    745                    dw_first, sizeof(uint32));
    746         sal_memcpy(&(isw1_raw_data[unit][(result_index *2) + 1]),
    747                    dw_second, sizeof(uint32));
    748 
    749         if ((*dw_first != 0) || (*dw_second != 0)) {
    750             trace_result_avail = 1;
    751         }
    752  
    753         sal_memcpy(&(pkt_trace_info->raw_data[(prev_index+result_index)*8]), 
    754                    (uint8*)&isw1_entry, (sizeof(isw1_entry)));
    755    
    756     }/*end of isw1_parsing*/
    757     prev_index += result_index;
    758  
    759     for (result_index = 0; result_index < TH_PTR_RESULTS_ISW2_MAX_INDEX; result_index++) {
    760 
    761         if (SOC_MEM_UNIQUE_ACC(unit, PTR_RESULTS_BUFFER_ISW2m) == NULL) {
    762             return BCM_E_INTERNAL;
    763         }
    764         mem = SOC_MEM_UNIQUE_ACC(unit, PTR_RESULTS_BUFFER_ISW2m)[pipe];
    765         if (mem == INVALIDm) {
    766             return BCM_E_INTERNAL;
    767         }
    768 
    769         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, result_index, &isw2_entry)); 
    770 
    771         dw_first = (uint32*)&isw2_entry;
    772         dw_second = dw_first+1; 
    773 
    774         sal_memcpy(&(isw2_raw_data[unit][result_index *2]),
    775                    dw_first, sizeof(uint32));
    776         sal_memcpy(&(isw2_raw_data[unit][(result_index *2) + 1]),
    777                    dw_second, sizeof(uint32));
    778 
    779         if ((*dw_first != 0) || (*dw_second != 0)) {
    780             trace_result_avail = 1;
    781         }
    782 
    783  
    784         sal_memcpy(&(pkt_trace_info->raw_data[(prev_index+result_index)*8]), 
    785                    (uint8*)&isw2_entry, (sizeof(isw2_entry)));
    786    
    787     }/*end of isw2_parsing*/
    788   
    789     if (trace_result_avail == 0) {
    790         return BCM_E_BUSY;
    791     }
    792 
    793     pkt_trace_info->raw_data_length = (prev_index+result_index)*8;
    794     /* abstraction */
    795     BCM_IF_ERROR_RETURN(_bcm_th_pkt_trace_info_abstract(unit, pkt_trace_info));
    796 
    797 #ifdef INCLUDE_L3
    798     BCM_IF_ERROR_RETURN(_bcm_th_pkt_trace_fwd_dst_info_get(unit, pkt_trace_info));
    799 #endif /* INCLUDE_L3 */
    800 
    801     return BCM_E_NONE;
    802 }
    803 
    804 /*
    805  * Function:
    806  *      _bcm_th_pkt_trace_cpu_profile_init 
    807  * Purpose:
    808  *      pre-configure CPU_PKT_PROFILE_1,2 Register according to
    809  *      index : drop | ifp  | no learn
    810  *       0       0      0      0          
    811  *       1       0      0      1
    812  *       2       0      1      0
    813  *       3       0      1      1
    814  *       4       1      0      0
    815  *       5       1      0      1
    816  *       6       1      1      0
    817  *       7       1      1      1
    818  * Parameters:
    819  *      IN :  unit
    820  * Returns:
    821  *      BCM_E_XXX
    822  */
    823 int _bcm_th_pkt_trace_cpu_profile_init(int unit) {
    824     /* pkt_profile_1 contains control of IFP and Learning */
    825     uint32  pkt_profile_1_w = 0xCCAA;
    826     /* pkt_profile_2 contains control of forwarding */
    827     uint32  pkt_profile_2_w = 0xF0;
    828 
    829     if (SOC_REG_IS_VALID(unit, CPU_PKT_PROFILE_1r)) {
    830         WRITE_CPU_PKT_PROFILE_1r(unit, pkt_profile_1_w);
    831     }
    832 
    833     if (SOC_REG_IS_VALID(unit, CPU_PKT_PROFILE_2r)) {
    834         WRITE_CPU_PKT_PROFILE_2r(unit, pkt_profile_2_w);
    835     }
    836 
    837     return BCM_E_NONE;
    838 }
    839 
    840 /*
    841  * Function:
    842  *      _bcm_th_pkt_trace_cpu_profile_set
    843  * Purpose:
    844  *      given visibility packet behavior flags
    845  *      setting the profile id for the next visiblity packet
    846  * Parameters:
    847  *      IN :  unit
    848  * Returns:
    849  *      BCM_E_XXX
    850  */
    851 int _bcm_th_pkt_trace_cpu_profile_set(int unit,
    852                                      uint32 flags)
    853 {
    854     uint32 negate_flags[1] = {0}, param_flags[1] = {0};
    855     uint32 max_profile_index[1] = {0}, profile_id[1] = {0};
    856     param_flags[0] = flags;
    857     max_profile_index[0] =  TH_MAX_PKT_TRACE_CPU_PROFILE_INDEX;
    858     SHR_BITNEGATE_RANGE(param_flags, 0, 3, negate_flags); 
    859 
    860     SHR_BITAND_RANGE(negate_flags, max_profile_index, 0, 3,
    861                      profile_id);    
    862 
    863     cpu_pkt_profile_id[unit] = profile_id[0];
    864           
    865 
    866     return BCM_E_NONE;
    867 }
    868 
    869 /*
    870  * Function:
    871  *      _bcm_th_pkt_trace_cpu_profile_get
    872  * Purpose:
    873  *      retrieve cpu profile id to be used for
    874  *      the next visibilty packet
    875  * Parameters:
    876  *      IN :  unit
    877  * Returns:
    878  *      BCM_E_XXX
    879  */
    880 
    881 int _bcm_th_pkt_trace_cpu_profile_get(int unit, uint32* profile_id)
    882 {
    883     if (profile_id == NULL) {
    884         return BCM_E_INTERNAL;
    885     }
    886     *profile_id = cpu_pkt_profile_id[unit];
    887     return BCM_E_NONE;
    888 }
    889 
    890 /*
    891  * Function:
    892  *      _bcm_th_pkt_trace_int_lbport_set
    893  * Purpose:
    894  *       When SDK performs cpu masquerade, make sure
    895  *       the following 6 fields are consistent between
    896  *       lport_table and port_table.
    897  *       V6L3_ENABLEf, V4L3_ENABLEf, IEEE_802_1AS_ENABLEf,
    898  *       V4IPMC_ENABLEf, L2GRE_TERMINATION_ALLOWEDf,
    899  *       VXLAN_TERMINATION_ALLOWEDf.
    900  *
    901  * Parameters:
    902  *      unit    - (IN)  bcm device.
    903  *      port    - (IN)  port number.
    904  *      enable   - (IN)  1: enable the sw workaround;
    905  *                              0: disable the sw workaround.
    906  * Returns:
    907  *      BCM_E_XXX
    908  */
    909 
    910 int _bcm_th_pkt_trace_int_lbport_set(int unit, uint8 port, int enable, int *old_values)
    911 {
    912     int pipe_num, i;
    913     int loopback_port;
    914     uint32 values[6];
    915     int rv = BCM_E_NONE;
    916     soc_field_t  fields[6] = {
    917         V6L3_ENABLEf, V4L3_ENABLEf, IEEE_802_1AS_ENABLEf,
    918         V4IPMC_ENABLEf, L2GRE_TERMINATION_ALLOWEDf, VXLAN_TERMINATION_ALLOWEDf,
    919     };
    920     SOC_IF_ERROR_RETURN(
    921         soc_port_pipe_get(unit, port, &pipe_num));
    922     loopback_port = soc_loopback_lbport_num_get(unit, pipe_num);
    923     if (loopback_port == -1) {
    924         return BCM_E_PARAM;
    925     }
    926     if (enable) {
    927         PORT_LOCK(unit);
    928         rv = bcm_esw_port_lport_fields_get(unit, port,
    929                                            LPORT_PROFILE_LPORT_TAB, 6,
    930                                            fields, values);
    931         PORT_UNLOCK(unit);
    932         if (BCM_FAILURE(rv)) {
    933             return rv;
    934         }
    935         for (i = 0; i < 6; i++) {
    936             BCM_IF_ERROR_RETURN(
    937                 _bcm_esw_port_tab_get(unit, loopback_port,
    938                                       fields[i], &old_values[i]));
    939             BCM_IF_ERROR_RETURN(
    940                 _bcm_esw_port_tab_set(unit, loopback_port, 0,
    941                                       fields[i], values[i]));
    942         }
    943     } else {
    944         for (i = 0; i < 6; i++) {
    945             BCM_IF_ERROR_RETURN(
    946                 _bcm_esw_port_tab_set(unit, loopback_port, 0,
    947                                       fields[i], old_values[i]));
    948         }
    949     }
    950     return BCM_E_NONE;
    951 }
    952 #endif /* BCM_INSTRUMENTATION_SUPPORT */