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 */