instrumentation.c (89484B)
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: instrumentaion.c 8 * Purpose: Visibility Packet trace core implementaion for 9 * Trident3. 10 */ 11 12 #include <soc/drv.h> 13 #if defined(BCM_INSTRUMENTATION_SUPPORT) 14 #include <soc/format.h> 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 <shared/bsl.h> 24 #include <shared/types.h> 25 #include <shared/bitop.h> 26 #include <bcm/l2.h> 27 #include <bcm_int/esw_dispatch.h> 28 #include <bcm_int/esw/port.h> 29 #include <bcm_int/esw/stack.h> 30 #include <bcm_int/esw/switch.h> 31 #include <bcm_int/esw/firebolt.h> 32 #include <bcm_int/common/multicast.h> 33 #include <bcm_int/esw/stack.h> 34 #include <bcm_int/esw/virtual.h> 35 #include <bcm_int/esw/trident3.h> 36 37 #define _BCM_PKT_TRACE_FLOW_TYPE_FIXED(_type_) \ 38 (((_type_) == bcmPktFlowIdFixedNoop) || \ 39 ((_type_) == bcmPktFlowIdFixedTunnelMim) || \ 40 ((_type_) == bcmPktFlowIdFixedTunnelNvgre) || \ 41 ((_type_) == bcmPktFlowIdFixedTunnelVxlan) || \ 42 ((_type_) == bcmPktFlowIdFixedTunnelIpinIp) || \ 43 ((_type_) == bcmPktFlowIdFixedTunnelMpls)) 44 45 #define bcmPktFlowIdFixedNoop 1 46 #define bcmPktFlowIdFixedTunnelMim 2 47 #define bcmPktFlowIdFixedTunnelNvgre 3 48 #define bcmPktFlowIdFixedTunnelVxlan 4 49 #define bcmPktFlowIdFixedTunnelIpinIp 5 50 #define bcmPktFlowIdFixedTunnelMpls 6 51 52 #define MAX_DOP_FORMATS(_u_) ((SOC_IS_TRIDENT3(_u_)) ? 120 : 123) 53 #define MAX_ING_DOP_FORMATS(_u_) ((SOC_IS_TRIDENT3(_u_)) ? 105 : 108) 54 #define MAX_EGR_DOP_FORMATS(_u_) 15 55 #define DOP_INGRESS 0x2 56 #define DOP_EGRESS 0x4 57 #define DOP_PIPE_0 0 58 #define DOP_PIPE_1 1 59 60 #define TD3_FORWARDING_TYPE_L2_FORWARD 0 61 #define TD3_FORWARDING_TYPE_L3UC 1 62 63 #define TD3_MAX_PKT_TRACE_CPU_PROFILE_INDEX 0xF 64 #define BCM_PKT_TRC_DOP_DATA_WORD_LEN 4 65 66 #define BYTE_MASK 0xFF 67 #define BYTE_SHIFT 8 68 69 /* when visibility packet is sent 70 * following datastructure will be set */ 71 STATIC _bcm_switch_pkt_trace_port_info_t td3_pkt_trace_port_info[BCM_MAX_NUM_UNITS]; 72 STATIC uint8 td3_cpu_pkt_profile_id[BCM_MAX_NUM_UNITS]; 73 74 typedef struct pkt_trace_dop_format_s { 75 soc_format_t format; 76 uint16 dop_id; 77 uint16 data_phases; 78 uint32 *entry; 79 uint32 *next; 80 } pkt_trace_dop_format_t; 81 82 typedef struct pkt_trace_hash_node_s { 83 pkt_trace_dop_format_t *ft_entry; 84 uint32 entry_num; 85 } pkt_trace_hash_node_t; 86 87 typedef struct pkt_trace_hash_info_s{ 88 int unit; 89 pkt_trace_hash_node_t *pkt_trace_hash_list; 90 } pkt_trace_hash_info_t; 91 92 STATIC pkt_trace_hash_info_t *pkt_trace_hash_info[BCM_MAX_NUM_UNITS]; 93 94 /* 95 * Function: 96 * _bcm_esw_pkt_trace_dop_data_swap 97 * Purpose: 98 * dop data swap 99 * Parameters: 100 * IN : unit 101 * Returns: 102 * BCM_E_XXX 103 */ 104 STATIC 105 int _bcm_esw_pkt_trace_dop_data_swap(int unit, 106 uint32 src_word_len, 107 uint32 *src, 108 uint32 *dst) 109 { 110 int i = 0; 111 112 if ((src == NULL) 113 || (dst == NULL)){ 114 return BCM_E_INTERNAL; 115 } 116 117 for (i = 0; i < src_word_len; i++) { 118 *(dst + (src_word_len - 1) - i) = *src++; 119 } 120 121 return BCM_E_NONE; 122 } 123 124 /* 125 * Function: 126 * _bcm_td3_pkt_trace_info_dop_init 127 * Purpose: 128 * Initialize the td3 packet trace. 129 * DOP's 130 * Parameters: 131 * IN : unit 132 * Returns: 133 * BCM_E_XXX 134 */ 135 STATIC 136 int _bcm_td3_pkt_trace_dop_init(int unit, 137 uint32 block, 138 uint32 dop_id_start) 139 { 140 /* initialize the DOP */ 141 uint32 i = 0; 142 soc_reg_t ing_dop_ctrl_0[3] = {ING_DOP_CTRL_0_64r, 143 ING_DOP_CTRL_0_64_PIPE0r, 144 ING_DOP_CTRL_0_64_PIPE1r}; 145 soc_reg_t egr_dop_ctrl_0[3] = {EGR_DOP_CTRL_0_64r, 146 EGR_DOP_CTRL_0_64_PIPE0r, 147 EGR_DOP_CTRL_0_64_PIPE1r}; 148 soc_reg_t ing_dop_ctrl_2[3] = {ING_DOP_CTRL_2_64r, 149 ING_DOP_CTRL_2_64_PIPE0r, 150 ING_DOP_CTRL_2_64_PIPE1r}; 151 soc_reg_t egr_dop_ctrl_2[3] = {EGR_DOP_CTRL_2_64r, 152 EGR_DOP_CTRL_2_64_PIPE0r, 153 EGR_DOP_CTRL_2_64_PIPE1r}; 154 155 uint64 irval; 156 uint64 erval; 157 switch (block) { 158 case DOP_INGRESS: 159 for (i = 0; i < (NUM_PIPE(unit) + 1); i++) { 160 /* DOP BASE set for Ingress DOPs*/ 161 sal_memset(&irval, 0, sizeof(irval)); 162 BCM_IF_ERROR_RETURN( 163 soc_reg64_get(unit, ing_dop_ctrl_2[i], 164 REG_PORT_ANY, 0, &irval)); 165 soc_reg64_field32_set(unit, ing_dop_ctrl_2[i], 166 &irval, DOP_IDf, dop_id_start); 167 soc_reg64_field32_set(unit, ing_dop_ctrl_2[i], 168 &irval, NUM_DOPSf, MAX_ING_DOP_FORMATS(unit)); 169 BCM_IF_ERROR_RETURN( 170 soc_reg64_set(unit, ing_dop_ctrl_2[i], 171 REG_PORT_ANY, 0, irval)); 172 sal_memset(&irval, 0, sizeof(irval)); 173 BCM_IF_ERROR_RETURN( 174 soc_reg64_get(unit, ing_dop_ctrl_0[i], 175 REG_PORT_ANY, 0, &irval)); 176 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 177 &irval, CAPTURE_MODEf, 0 /* capture_first*/); 178 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 179 &irval, COMMANDf, 1/* init*/); 180 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 181 &irval, STARTf, 1 /* start */); 182 BCM_IF_ERROR_RETURN( 183 soc_reg64_set(unit, ing_dop_ctrl_0[i], 184 REG_PORT_ANY, 0, irval)); 185 } 186 break; 187 case DOP_EGRESS: 188 for (i = 0; i < (NUM_PIPE(unit) + 1); i++) { 189 /* DOP BASE set for Egress DOP's */ 190 sal_memset(&erval, 0, sizeof(erval)); 191 BCM_IF_ERROR_RETURN( 192 soc_reg64_get(unit, egr_dop_ctrl_2[i], 193 REG_PORT_ANY, 0, &erval)); 194 soc_reg64_field32_set(unit, egr_dop_ctrl_2[i], 195 &erval, DOP_IDf, dop_id_start); 196 soc_reg64_field32_set(unit, egr_dop_ctrl_2[i], 197 &erval, NUM_DOPSf, MAX_EGR_DOP_FORMATS(unit)); 198 BCM_IF_ERROR_RETURN( 199 soc_reg64_set(unit, egr_dop_ctrl_2[i], 200 REG_PORT_ANY, 0, erval)); 201 sal_memset(&erval, 0, sizeof(erval)); 202 BCM_IF_ERROR_RETURN( 203 soc_reg64_get(unit, egr_dop_ctrl_0[i], 204 REG_PORT_ANY, 0, &erval)); 205 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 206 &erval, COMMANDf, 1/* init*/); 207 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 208 &erval, STARTf, 1 /* start */); 209 BCM_IF_ERROR_RETURN( 210 soc_reg64_set(unit, egr_dop_ctrl_0[i], 211 REG_PORT_ANY, 0, erval)); 212 } 213 break; 214 default: 215 break; 216 } 217 return BCM_E_NONE; 218 } 219 220 #if 0 221 /* 222 * Function: 223 * _bcm_td3_pkt_trace_info_dop_capture 224 * Purpose: 225 * Capture on the td3 packet trace 226 * DOP's 227 * Parameters: 228 * IN : unit 229 * Returns: 230 * BCM_E_XXX 231 */ 232 STATIC 233 int _bcm_td3_pkt_trace_dop_capture(int unit, uint32 block) 234 { 235 /* initialize the DOP */ 236 uint32 i = 0; 237 soc_reg_t ing_dop_ctrl_0[3] = {ING_DOP_CTRL_0_64r, 238 ING_DOP_CTRL_0_64_PIPE0r, 239 ING_DOP_CTRL_0_64_PIPE1r}; 240 241 soc_reg_t egr_dop_ctrl_0[3] = {EGR_DOP_CTRL_0_64r, 242 EGR_DOP_CTRL_0_64_PIPE0r, 243 EGR_DOP_CTRL_0_64_PIPE1r}; 244 uint64 irval; 245 uint64 erval; 246 247 switch (block) { 248 case DOP_INGRESS: 249 for (i = 0; i < 3 ; i++) { 250 sal_memset(&irval, 0, sizeof(irval)); 251 BCM_IF_ERROR_RETURN( 252 soc_reg64_get(unit, ing_dop_ctrl_0[i], 253 REG_PORT_ANY, 0, &irval)); 254 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 255 &irval, CAPTURE_MODEf, 1 /* capture_first*/); 256 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 257 &irval, STARTf, 1 /* start */); 258 BCM_IF_ERROR_RETURN( 259 soc_reg64_set(unit, ing_dop_ctrl_0[i], 260 REG_PORT_ANY, 0, irval)); 261 } 262 break; 263 case DOP_EGRESS: 264 for (i = 0; i < 3 ; i++) { 265 sal_memset(&erval, 0, sizeof(erval)); 266 BCM_IF_ERROR_RETURN( 267 soc_reg64_get(unit, egr_dop_ctrl_0[0], 268 REG_PORT_ANY, 0, &erval)); 269 soc_reg64_field32_set(unit, egr_dop_ctrl_0[1], 270 &erval, CAPTURE_MODEf, 1 /* capture_first*/); 271 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 272 &irval, STARTf, 1 /* start */); 273 BCM_IF_ERROR_RETURN( 274 soc_reg64_set(unit, egr_dop_ctrl_0[i], 275 REG_PORT_ANY, 0, erval)); 276 } 277 break; 278 default: 279 break; 280 } 281 return BCM_E_NONE; 282 283 } 284 #endif 285 286 /* 287 * Function: 288 * _bcm_td3_pkt_trace_info_dop_reset 289 * Purpose: 290 * Reset the td3 packet trace 291 * DOP's 292 * Parameters: 293 * IN : unit 294 * Returns: 295 * BCM_E_XXX 296 */ 297 STATIC 298 int _bcm_td3_pkt_trace_dop_reset(int unit, uint32 block) 299 { 300 /* initialize the DOP */ 301 soc_reg_t ing_dop_ctrl_0[3] = {ING_DOP_CTRL_0_64r, 302 ING_DOP_CTRL_0_64_PIPE0r, 303 ING_DOP_CTRL_0_64_PIPE1r}; 304 soc_reg_t egr_dop_ctrl_0[3] = {EGR_DOP_CTRL_0_64r, 305 EGR_DOP_CTRL_0_64_PIPE0r, 306 EGR_DOP_CTRL_0_64_PIPE1r}; 307 308 uint32 i = 0; 309 uint64 irval; 310 uint64 erval; 311 switch (block) { 312 case DOP_INGRESS: 313 for (i = 0; i < (NUM_PIPE(unit) + 1); i++) { 314 sal_memset(&irval, 0, sizeof(irval)); 315 BCM_IF_ERROR_RETURN( 316 soc_reg64_get(unit, ing_dop_ctrl_0[i], 317 REG_PORT_ANY, 0, &irval)); 318 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 319 &irval, CAPTURE_MODEf, 0 /* capture_first*/); 320 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 321 &irval, COMMANDf, 0 /* reset*/); 322 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 323 &irval, STARTf, 0 /* start */); 324 BCM_IF_ERROR_RETURN( 325 soc_reg64_set(unit, ing_dop_ctrl_0[i], 326 REG_PORT_ANY, 0, irval)); 327 } 328 break; 329 case DOP_EGRESS: 330 for (i = 0; i < (NUM_PIPE(unit) + 1); i++) { 331 sal_memset(&erval, 0, sizeof(erval)); 332 BCM_IF_ERROR_RETURN( 333 soc_reg64_get(unit, egr_dop_ctrl_0[i], 334 REG_PORT_ANY, 0, &erval)); 335 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 336 &erval, COMMANDf, 0 /*reset*/); 337 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 338 &erval, STARTf, 0 /* start */); 339 BCM_IF_ERROR_RETURN( 340 soc_reg64_set(unit, egr_dop_ctrl_0[i], 341 REG_PORT_ANY, 0, erval)); 342 } 343 break; 344 default: 345 break; 346 } 347 return BCM_E_NONE; 348 349 } 350 351 /* 352 * Function: 353 * _bcm_td3_pkt_trace_info_dop_collect 354 * Purpose: 355 * Collect the td3 packet trace 356 * DOP's 357 * Parameters: 358 * IN : unit 359 * Returns: 360 * BCM_E_XXX 361 */ 362 STATIC 363 int _bcm_td3_pkt_trace_dop_collect(int unit, 364 uint32 block) 365 { 366 /* initialize the DOP */ 367 soc_reg_t ing_dop_ctrl_0[3] = {ING_DOP_CTRL_0_64r, 368 ING_DOP_CTRL_0_64_PIPE0r, 369 ING_DOP_CTRL_0_64_PIPE1r}; 370 soc_reg_t egr_dop_ctrl_0[3] = {EGR_DOP_CTRL_0_64r, 371 EGR_DOP_CTRL_0_64_PIPE0r, 372 EGR_DOP_CTRL_0_64_PIPE1r}; 373 uint32 i = 0; 374 uint64 irval; 375 uint64 erval; 376 377 switch (block) { 378 case DOP_INGRESS: 379 for (i = 0; i < (NUM_PIPE(unit) + 1); i++) { 380 sal_memset(&irval, 0, sizeof(irval)); 381 BCM_IF_ERROR_RETURN( 382 soc_reg64_get(unit, ing_dop_ctrl_0[i], 383 REG_PORT_ANY, 0, &irval)); 384 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 385 &irval, CAPTURE_MODEf, 0 /* capture_first*/); 386 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 387 &irval, COMMANDf, 3/* collect*/); 388 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 389 &irval, STARTf, 1 /* start */); 390 BCM_IF_ERROR_RETURN( 391 soc_reg64_set(unit, ing_dop_ctrl_0[i], 392 REG_PORT_ANY, 0, irval)); 393 } 394 break; 395 case DOP_EGRESS: 396 for (i = 0; i < (NUM_PIPE(unit) + 1); i++) { 397 sal_memset(&erval, 0, sizeof(erval)); 398 BCM_IF_ERROR_RETURN( 399 soc_reg64_get(unit, egr_dop_ctrl_0[i], 400 REG_PORT_ANY, 0, &erval)); 401 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 402 &erval, CAPTURE_MODEf, 0 /* capture_first*/); 403 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 404 &erval, COMMANDf, 3/* collect*/); 405 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 406 &erval, STARTf, 1 /* start */); 407 BCM_IF_ERROR_RETURN( 408 soc_reg64_set(unit, egr_dop_ctrl_0[i], 409 REG_PORT_ANY, 0, erval)); 410 } 411 break; 412 default: 413 break; 414 } 415 return BCM_E_NONE; 416 } 417 418 /* 419 * Function: 420 * _bcm_td3_pkt_trace_info_dop_ 421 * Purpose: 422 * Clear the td3 packet trace 423 * DOP's 424 * Parameters: 425 * IN : unit 426 * Returns: 427 * BCM_E_XXX 428 */ 429 STATIC 430 int _bcm_td3_pkt_trace_dop_clear(int unit, uint32 block) 431 { 432 /* initialize the DOP */ 433 soc_reg_t ing_dop_ctrl_0[3] = {ING_DOP_CTRL_0_64r, 434 ING_DOP_CTRL_0_64_PIPE0r, 435 ING_DOP_CTRL_0_64_PIPE1r}; 436 soc_reg_t egr_dop_ctrl_0[3] = {EGR_DOP_CTRL_0_64r, 437 EGR_DOP_CTRL_0_64_PIPE0r, 438 EGR_DOP_CTRL_0_64_PIPE1r}; 439 uint32 i = 0; 440 uint64 irval; 441 uint64 erval; 442 443 switch (block) { 444 case DOP_INGRESS: 445 for (i = 0; i < (NUM_PIPE(unit) + 1); i++) { 446 sal_memset(&irval, 0, sizeof(irval)); 447 BCM_IF_ERROR_RETURN( 448 soc_reg64_get(unit, ing_dop_ctrl_0[i], 449 REG_PORT_ANY, 0, &irval)); 450 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 451 &irval, COMMANDf, 2/* clear*/); 452 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 453 &irval, CAPTURE_MODEf, 0 /* capture_first*/); 454 soc_reg64_field32_set(unit, ing_dop_ctrl_0[i], 455 &irval, STARTf, 1 /* start */); 456 BCM_IF_ERROR_RETURN( 457 soc_reg64_set(unit, ing_dop_ctrl_0[i], 458 REG_PORT_ANY, 0, irval)); 459 } 460 break; 461 case DOP_EGRESS: 462 for (i = 0; i < (NUM_PIPE(unit) + 1); i++) { 463 sal_memset(&erval, 0, sizeof(erval)); 464 BCM_IF_ERROR_RETURN( 465 soc_reg64_get(unit, egr_dop_ctrl_0[i], 466 REG_PORT_ANY, 0, &erval)); 467 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 468 &erval, COMMANDf, 2/* clear*/); 469 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 470 &erval, STARTf, 1 /* start */); 471 soc_reg64_field32_set(unit, egr_dop_ctrl_0[i], 472 &erval, CAPTURE_MODEf, 473 0 /* capture_start*/); 474 BCM_IF_ERROR_RETURN( 475 soc_reg64_set(unit, egr_dop_ctrl_0[i], 476 REG_PORT_ANY, 0, erval)); 477 } 478 break; 479 default: 480 break; 481 } 482 return BCM_E_NONE; 483 } 484 485 486 487 /* 488 * Function: 489 * _bcm_td3_pkt_trace_dop_buffer_collecct 490 * Purpose: 491 * read results ptr buffer for 492 * visibility packet process and 493 * store into pkt_trace_info 494 * Parameters: 495 * IN : unit 496 * Returns: 497 * BCM_E_XXX 498 */ 499 int _bcm_td3_pkt_trace_dop_buffer_collect(int unit, 500 uint32 block, 501 uint32 buf_size, 502 uint32 *buf, 503 uint32 *data_size) 504 { 505 soc_mem_t mem = INVALIDm; 506 uint32 mem_idx_min = 0; 507 uint32 mem_idx_max = 0; 508 uint32 dop_index = 0; 509 uint32 *tmp_buf = NULL; 510 int rv = BCM_E_NONE; 511 uint32 dop_data[BCM_PKT_TRC_DOP_DATA_WORD_LEN]; 512 uint32 data[BCM_PKT_TRC_DOP_DATA_WORD_LEN]; 513 uint32 *dop_entry_ptr = NULL; 514 int pipe = 0; 515 516 LOG_VERBOSE(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 517 "Packet trace buffer collect"))); 518 519 pipe = td3_pkt_trace_port_info[unit].pkt_trace_src_pipe; 520 521 if ((buf == NULL) || 522 (buf_size == 0) || 523 (data_size == NULL)) { 524 return BCM_E_INTERNAL; 525 } 526 if ((pipe != DOP_PIPE_0) && 527 (pipe != DOP_PIPE_1)) { 528 return BCM_E_PARAM; 529 } 530 *data_size = 0; 531 if (block == DOP_INGRESS) { 532 if (pipe == DOP_PIPE_0) { 533 mem = ING_DOP_STORAGE_MEM_PIPE0m; 534 } else if (pipe == DOP_PIPE_1) { 535 mem = ING_DOP_STORAGE_MEM_PIPE1m; 536 } 537 } else if (block == DOP_EGRESS) { 538 if (pipe == DOP_PIPE_0) { 539 mem = EGR_DOP_STORAGE_MEM_PIPE0m; 540 } else if (pipe == DOP_PIPE_1) { 541 mem = EGR_DOP_STORAGE_MEM_PIPE1m; 542 } 543 } else { 544 return BCM_E_PARAM; 545 } 546 mem_idx_min = soc_mem_index_min(unit, mem); 547 mem_idx_max = soc_mem_index_max(unit, mem); 548 549 tmp_buf = (uint32 *) soc_cm_salloc(unit, buf_size, 550 "dop buffer collect"); 551 if (tmp_buf == NULL) { 552 return BCM_E_MEMORY; 553 } 554 sal_memset(tmp_buf, 0, buf_size); 555 556 /*Reading the whole chunk */ 557 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 558 mem_idx_min, mem_idx_max, buf); 559 560 if (BCM_FAILURE(rv)) { 561 goto clean_up; 562 } 563 for (dop_index = 0; dop_index <= mem_idx_max; dop_index++) { 564 dop_entry_ptr = soc_mem_table_idx_to_pointer(unit, mem, uint32 *, 565 buf, dop_index); 566 soc_mem_field_get(unit, mem, dop_entry_ptr, DATAf, data); 567 _bcm_esw_pkt_trace_dop_data_swap(unit, 568 BCM_PKT_TRC_DOP_DATA_WORD_LEN, 569 data, 570 dop_data); 571 sal_memcpy((tmp_buf + (dop_index * BCM_PKT_TRC_DOP_DATA_WORD_LEN)), 572 dop_data, sizeof(dop_data)); 573 *data_size += (BCM_PKT_TRC_DOP_DATA_WORD_LEN * (sizeof(uint32))); 574 } 575 sal_memset(buf, 0, buf_size); 576 sal_memcpy(buf, tmp_buf, *data_size); 577 clean_up: 578 if (tmp_buf != NULL) { 579 soc_cm_sfree(unit, tmp_buf); 580 } 581 return rv; 582 } 583 584 /* 585 * Function: 586 * _bcm_pkt_trace_format_hash_key_get 587 * Purpose: 588 * DOP parsing. 589 * Parameters: 590 * IN : unit 591 * Returns: 592 * BCM_E_XXX 593 */ 594 STATIC 595 int _bcm_pkt_trace_format_hash_key_get(int unit, 596 soc_format_t format, 597 uint32 *key) 598 { 599 uint32 num_dops = MAX_DOP_FORMATS(unit); 600 if (key == NULL) { 601 return BCM_E_INTERNAL; 602 } 603 *key = (1 * format) % num_dops; 604 return BCM_E_NONE; 605 } 606 607 STATIC 608 uint32 _bcm_td3_dop_format_field_get(int unit, 609 soc_format_t format, 610 soc_field_t field, 611 uint32 *fldbuf) 612 { 613 pkt_trace_hash_info_t *ph = NULL; 614 pkt_trace_hash_node_t *hash_node = NULL; 615 pkt_trace_hash_node_t *hash_list = NULL; 616 pkt_trace_dop_format_t *fptr = NULL; 617 uint32 entry[SOC_MAX_MEM_WORDS]; 618 uint32 key; 619 620 ph = pkt_trace_hash_info[unit]; 621 if (ph->pkt_trace_hash_list == NULL) { 622 return BCM_E_INTERNAL; 623 } 624 hash_list = ph->pkt_trace_hash_list; 625 626 BCM_IF_ERROR_RETURN( 627 _bcm_pkt_trace_format_hash_key_get(unit, 628 format, &key)); 629 630 if (key >= MAX_DOP_FORMATS(unit)) { 631 return BCM_E_INTERNAL; 632 } 633 634 hash_node = &hash_list[key]; 635 636 if ((!hash_node->entry_num) || 637 (hash_node->ft_entry == NULL)) { 638 return BCM_E_PARAM; 639 } 640 sal_memset(entry, 0, sizeof(entry)); 641 for(fptr = hash_node->ft_entry; 642 fptr != NULL; 643 fptr = (pkt_trace_dop_format_t *) fptr->next) { 644 if (fptr->format == format) { 645 sal_memcpy(entry, fptr->entry, 646 WORDS2BYTES(fptr->data_phases)); 647 soc_format_field_get(unit, format, 648 entry, 649 field, 650 fldbuf); 651 return BCM_E_NONE; 652 } 653 } 654 return BCM_E_NOT_FOUND; 655 } 656 657 STATIC 658 uint32 _bcm_td3_dop_format_field32_get(int unit, 659 soc_format_t format, 660 soc_field_t field) 661 { 662 pkt_trace_hash_info_t *ph = NULL; 663 pkt_trace_hash_node_t *hash_node = NULL; 664 pkt_trace_hash_node_t *hash_list = NULL; 665 pkt_trace_dop_format_t *fptr = NULL; 666 uint32 entry[SOC_MAX_MEM_WORDS]; 667 uint32 key; 668 uint32 value = 0; 669 670 ph = pkt_trace_hash_info[unit]; 671 if (ph->pkt_trace_hash_list == NULL) { 672 return BCM_E_INTERNAL; 673 } 674 hash_list = ph->pkt_trace_hash_list; 675 676 677 BCM_IF_ERROR_RETURN( 678 _bcm_pkt_trace_format_hash_key_get(unit, 679 format, &key)); 680 681 if (key >= MAX_DOP_FORMATS(unit)) { 682 return 0; 683 } 684 hash_node = &hash_list[key]; 685 686 if ((!hash_node->entry_num) || 687 (hash_node->ft_entry == NULL)) { 688 return 0; 689 } 690 sal_memset(entry, 0, sizeof(entry)); 691 for(fptr = hash_node->ft_entry; 692 fptr != NULL; 693 fptr = (pkt_trace_dop_format_t *) fptr->next) { 694 if (fptr->format == format) { 695 sal_memcpy(entry, fptr->entry, 696 WORDS2BYTES(fptr->data_phases)); 697 value = soc_format_field32_get(unit, 698 format, entry, field); 699 break; 700 } 701 } 702 703 return value; 704 } 705 706 STATIC 707 int _bcm_td3_pkt_trace_flow_type_get(int unit) 708 709 { 710 uint32 pkt_flow_id = 0; 711 uint32 flow_type_fixed = 0; 712 713 pkt_flow_id = 714 _bcm_td3_dop_format_field32_get(unit, 715 PKT_FLOW_SELECT_TCAM_1_DOP_DOPfmt, 716 PKT_FLOW_ID_1f); 717 flow_type_fixed = soc_format_field32_get(unit, PKT_FLOW_ID_1_FORMATfmt, 718 &pkt_flow_id, 719 MACRO_FLOW_ID_FIXEDf); 720 if (_BCM_PKT_TRACE_FLOW_TYPE_FIXED(flow_type_fixed)) { 721 return flow_type_fixed; 722 } 723 return FALSE; 724 } 725 726 #if defined(INCLUDE_L3) 727 STATIC 728 int _bcm_td3_pkt_trace_nh_dvp_get(int unit, 729 uint32 nh, 730 uint32 *dvp) 731 732 { 733 uint32 vp = 0; 734 uint32 nh_index = 0; 735 ing_dvp_table_entry_t dvp_entry; 736 737 sal_memset(&dvp_entry, 0, sizeof(ing_dvp_table_entry_t)); 738 739 if (dvp == NULL) { 740 return BCM_E_PARAM; 741 } 742 *dvp = 0; 743 for (vp = 0; 744 vp < soc_mem_index_count(unit, SOURCE_VPm); 745 vp++) { 746 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeAny)) { 747 BCM_IF_ERROR_RETURN( 748 READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, 749 vp, &dvp_entry)); 750 nh_index = soc_ING_DVP_TABLEm_field32_get( 751 unit, &dvp_entry, 752 NEXT_HOP_INDEXf); 753 if (nh_index == nh) { 754 *dvp = vp; 755 return BCM_E_NONE; 756 } 757 } 758 } 759 return BCM_E_NOT_FOUND; 760 } 761 #endif /* INCLUDE_L3 */ 762 763 /* 764 * Function: 765 * _bcm_td3_pkt_trace_lookup_status_get 766 * Purpose: 767 * Lookup status processing 768 * Parameters: 769 * IN : unit 770 * Returns: 771 * BCM_E_XXX 772 */ 773 STATIC 774 int _bcm_td3_pkt_trace_lookup_status_get(int unit, 775 bcm_switch_pkt_trace_info_t *pkt_trace_info) 776 { 777 uint32 pkt_flow_type_fixed = FALSE; 778 uint32 ifp_lookup_vec = 0; 779 780 pkt_flow_type_fixed = _bcm_td3_pkt_trace_flow_type_get(unit); 781 782 if (pkt_flow_type_fixed) { 783 if (pkt_flow_type_fixed == bcmPktFlowIdFixedTunnelMpls) { 784 if (_bcm_td3_dop_format_field32_get(unit, 785 ING_TUNNEL_ADAPT_2_DOPfmt, 786 HIT_0f)) { 787 SHR_BITSET( 788 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 789 bcmSwitchPktTraceLookupMplsLabel1Hit); 790 } 791 if (_bcm_td3_dop_format_field32_get(unit, 792 ING_TUNNEL_ADAPT_2_DOPfmt, 793 HIT_1f)) { 794 SHR_BITSET( 795 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 796 bcmSwitchPktTraceLookupMplsLabel2Hit); 797 } 798 } else { 799 if (_bcm_td3_dop_format_field32_get(unit, 800 ING_TUNNEL_ADAPT_1_DOPfmt, 801 HIT_0f)) { 802 SHR_BITSET( 803 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 804 bcmSwitchPktTraceLookupFirstVlanTranslationHit); 805 } 806 if (_bcm_td3_dop_format_field32_get(unit, 807 ING_TUNNEL_ADAPT_1_DOPfmt, 808 HIT_1f)) { 809 SHR_BITSET( 810 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 811 bcmSwitchPktTraceLookupSecondVlanTranslationHit); 812 } 813 } 814 if (_bcm_td3_dop_format_field32_get(unit, 815 ING_TUNNEL_ADAPT_2_DOPfmt, 816 HIT_0f)) { 817 SHR_BITSET( 818 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 819 bcmSwitchPktTraceLookupMplsLabel1Hit); 820 } 821 if (_bcm_td3_dop_format_field32_get(unit, 822 ING_TUNNEL_ADAPT_2_DOPfmt, 823 HIT_1f)) { 824 SHR_BITSET( 825 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 826 bcmSwitchPktTraceLookupMplsLabel2Hit); 827 } 828 if (_bcm_td3_dop_format_field32_get(unit, 829 ING_TUNNEL_ADAPT_3_LKUP_DOPfmt, 830 HITf)) { 831 SHR_BITSET( 832 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 833 bcmSwitchPktTraceLookupIpTunnelHit); 834 } 835 } 836 /******************************************************************** 837 NOTE : FORWARDING_1_LKUP_DOP.HIT0/1 838 FORWARDING_2_LKUP_DOP.HIT0/1 839 FORWARDING_3_LKUP_DOP.HIT0/1 840 TD3-3732 look for INDEX_0/1 ! = 0 for HIT. 841 */ 842 if (_bcm_td3_dop_format_field32_get(unit, 843 RSEL1_3_DOPfmt, 844 FORWARD_1_LKUP_1_VALIDf)){ 845 SHR_BITSET( 846 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 847 bcmSwitchPktTraceLookupL2SrcHit); 848 } 849 if (_bcm_td3_dop_format_field32_get(unit, 850 RSEL1_3_DOPfmt, 851 FORWARD_1_LKUP_0_VALIDf)){ 852 SHR_BITSET( 853 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 854 bcmSwitchPktTraceLookupL2DstHit); 855 } 856 if (_bcm_td3_dop_format_field32_get(unit, 857 L2_USER_ENTRY_DOPfmt, 858 HITf) != 0) { 859 SHR_BITSET( 860 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 861 bcmSwitchPktTraceLookupL2CacheHit); 862 } 863 if (_bcm_td3_dop_format_field32_get(unit, 864 RSEL1_3_DOPfmt, 865 FORWARD_2_LKUP_1_VALIDf)){ 866 SHR_BITSET( 867 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 868 bcmSwitchPktTraceLookupL3SrcHostHit); 869 } 870 if (_bcm_td3_dop_format_field32_get(unit, 871 RSEL1_3_DOPfmt, 872 FORWARD_2_LKUP_0_VALIDf)){ 873 SHR_BITSET( 874 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 875 bcmSwitchPktTraceLookupL3DestHostHit); 876 } 877 if (_bcm_td3_dop_format_field32_get(unit, 878 RSEL1_3_DOPfmt, 879 FORWARD_3_LKUP_0_VALIDf)){ 880 SHR_BITSET( 881 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 882 bcmSwitchPktTraceLookupL3DestRouteHit); 883 } 884 if (_bcm_td3_dop_format_field32_get(unit, 885 MY_STATION_TCAM_VAL_DOPfmt, 886 HITf)) { 887 SHR_BITSET( 888 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 889 bcmSwitchPktTraceLookupMystationHit); 890 } 891 ifp_lookup_vec = _bcm_td3_dop_format_field32_get(unit, 892 IFP_LOOKUP_STATUS_VECTOR_DOPfmt, 893 IFP_LOOKUP_STATUS_VECTORf); 894 895 if (ifp_lookup_vec & 896 (1U << bcmSwitchPktTraceLookupL2DstHit)) { 897 SHR_BITSET( 898 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 899 bcmSwitchPktTraceLookupL2DstHit); 900 } 901 902 if (ifp_lookup_vec & 903 (1U << bcmSwitchPktTraceLookupForwardingVlanValid)) { 904 SHR_BITSET( 905 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 906 bcmSwitchPktTraceLookupForwardingVlanValid); 907 } 908 if (ifp_lookup_vec & 909 (1U << bcmSwitchPktTraceLookupL2SrcStatic)) { 910 SHR_BITSET( 911 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 912 bcmSwitchPktTraceLookupL2SrcStatic); 913 } 914 if (ifp_lookup_vec & 915 (1U << bcmSwitchPktTraceLookupL2CacheHit)) { 916 SHR_BITSET( 917 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 918 bcmSwitchPktTraceLookupL2CacheHit); 919 } 920 if (ifp_lookup_vec & 921 (1U << bcmSwitchPktTraceLookupL2SrcMiss)) { 922 SHR_BITSET( 923 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 924 bcmSwitchPktTraceLookupL2SrcMiss); 925 } 926 if (ifp_lookup_vec & 927 (1U << bcmSwitchPktTraceLookupDosAttack)) { 928 SHR_BITSET( 929 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 930 bcmSwitchPktTraceLookupDosAttack); 931 } 932 if (ifp_lookup_vec & 933 (1U << bcmSwitchPktTraceLookupMplsLabel1Hit)) { 934 SHR_BITSET( 935 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 936 bcmSwitchPktTraceLookupMplsLabel1Hit); 937 } 938 if (ifp_lookup_vec & 939 (1U << bcmSwitchPktTraceLookupMplsLabel2Hit)) { 940 SHR_BITSET( 941 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 942 bcmSwitchPktTraceLookupMplsLabel2Hit); 943 } 944 if (ifp_lookup_vec & 945 (1U << bcmSwitchPktTraceLookupMplsTerminated)) { 946 SHR_BITSET( 947 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 948 bcmSwitchPktTraceLookupMplsTerminated); 949 } 950 if (ifp_lookup_vec & 951 (1U << bcmSwitchPktTraceLookupSecondVlanTranslationHit)) { 952 SHR_BITSET( 953 (pkt_trace_info->pkt_trace_lookup_status.pkt_trace_status_bitmap), 954 bcmSwitchPktTraceLookupSecondVlanTranslationHit); 955 } 956 return BCM_E_NONE; 957 } 958 959 /* 960 * Function: 961 * _bcm_td3_pkt_trace_pkt_resolution_get 962 * Purpose: 963 * Packet Resolution processing 964 * Parameters: 965 * IN : unit 966 * Returns: 967 * BCM_E_XXX 968 */ 969 STATIC 970 int _bcm_td3_pkt_trace_pkt_resolution_get(int unit, 971 bcm_switch_pkt_trace_info_t *pkt_trace_info) 972 { 973 uint32 pkt_rsl = 0; 974 975 if (pkt_trace_info == NULL) { 976 return BCM_E_INTERNAL; 977 } 978 pkt_rsl = _bcm_td3_dop_format_field32_get(unit, 979 RSEL1_2_DOPfmt, 980 PKT_RESOLUTION_VECTORf); 981 982 pkt_trace_info->pkt_trace_resolution = pkt_rsl; 983 return BCM_E_NONE; 984 } 985 986 #if defined(INCLUDE_L3) 987 /* 988 * Function: 989 * _bcm_td3_pkt_trace_ecmp_resolution_get 990 * Purpose: 991 * ECMP Resolution processing 992 * Parameters: 993 * IN : unit 994 * Returns: 995 * BCM_E_XXX 996 */ 997 STATIC 998 int _bcm_td3_pkt_trace_ecmp_resolution_get(int unit, 999 bcm_switch_pkt_trace_info_t *pkt_trace_info) 1000 { 1001 uint16 ecmp_id_1 = 0; 1002 uint16 ecmp_id_2 = 0; 1003 uint16 ecmp_offset_1 = 0; 1004 uint16 ecmp_offset_2 = 0; 1005 uint16 ecmp_hash_val_1 = 0; 1006 uint16 ecmp_hash_val_2 = 0; 1007 uint32 ecmp_ptr = 0; 1008 uint32 ecmp_mem_index = 0; 1009 uint32 ecmp_flag = 0; 1010 uint32 nhop_ecmp_group = 0; 1011 uint32 destination = 0; 1012 uint8 count1 = 0; 1013 uint8 count2 = 0; 1014 uint8 nh_flag = 0; 1015 ecmp_count_entry_t ecmpc_entry; 1016 ecmp_entry_t ecmp_entry; 1017 uint32 first_ecmp_rsl = 0; 1018 uint32 second_ecmp_rsl = 0; 1019 1020 if (pkt_trace_info == NULL) { 1021 return BCM_E_INTERNAL; 1022 } 1023 /* ECMP GROUP 1 */ 1024 ecmp_id_1 = _bcm_td3_dop_format_field32_get(unit, 1025 RSEL2_FIRST_ECMP_DOPfmt, 1026 ECMP1_GROUPf); 1027 1028 ecmp_hash_val_1 = _bcm_td3_dop_format_field32_get(unit, 1029 RSEL2_FIRST_ECMP_DOPfmt, 1030 ECMP1_HASH_VALUEf); 1031 1032 first_ecmp_rsl = _bcm_td3_dop_format_field32_get(unit, 1033 RSEL2_FIRST_ECMP_DOPfmt, 1034 FIRST_ECMP_RESOLUTION_DONEf); 1035 /* ECMP GROUP 2 */ 1036 ecmp_id_2 = _bcm_td3_dop_format_field32_get(unit, 1037 RSEL2_SECOND_ECMP_DOPfmt, 1038 ECMP2_GROUPf); 1039 1040 ecmp_hash_val_2 = _bcm_td3_dop_format_field32_get(unit, 1041 RSEL2_SECOND_ECMP_DOPfmt, 1042 ECMP2_HASH_VALUEf); 1043 1044 second_ecmp_rsl = _bcm_td3_dop_format_field32_get(unit, 1045 RSEL2_SECOND_ECMP_DOPfmt, 1046 SECOND_ECMP_RESOLUTION_DONEf); 1047 /* ECMP ID 1 Resolution */ 1048 if (first_ecmp_rsl) { 1049 sal_memset(&ecmpc_entry, 0, sizeof(ecmpc_entry)); 1050 sal_memset(&ecmp_entry, 0, sizeof(ecmp_entry)); 1051 BCM_IF_ERROR_RETURN 1052 (READ_L3_ECMP_COUNTm(unit, MEM_BLOCK_ANY, 1053 ecmp_id_1, &ecmpc_entry)); 1054 1055 ecmp_ptr = soc_L3_ECMP_COUNTm_field32_get(unit, &ecmpc_entry, 1056 BASE_PTRf); 1057 count1 = soc_L3_ECMP_COUNTm_field32_get(unit, &ecmpc_entry, 1058 COUNTf); 1059 ecmp_offset_1 = ((ecmp_hash_val_1) % (count1 + 1)) & 1060 ((1 << (soc_format_field_length( 1061 unit, 1062 RSEL2_FIRST_ECMP_DOPfmt, 1063 ECMP1_OFFSETf))) -1) ; 1064 1065 ecmp_mem_index = (ecmp_ptr + ecmp_offset_1) & 1066 (soc_mem_index_count(unit, L3_ECMPm) - 1); 1067 1068 BCM_IF_ERROR_RETURN 1069 (READ_L3_ECMPm(unit, MEM_BLOCK_ANY, ecmp_mem_index, &ecmp_entry)); 1070 pkt_trace_info->pkt_trace_hash_info.ecmp_1_group = ecmp_id_1; 1071 pkt_trace_info->pkt_trace_hash_info.ecmp_1_group 1072 += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit); 1073 1074 /* ecmp_flag is set only when hierarchial ECMP */ 1075 destination = soc_L3_ECMPm_field32_get(unit, 1076 &ecmp_entry, DESTINATIONf); 1077 ecmp_flag = soc_format_field32_get(unit, DESTINATION_FORMATfmt, 1078 &destination, DEST_TYPE1f); 1079 nh_flag = soc_format_field32_get(unit, DESTINATION_FORMATfmt, 1080 &destination, DEST_TYPE0f); 1081 if (ecmp_flag == BCMI_TD3_DEST_TYPE1_ECMP) { 1082 nhop_ecmp_group = soc_format_field32_get(unit, 1083 DESTINATION_FORMATfmt, 1084 &destination, 1085 ECMP_GROUPf); 1086 pkt_trace_info->pkt_trace_hash_info.ecmp_1_egress = nhop_ecmp_group; 1087 } else { 1088 if (nh_flag == BCMI_TD3_DEST_TYPE0_NH) { 1089 pkt_trace_info->pkt_trace_hash_info.ecmp_1_egress = 1090 soc_format_field32_get( 1091 unit, 1092 DESTINATION_FORMATfmt, 1093 &destination, 1094 NEXT_HOP_INDEXf); 1095 } else { 1096 pkt_trace_info->pkt_trace_hash_info.ecmp_1_egress = 1097 soc_L3_ECMPm_field32_get( 1098 unit, 1099 &ecmp_entry, 1100 NEXT_HOP_INDEXf); 1101 } 1102 } 1103 1104 if (second_ecmp_rsl) { 1105 pkt_trace_info->pkt_trace_hash_info.ecmp_1_egress 1106 += BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit); 1107 } else { 1108 pkt_trace_info->pkt_trace_hash_info.ecmp_1_egress 1109 += BCM_XGS3_EGRESS_IDX_MIN(unit); 1110 } 1111 pkt_trace_info->pkt_trace_hash_info.flags 1112 += BCM_SWITCH_PKT_TRACE_ECMP_1; 1113 } 1114 1115 if (second_ecmp_rsl) { 1116 /* ECMP ID 2 Resolution */ 1117 sal_memset(&ecmpc_entry, 0, sizeof(ecmpc_entry)); 1118 sal_memset(&ecmp_entry, 0, sizeof(ecmp_entry)); 1119 ecmp_flag = 0; 1120 nh_flag = 0; 1121 destination = 0; 1122 BCM_IF_ERROR_RETURN 1123 (READ_L3_ECMP_COUNTm(unit, MEM_BLOCK_ANY, 1124 ecmp_id_2, &ecmpc_entry)); 1125 1126 ecmp_ptr = soc_L3_ECMP_COUNTm_field32_get(unit, &ecmpc_entry, 1127 BASE_PTRf); 1128 count2 = soc_L3_ECMP_COUNTm_field32_get(unit, &ecmpc_entry, 1129 COUNTf); 1130 ecmp_offset_2 = ((ecmp_hash_val_2) % (count2 + 1)) & 1131 ((1 << (soc_format_field_length( 1132 unit, 1133 RSEL2_SECOND_ECMP_DOPfmt, 1134 ECMP2_OFFSETf))) -1) ; 1135 1136 ecmp_mem_index = (ecmp_ptr + ecmp_offset_2) & 1137 (soc_mem_index_count(unit, L3_ECMPm) - 1); 1138 1139 BCM_IF_ERROR_RETURN 1140 (READ_L3_ECMPm(unit, MEM_BLOCK_ANY, ecmp_mem_index, &ecmp_entry)); 1141 1142 pkt_trace_info->pkt_trace_hash_info.ecmp_2_group = ecmp_id_2; 1143 pkt_trace_info->pkt_trace_hash_info.ecmp_2_group += 1144 BCM_XGS3_MPATH_EGRESS_IDX_MIN(unit); 1145 1146 destination = soc_L3_ECMPm_field32_get(unit, 1147 &ecmp_entry, DESTINATIONf); 1148 nh_flag = soc_format_field32_get(unit, DESTINATION_FORMATfmt, 1149 &destination, DEST_TYPE0f); 1150 if (nh_flag == BCMI_TD3_DEST_TYPE0_NH) { 1151 pkt_trace_info->pkt_trace_hash_info.ecmp_2_egress = 1152 soc_format_field32_get( 1153 unit, 1154 DESTINATION_FORMATfmt, 1155 &destination, 1156 NEXT_HOP_INDEXf); 1157 } else { 1158 pkt_trace_info->pkt_trace_hash_info.ecmp_2_egress = 1159 soc_L3_ECMPm_field32_get( 1160 unit, 1161 &ecmp_entry, 1162 NEXT_HOP_INDEXf); 1163 } 1164 1165 pkt_trace_info->pkt_trace_hash_info.ecmp_2_egress += 1166 BCM_XGS3_EGRESS_IDX_MIN(unit); 1167 pkt_trace_info->pkt_trace_hash_info.flags 1168 += BCM_SWITCH_PKT_TRACE_ECMP_2; 1169 } 1170 return BCM_E_NONE; 1171 } 1172 #endif 1173 1174 /* 1175 * Function: 1176 * _bcm_td3_pkt_trace_hg_trunk_resolution_get 1177 * Purpose: 1178 * HG TRUNK Resolution processing 1179 * Parameters: 1180 * IN : unit 1181 * Returns: 1182 * BCM_E_XXX 1183 */ 1184 STATIC 1185 int _bcm_td3_pkt_trace_hg_trunk_resolution_get(int unit, 1186 bcm_switch_pkt_trace_info_t *pkt_trace_info) 1187 { 1188 uint16 hg_rsl_done = 0; 1189 uint32 hg_hash_val = 0; 1190 uint32 hg_trunk_id = 0; 1191 1192 int tgid; 1193 uint32 trunk_base, trunk_group_size; 1194 uint32 trunk_index, trunk_member_table_index; 1195 bcm_module_t mod_id; 1196 bcm_port_t port_id; 1197 bcm_gport_t dst_member_port; 1198 _bcm_gport_dest_t dest; 1199 1200 hg_trunk_member_entry_t hg_trunk_member_entry; 1201 hg_trunk_group_entry_t hg_tg_entry; 1202 1203 bcm_trunk_chip_info_t chip_info; 1204 1205 1206 if (pkt_trace_info == NULL) { 1207 return BCM_E_INTERNAL; 1208 } 1209 1210 /* HIGIG TRUNK RESOLVE*/ 1211 hg_rsl_done = _bcm_td3_dop_format_field32_get(unit, 1212 HG_TRUNK_DOPfmt, 1213 INSTR_HG_TRUNK_RESOLUTION_DONEf); 1214 hg_hash_val = _bcm_td3_dop_format_field32_get(unit, 1215 HG_TRUNK_DOPfmt, 1216 INSTR_HG_TRUNK_HASHf); 1217 hg_trunk_id = _bcm_td3_dop_format_field32_get(unit, 1218 HG_TRUNK_DOPfmt, 1219 INSTR_HG_TRUNK_IDf); 1220 1221 if (hg_rsl_done) { 1222 tgid = hg_trunk_id; 1223 1224 BCM_IF_ERROR_RETURN(READ_HG_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tgid, &hg_tg_entry)); 1225 1226 trunk_group_size = soc_HG_TRUNK_GROUPm_field32_get(unit, &hg_tg_entry, TG_SIZEf); 1227 trunk_base = soc_HG_TRUNK_GROUPm_field32_get(unit, &hg_tg_entry, BASE_PTRf); 1228 trunk_index = hg_hash_val % (trunk_group_size + 1); 1229 trunk_member_table_index = (trunk_base + trunk_index) & 0xff; 1230 1231 BCM_IF_ERROR_RETURN(READ_HG_TRUNK_MEMBERm(unit, MEM_BLOCK_ANY, 1232 trunk_member_table_index, &hg_trunk_member_entry)); 1233 port_id = soc_HG_TRUNK_MEMBERm_field32_get(unit, 1234 &hg_trunk_member_entry, PORT_NUMf); 1235 1236 if (BCM_FAILURE(bcm_esw_stk_my_modid_get(unit, &mod_id))) { 1237 mod_id = 0; 1238 } 1239 1240 BCM_IF_ERROR_RETURN 1241 (_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, mod_id, port_id, 1242 &(dest.modid), &(dest.port))); 1243 dest.gport_type = _SHR_GPORT_TYPE_DEVPORT; 1244 1245 BCM_IF_ERROR_RETURN(_bcm_esw_gport_construct(unit, &dest, &dst_member_port)); 1246 1247 BCM_IF_ERROR_RETURN(bcm_esw_trunk_chip_info_get(unit, &chip_info)); 1248 pkt_trace_info->pkt_trace_hash_info.fabric_trunk = 1249 tgid + chip_info.trunk_fabric_id_min; 1250 pkt_trace_info->pkt_trace_hash_info.fabric_trunk_member = 1251 dst_member_port; 1252 pkt_trace_info->pkt_trace_hash_info.flags += 1253 BCM_SWITCH_PKT_TRACE_FABRIC_TRUNK; 1254 1255 } /* end hg trunk resolution */ 1256 1257 return BCM_E_NONE; 1258 1259 } 1260 1261 /* 1262 * Function: 1263 * _bcm_td3_pkt_trace_ucast_lag_resolution_get 1264 * Purpose: 1265 * Unicast LAG Resolution processing 1266 i* Parameters: 1267 * IN : unit 1268 * Returns: 1269 * BCM_E_XXX 1270 */ 1271 STATIC 1272 int _bcm_td3_pkt_trace_ucast_lag_resolution_get(int unit, 1273 bcm_switch_pkt_trace_info_t *pkt_trace_info) 1274 { 1275 uint32 sw_dst; 1276 bcm_gport_t dgpp_gport; 1277 _bcm_gport_dest_t dest; 1278 uint16 pkt_opcode = 0; 1279 egr_gpp_attributes_modbase_entry_t modbase_entry; 1280 egr_gpp_attributes_entry_t egr_gpp_attributes; 1281 int base = -1; 1282 int egr_attr_index = -1; 1283 int is_trunk = -1; 1284 int tgid = -1; 1285 int mod_is_local = -1; 1286 1287 pkt_opcode = _bcm_td3_dop_format_field32_get(unit, 1288 RSEL2_3_DOPfmt, 1289 MH_OPCODEf); 1290 1291 sw_dst = _bcm_td3_dop_format_field32_get(unit, 1292 SW3_0_DOPfmt, 1293 SW3_DESTINATIONf); 1294 1295 if (pkt_opcode == BCM_PKT_OPCODE_UC) { 1296 dest.port = (sw_dst & BYTE_MASK); 1297 dest.modid = ((sw_dst >> BYTE_SHIFT) & BYTE_MASK); 1298 1299 BCM_IF_ERROR_RETURN( 1300 READ_EGR_GPP_ATTRIBUTES_MODBASEm(unit, 1301 MEM_BLOCK_ANY, 1302 dest.modid, 1303 &modbase_entry)); 1304 1305 1306 base = soc_EGR_GPP_ATTRIBUTES_MODBASEm_field32_get( 1307 unit, 1308 &modbase_entry, 1309 BASEf); 1310 1311 egr_attr_index = base + dest.port; 1312 1313 BCM_IF_ERROR_RETURN( 1314 READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 1315 egr_attr_index, 1316 &egr_gpp_attributes)); 1317 1318 is_trunk = soc_EGR_GPP_ATTRIBUTESm_field32_get( 1319 unit, 1320 &egr_gpp_attributes, 1321 ISTRUNKf); 1322 1323 if (is_trunk) { 1324 tgid = soc_EGR_GPP_ATTRIBUTESm_field32_get( 1325 unit, 1326 &egr_gpp_attributes, 1327 TGIDf); 1328 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 1329 BCM_IF_ERROR_RETURN 1330 (_bcm_esw_modid_is_local(unit, dest.modid, 1331 &mod_is_local)); 1332 if (mod_is_local) { 1333 if (IS_ST_PORT(unit, dest.port)) { 1334 dest.gport_type = _SHR_GPORT_TYPE_DEVPORT; 1335 } 1336 } 1337 BCM_IF_ERROR_RETURN(_bcm_esw_gport_construct(unit, &dest, &dgpp_gport)); 1338 pkt_trace_info->pkt_trace_hash_info.trunk = tgid; 1339 pkt_trace_info->pkt_trace_hash_info.trunk_member = dgpp_gport; 1340 pkt_trace_info->pkt_trace_hash_info.flags += BCM_SWITCH_PKT_TRACE_TRUNK; 1341 } 1342 } 1343 return BCM_E_NONE; 1344 } 1345 1346 #if defined(INCLUDE_L3) 1347 /* 1348 * Function: 1349 * _bcm_td3_pkt_trace_fwd_dst_resolution_get 1350 * Purpose: 1351 * Forward Destination Resolution processing 1352 * Parameters: 1353 * IN : unit 1354 * Returns: 1355 * BCM_E_XXX 1356 */ 1357 STATIC 1358 int _bcm_td3_pkt_trace_fwd_dst_resolution_get(int unit, 1359 bcm_switch_pkt_trace_info_t *pkt_trace_info) 1360 { 1361 uint16 pkt_opcode = 0; 1362 uint32 sw_dst; 1363 uint32 l2mc_index, l3mc_index; 1364 uint32 fwd_dst_type; 1365 uint32 l3_routed; 1366 bcm_multicast_t mc_group; 1367 uint32 dvp_nh_1; 1368 uint32 dvp_nh_sel_1; 1369 uint32 dvp_nh_2; 1370 uint32 dvp_nh_sel_2; 1371 bcm_gport_t dgpp_gport; 1372 bcm_module_t modid; 1373 bcm_port_t port; 1374 #if defined(INCLUDE_L3) 1375 uint32 dvp; 1376 bcm_gport_t dvp_gport; 1377 int rv = 0; 1378 #endif /* INCLUDE_L3 */ 1379 pkt_opcode = _bcm_td3_dop_format_field32_get(unit, 1380 RSEL2_3_DOPfmt, 1381 MH_OPCODEf); 1382 sw_dst = _bcm_td3_dop_format_field32_get(unit, 1383 SW3_0_DOPfmt, 1384 SW3_DESTINATIONf); 1385 fwd_dst_type = _bcm_td3_dop_format_field32_get(unit, 1386 SW3_0_DOPfmt, 1387 FORWARDING_TYPEf); 1388 if (fwd_dst_type >= TD3_FORWARDING_TYPE_L3UC) { 1389 l3_routed = 1; 1390 } else { 1391 l3_routed = 0; 1392 } 1393 1394 if (pkt_opcode == BCM_PKT_OPCODE_UC) { 1395 dvp_nh_1 = _bcm_td3_dop_format_field32_get(unit, 1396 RSEL2_FIRST_DVP_NHI_DOPfmt, 1397 DVP_NHIf); 1398 dvp_nh_sel_1 = _bcm_td3_dop_format_field32_get(unit, 1399 RSEL2_FIRST_DVP_NHI_DOPfmt, 1400 SELf); 1401 dvp_nh_2 = _bcm_td3_dop_format_field32_get(unit, 1402 RSEL2_SECOND_DVP_NHI_DOPfmt, 1403 DVP_NHIf); 1404 dvp_nh_sel_2 = _bcm_td3_dop_format_field32_get(unit, 1405 RSEL2_SECOND_DVP_NHI_DOPfmt, 1406 SELf); 1407 1408 port = (sw_dst & BYTE_MASK); 1409 modid = ((sw_dst >> BYTE_SHIFT) & BYTE_MASK); 1410 BCM_GPORT_MODPORT_SET(dgpp_gport, modid, port); 1411 pkt_trace_info->pkt_trace_fwd_dst_info.flags |= 1412 BCM_SWITCH_PKT_TRACE_FWD_DST_DGPP; 1413 pkt_trace_info->pkt_trace_fwd_dst_info.port = dgpp_gport; 1414 1415 if (l3_routed) { 1416 /**************** 1417 Present 1418 1. DGPP which is sw_dst 1419 3. NH1/NH2 which ever is valid. 1420 */ 1421 if ((dvp_nh_1 != 0) 1422 && (dvp_nh_sel_1)) { 1423 pkt_trace_info->pkt_trace_fwd_dst_info.egress_intf = 1424 dvp_nh_1 + BCM_XGS3_EGRESS_IDX_MIN(unit); 1425 pkt_trace_info->pkt_trace_fwd_dst_info.flags |= 1426 BCM_SWITCH_PKT_TRACE_FWD_DST_NH; 1427 } else if ((dvp_nh_2 != 0) 1428 && (dvp_nh_sel_2)) { 1429 pkt_trace_info->pkt_trace_fwd_dst_info.egress_intf = 1430 dvp_nh_2 + BCM_XGS3_EGRESS_IDX_MIN(unit); 1431 pkt_trace_info->pkt_trace_fwd_dst_info.flags |= 1432 BCM_SWITCH_PKT_TRACE_FWD_DST_NH; 1433 } 1434 1435 } else { 1436 #if defined(INCLUDE_L3) 1437 if ((dvp_nh_1 != 0) && 1438 (dvp_nh_sel_1)) { 1439 rv = _bcm_td3_pkt_trace_nh_dvp_get(unit, 1440 dvp_nh_1, &dvp); 1441 } else if ((dvp_nh_2 != 0) 1442 && (dvp_nh_sel_2)) { 1443 rv = _bcm_td3_pkt_trace_nh_dvp_get(unit, 1444 dvp_nh_2, &dvp); 1445 } 1446 if (BCM_SUCCESS(rv)) { 1447 _bcm_vp_encode_gport(unit, dvp, &dvp_gport); 1448 pkt_trace_info->pkt_trace_fwd_dst_info.flags |= 1449 BCM_SWITCH_PKT_TRACE_FWD_DST_DVP; 1450 pkt_trace_info->pkt_trace_fwd_dst_info.dvp = dvp_gport; 1451 } 1452 #endif /* INCLUDE_L3 */ 1453 } 1454 } else if (pkt_opcode == BCM_PKT_OPCODE_BC) { 1455 if (l3_routed) { 1456 pkt_trace_info->pkt_trace_fwd_dst_info.flags |= 1457 BCM_SWITCH_PKT_TRACE_FWD_DST_IPMC; 1458 _BCM_MULTICAST_GROUP_SET(mc_group, 1459 _BCM_MULTICAST_TYPE_L3,sw_dst); 1460 pkt_trace_info->pkt_trace_fwd_dst_info.mc_group = 1461 mc_group; 1462 } else { 1463 pkt_trace_info->pkt_trace_fwd_dst_info.flags |= 1464 BCM_SWITCH_PKT_TRACE_FWD_DST_VLAN; 1465 pkt_trace_info->pkt_trace_fwd_dst_info.fwd_vlan = 1466 sw_dst; 1467 } 1468 } else if (pkt_opcode == BCM_PKT_OPCODE_MC) { 1469 l2mc_index = _bcm_td3_dop_format_field32_get(unit, 1470 MC_INDICES_DOPfmt, 1471 L2MC_INDEXf); 1472 if (l2mc_index != 0) { 1473 /* valid l2mc index */ 1474 if (l2mc_index != sw_dst) { 1475 return BCM_E_INTERNAL; 1476 } 1477 pkt_trace_info->pkt_trace_fwd_dst_info.flags |= 1478 BCM_SWITCH_PKT_TRACE_FWD_DST_L2MC; 1479 _BCM_MULTICAST_GROUP_SET(mc_group, 1480 _BCM_MULTICAST_TYPE_L2, l2mc_index); 1481 pkt_trace_info->pkt_trace_fwd_dst_info.mc_group = 1482 mc_group; 1483 } 1484 } else if (pkt_opcode == BCM_PKT_OPCODE_IPMC) { 1485 l3mc_index = _bcm_td3_dop_format_field32_get(unit, 1486 MC_INDICES_DOPfmt, 1487 L3_IPMC_INDEXf); 1488 if (l3mc_index != 0) { 1489 /* valida l3mc index */ 1490 if (l3mc_index != sw_dst) { 1491 return BCM_E_INTERNAL; 1492 } 1493 pkt_trace_info->pkt_trace_fwd_dst_info.flags |= 1494 BCM_SWITCH_PKT_TRACE_FWD_DST_IPMC; 1495 _BCM_MULTICAST_GROUP_SET(mc_group, 1496 _BCM_MULTICAST_TYPE_L3, l3mc_index); 1497 pkt_trace_info->pkt_trace_fwd_dst_info.mc_group = 1498 mc_group; 1499 } 1500 } 1501 return BCM_E_NONE; 1502 } 1503 #endif /* INCLUDE_L3 */ 1504 1505 /* 1506 * Function: 1507 * _bcm_td3_pkt_trace_drop_reason_get 1508 * Purpose: 1509 * Drop Reason processing 1510 * Parameters: 1511 * IN : unit 1512 * Returns: 1513 * BCM_E_XXX 1514 */ 1515 STATIC 1516 int _bcm_td3_pkt_trace_drop_reason_get(int unit, 1517 bcm_switch_pkt_trace_info_t *pkt_trace_info) 1518 { 1519 uint32 tl_dp_v = 0; 1520 uint32 disc_dp_v = 0; 1521 uint32 vlan_dp_v = 0; 1522 uint32 c_v[4]; 1523 uint32 pkt_dp_v[4]; 1524 uint32 pre_coun_v = 0; 1525 uint32 pre_dp_v = 0; 1526 uint32 vx_dp_v = 0; 1527 uint32 rsel2_dp_v =0; 1528 1529 sal_memset(c_v, 0, sizeof(c_v)); 1530 sal_memset(pkt_dp_v, 0, sizeof(pkt_dp_v)); 1531 1532 _bcm_td3_dop_format_field_get(unit, 1533 COUNTER_UPDATE_VECTOR_DOPfmt, 1534 COUNTER_UPDATE_VECTORf, 1535 c_v); 1536 1537 soc_format_field_get(unit, 1538 INGRESS_COUNTER_UPDATE_VECTORfmt, 1539 c_v, 1540 PKT_PROC_DROP_VECTORf, 1541 pkt_dp_v); 1542 1543 pre_coun_v = soc_format_field32_get(unit, 1544 INGRESS_COUNTER_UPDATE_VECTORfmt, 1545 c_v, 1546 PRE_COUNTER_UPDATE_VECTORf); 1547 1548 /* only pre drop vector */ 1549 SHR_BITCOPY_RANGE(&pre_dp_v, 12, &pre_coun_v, 12, 20); 1550 1551 vx_dp_v = soc_format_field32_get(unit, 1552 PKT_PROC_DROP_VECTORfmt, 1553 &pkt_dp_v, 1554 VXLT_DROP_VECTORf); 1555 1556 disc_dp_v = soc_format_field32_get(unit, 1557 PKT_PROC_DROP_VECTORfmt, 1558 &pkt_dp_v, 1559 DISCARD_PROC_DROP_VECTORf); 1560 1561 vlan_dp_v = soc_format_field32_get(unit, 1562 PKT_PROC_DROP_VECTORfmt, 1563 &pkt_dp_v, 1564 VLAN_DROP_VECTORf); 1565 1566 tl_dp_v = soc_format_field32_get(unit, 1567 PKT_PROC_DROP_VECTORfmt, 1568 &pkt_dp_v, 1569 TUNNEL_PROC_DROP_VECTORf); 1570 1571 rsel2_dp_v = soc_format_field32_get(unit, 1572 PKT_PROC_DROP_VECTORfmt, 1573 &pkt_dp_v, 1574 RSEL2_DROP_VECTORf); 1575 1576 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1577 bcmSwitchPktTraceNoDrop); 1578 1579 if (soc_format_field32_get(unit, TUNNEL_PROC_DROP_VECTORfmt, 1580 &tl_dp_v, MPLS_LABEL_MISSf)) { 1581 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1582 bcmSwitchPktTraceDropReasonMplsLabelLookupMiss); 1583 } 1584 1585 if (soc_format_field32_get(unit, TUNNEL_PROC_DROP_VECTORfmt, 1586 &tl_dp_v, MPLS_INVALID_ACTIONf)) { 1587 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1588 bcmSwitchPktTraceDropReasonMplsInvalidAction); 1589 } 1590 1591 if (soc_format_field32_get(unit, TUNNEL_PROC_DROP_VECTORfmt, 1592 &tl_dp_v, MPLS_INVALID_PAYLOADf)) { 1593 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1594 bcmSwitchPktTraceDropReasonMplsInvalidPayload); 1595 } 1596 1597 if (soc_format_field32_get(unit, TUNNEL_PROC_DROP_VECTORfmt, 1598 &tl_dp_v, MPLS_CONTROL_PKTf)) { 1599 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1600 bcmSwitchPktTraceDropReasonMplsInvalidControlWord); 1601 } 1602 1603 #if 0 1604 if (soc_format_field32_get(unit, TUNNEL_PROC_DROP_VECTORfmt, 1605 &tl_dp_v, TUNNEL_TTL_CHECK_FAILf)) { 1606 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1607 bcmSwitchPktTraceDropReasonMplsTtlCheckFail); 1608 } 1609 #endif 1610 1611 if (soc_format_field32_get(unit, TUNNEL_PROC_DROP_VECTORfmt, 1612 &tl_dp_v, TUNNEL_OBJECT_VALIDATION_FAILf)) { 1613 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1614 bcmSwitchPktTraceDropReasonTunnelObjectValidationFail); 1615 } 1616 1617 if (soc_format_field32_get(unit, TUNNEL_PROC_DROP_VECTORfmt, 1618 &tl_dp_v, TUNNEL_TTL_CHECK_FAILf)) { 1619 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1620 bcmSwitchPktTraceDropReasonTunnelTTLError); 1621 } 1622 1623 if (soc_format_field32_get(unit, TUNNEL_PROC_DROP_VECTORfmt, 1624 &tl_dp_v, TUNNEL_INTERFACE_CHECK_FAILf)) { 1625 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1626 bcmSwitchPktTraceDropReasonTunnelInterfaceCheckFail); 1627 } 1628 1629 if (soc_format_field32_get(unit, TUNNEL_PROC_DROP_VECTORfmt, 1630 &tl_dp_v, TUNNEL_SHIM_HDR_ERRORf)) { 1631 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1632 bcmSwitchPktTraceDropReasonTunnelShimHeaderError); 1633 } 1634 1635 if (soc_format_field32_get(unit, VXLT_DROP_VECTORfmt, 1636 &vx_dp_v, TUNNEL_ADAPT_1_LOOKUP_MISSf)) { 1637 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1638 bcmSwitchPktTraceDropReasonTunnelAdapt1LookupMiss); 1639 } 1640 1641 if (soc_format_field32_get(unit, VXLT_DROP_VECTORfmt, 1642 &vx_dp_v, TUNNEL_ADAPT_2_LOOKUP_MISSf)) { 1643 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1644 bcmSwitchPktTraceDropReasonTunnelAdapt2LookupMiss); 1645 } 1646 1647 if (soc_format_field32_get(unit, VXLT_DROP_VECTORfmt, 1648 &vx_dp_v, TUNNEL_ADAPT_3_LOOKUP_MISSf)) { 1649 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1650 bcmSwitchPktTraceDropReasonTunnelAdapt3LookupMiss); 1651 } 1652 1653 if (soc_format_field32_get(unit, VXLT_DROP_VECTORfmt, 1654 &vx_dp_v, TUNNEL_ADAPT_4_LOOKUP_MISSf)) { 1655 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1656 bcmSwitchPktTraceDropReasonTunnelAdapt4LookupMiss); 1657 } 1658 1659 if (soc_format_field32_get(unit, RSEL2_DROP_VECTORfmt, 1660 &rsel2_dp_v, TUNNEL_ERRORf)) { 1661 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1662 bcmSwitchPktTraceDropReasonTunnelError); 1663 } 1664 1665 if (soc_format_field32_get(unit, PKT_PROC_DROP_VECTORfmt, 1666 &pkt_dp_v, TUNNEL_DECAP_ECNf)) { 1667 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1668 bcmSwitchPktTraceDropReasonTunnlDecapEcnError); 1669 } 1670 1671 if (soc_format_field32_get(unit, DISCARD_PROC_DROP_VECTORfmt, 1672 &disc_dp_v, HIGIG_LOOPBACKf)) { 1673 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1674 bcmSwitchPktTraceDropReasonHigigLoopback); 1675 } 1676 1677 if (soc_format_field32_get(unit, DISCARD_PROC_DROP_VECTORfmt, 1678 &disc_dp_v, HIGIG_HDR_ERRORf)) { 1679 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1680 bcmSwitchPktTraceDropReasonHigigUnknownHeader); 1681 } 1682 1683 if (soc_format_field32_get(unit, DISCARD_PROC_DROP_VECTORfmt, 1684 &disc_dp_v, HIGIG_UNKNOWN_OPCODEf)) { 1685 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1686 bcmSwitchPktTraceDropReasonHigigUnknownOpcode); 1687 } 1688 1689 if (soc_format_field32_get(unit, DISCARD_PROC_DROP_VECTORfmt, 1690 &disc_dp_v, LAG_FAIL_LOOPBACKf)) { 1691 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1692 bcmSwitchPktTraceDropReasonLagFailLoopback); 1693 } 1694 1695 if (soc_format_field32_get(unit, DISCARD_PROC_DROP_VECTORfmt, 1696 &disc_dp_v, MACSA_EQUALS_DAf)) { 1697 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1698 bcmSwitchPktTraceDropReasonL2SrcEqualL2Dst); 1699 } 1700 1701 if (soc_format_field32_get(unit, DISCARD_PROC_DROP_VECTORfmt, 1702 &disc_dp_v, NIV_VNTAG_PRESENTf)) { 1703 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1704 bcmSwitchPktTraceDropReasonNivVntagPresent); 1705 } 1706 1707 if (soc_format_field32_get(unit, DISCARD_PROC_DROP_VECTORfmt, 1708 &disc_dp_v, NIV_VNTAG_NOT_PRESENTf)) { 1709 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1710 bcmSwitchPktTraceDropReasonNivVntagNotPresent); 1711 } 1712 1713 if (soc_format_field32_get(unit, DISCARD_PROC_DROP_VECTORfmt, 1714 &disc_dp_v, NIV_VNTAG_FORMATf)) { 1715 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1716 bcmSwitchPktTraceDropReasonNivVntagFormat); 1717 } 1718 1719 if (soc_format_field32_get(unit, PRE_COUNTER_UPDATE_VECTORfmt, 1720 &pre_coun_v, RIPHE4f)) { 1721 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1722 bcmSwitchPktTraceDropReasonIpv4HeaderError); 1723 } 1724 1725 if (soc_format_field32_get(unit, PRE_COUNTER_UPDATE_VECTORfmt, 1726 &pre_coun_v, RIPHE6f)) { 1727 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1728 bcmSwitchPktTraceDropReasonIpv6HeaderError); 1729 } 1730 1731 if (soc_format_field32_get(unit, PRE_COUNTER_UPDATE_VECTORfmt, 1732 &pre_coun_v, PARITYDf)) { 1733 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1734 bcmSwitchPktTraceDropReasonParityError); 1735 } 1736 1737 if (soc_format_field32_get(unit, PKT_PROC_DROP_VECTORfmt, 1738 &pkt_dp_v, BPDUf)) { 1739 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1740 bcmSwitchPktTraceDropReasonBpdu); 1741 } 1742 1743 if (soc_format_field32_get(unit, PKT_PROC_DROP_VECTORfmt, 1744 &pkt_dp_v, TUNNEL_DECAP_ECNf)) { 1745 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1746 bcmSwitchPktTraceDropReasonTunnlDecapEcnError); 1747 } 1748 1749 if (soc_format_field32_get(unit, PKT_PROC_DROP_VECTORfmt, 1750 &pkt_dp_v, L2_RPF_CHECK_FAILf)) { 1751 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1752 bcmSwitchPktTraceDropReasonRpfCheckFail); 1753 } 1754 1755 if (soc_format_field32_get(unit, VLAN_DROP_VECTORfmt, 1756 &vlan_dp_v, INVALID_VLANf)) { 1757 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1758 bcmSwitchPktTraceDropReasonVlanNotValid); 1759 } 1760 1761 if (soc_format_field32_get(unit, VLAN_DROP_VECTORfmt, 1762 &vlan_dp_v, ENIFILTERf)) { 1763 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1764 bcmSwitchPktTraceDropReasonIngressPortNotInVlanMember); 1765 } 1766 1767 if (soc_format_field32_get(unit, VLAN_DROP_VECTORfmt, 1768 &vlan_dp_v, INVALID_TPIDf)) { 1769 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1770 bcmSwitchPktTraceDropReasonTpidMismatch); 1771 } 1772 1773 if (soc_format_field32_get(unit, VXLT_DROP_VECTORfmt, 1774 &vx_dp_v, VFPf)) { 1775 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1776 bcmSwitchPktTraceDropReasonStageLookup); 1777 } 1778 1779 if (soc_format_field32_get(unit, RSEL2_DROP_VECTORfmt, 1780 &rsel2_dp_v, IFP_DROPf)) { 1781 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1782 bcmSwitchPktTraceDropReasonStageIngress); 1783 } 1784 1785 if (soc_format_field32_get(unit, RSEL2_DROP_VECTORfmt, 1786 &rsel2_dp_v, URPF_CHECK_FAILf)) { 1787 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1788 bcmSwitchPktTraceDropReasonRpfCheckFail); 1789 } 1790 if (tl_dp_v || disc_dp_v || vlan_dp_v || 1791 vx_dp_v || pre_dp_v || pkt_dp_v[0] || 1792 pkt_dp_v[1]|| pkt_dp_v[2] || pkt_dp_v[3] || 1793 rsel2_dp_v) { 1794 SHR_BITSET(pkt_trace_info->pkt_trace_drop_reason, 1795 bcmSwitchPktTraceDropReasonInternal); 1796 SHR_BITCLR(pkt_trace_info->pkt_trace_drop_reason, 1797 bcmSwitchPktTraceNoDrop); 1798 } 1799 1800 return BCM_E_NONE; 1801 } 1802 1803 /* 1804 * Function: 1805 * _bcm_td3_pkt_trace_stp_state_get 1806 * Purpose: 1807 * STP state processing 1808 * Parameters: 1809 * IN : unit 1810 * Returns: 1811 * BCM_E_XXX 1812 */ 1813 STATIC 1814 int _bcm_td3_pkt_trace_stp_state_get(int unit, 1815 bcm_switch_pkt_trace_info_t *pkt_trace_info) 1816 { 1817 uint32 hw_stp_st = 0; 1818 uint32 stp_state = BCM_STG_STP_DISABLE; 1819 1820 hw_stp_st = _bcm_td3_dop_format_field32_get(unit, 1821 FWD1_1_DOPfmt, 1822 SPST_INGRESSf); 1823 1824 switch (hw_stp_st) { 1825 case 0: 1826 stp_state = BCM_STG_STP_DISABLE; 1827 break; 1828 case 1: 1829 stp_state = BCM_STG_STP_BLOCK; 1830 break; 1831 case 2: 1832 stp_state = BCM_STG_STP_LEARN; 1833 break; 1834 case 3: 1835 stp_state = BCM_STG_STP_FORWARD; 1836 break; 1837 default: 1838 return BCM_E_INTERNAL; 1839 } 1840 1841 pkt_trace_info->pkt_trace_stp_state = stp_state; 1842 return BCM_E_NONE; 1843 } 1844 1845 /* 1846 * Function: 1847 * _bcm_td3_pkt_trace_dop_parse_hash_init 1848 * Purpose: 1849 * DOP parsing. 1850 * Parameters: 1851 * IN : unit 1852 * Returns: 1853 * BCM_E_XXX 1854 */ 1855 STATIC 1856 int _bcm_td3_pkt_trace_dop_parse_hash_init(int unit, 1857 uint32 block, 1858 uint32 *buf) 1859 { 1860 uint32 resp_word; 1861 uint16 dop_id = 0; 1862 uint16 data_valid = 0; 1863 uint16 data_phases = 0; 1864 soc_format_t format_id = 0; 1865 uint16 format_len= 0; 1866 uint32 key = 0; 1867 pkt_trace_hash_info_t *ph = NULL; 1868 pkt_trace_hash_node_t *hash_list = NULL; 1869 pkt_trace_hash_node_t *hash_node = NULL; 1870 pkt_trace_dop_format_t *dop_format = NULL; 1871 pkt_trace_dop_format_t *fptr = NULL; 1872 uint32 *entry; 1873 uint32 *dop_ptr = NULL; 1874 uint32 temp_entry[SOC_MAX_MEM_WORDS * 2]; 1875 1876 ph = pkt_trace_hash_info[unit]; 1877 1878 if (ph->pkt_trace_hash_list == NULL) { 1879 return BCM_E_INTERNAL; 1880 } 1881 hash_list = ph->pkt_trace_hash_list; 1882 1883 if ((block != DOP_INGRESS) && 1884 (block != DOP_EGRESS)) { 1885 return BCM_E_INTERNAL; 1886 } 1887 1888 dop_ptr = buf; 1889 do { 1890 /* Read the first word of the dop_data 1891 * response word */ 1892 sal_memcpy(&resp_word, dop_ptr, sizeof(resp_word)); 1893 LOG_VERBOSE(BSL_LS_BCM_COMMON, 1894 (BSL_META_U(unit, "\n resp_word 0x%x\n"),resp_word)); 1895 dop_ptr++; 1896 dop_id = soc_format_field32_get(unit, 1897 DOP_COLLECTION_RESP_WORDfmt, 1898 &resp_word, DOP_IDf); 1899 data_phases = soc_format_field32_get(unit, 1900 DOP_COLLECTION_RESP_WORDfmt, 1901 &resp_word, DATA_PHASESf); 1902 data_valid = soc_format_field32_get(unit, 1903 DOP_COLLECTION_RESP_WORDfmt, 1904 &resp_word, DATA_VALIDf); 1905 1906 LOG_VERBOSE(BSL_LS_BCM_COMMON, 1907 (BSL_META_U(unit, 1908 "\n dop_id %d data_phases %d data_valid %d\n"), 1909 dop_id, data_phases, data_valid)); 1910 if (dop_id == 0) { 1911 LOG_ERROR(BSL_LS_BCM_COMMON, 1912 (BSL_META_U(unit, "\n INVALID DOP_ID: %d\n"), dop_id)); 1913 1914 return BCM_E_NONE; 1915 } 1916 BCM_IF_ERROR_RETURN( 1917 soc_dop_format_get(unit, dop_id, 0,/*dop_ext for ingress */ 1918 &format_len, &format_id)); 1919 if (format_len != data_phases) { 1920 LOG_ERROR(BSL_LS_BCM_COMMON, 1921 (BSL_META_U(unit, "\n DOP_ID %d - Mismatch in DOP Length. " 1922 "\n Data_phases %d format_len %d\n"), 1923 dop_id, data_phases, format_len)); 1924 1925 } 1926 1927 sal_memset(temp_entry, 0, sizeof(temp_entry)); 1928 entry = soc_cm_salloc(unit, WORDS2BYTES(data_phases), 1929 "dop format entry"); 1930 if (entry == NULL) { 1931 return BCM_E_MEMORY; 1932 } 1933 1934 sal_memcpy(temp_entry, dop_ptr, WORDS2BYTES(data_phases)); 1935 _bcm_esw_pkt_trace_dop_data_swap(unit, data_phases, temp_entry, entry); 1936 dop_ptr += data_phases; 1937 1938 BCM_IF_ERROR_RETURN( 1939 _bcm_pkt_trace_format_hash_key_get(unit, format_id, &key)); 1940 1941 LOG_VERBOSE(BSL_LS_BCM_COMMON, 1942 (BSL_META_U(unit, 1943 "\n HASH format ID %d Key %d\n"),format_id, key)); 1944 hash_node = &hash_list[key]; 1945 1946 dop_format = (pkt_trace_dop_format_t *) soc_cm_salloc(unit, 1947 sizeof(pkt_trace_dop_format_t), 1948 "dop format "); 1949 if (dop_format == NULL){ 1950 return BCM_E_MEMORY; 1951 } 1952 1953 sal_memset(dop_format, 0, sizeof(pkt_trace_dop_format_t)); 1954 dop_format->next = NULL; 1955 1956 dop_format->entry = entry; 1957 dop_format->format = format_id; 1958 dop_format->data_phases = format_len; 1959 dop_format->dop_id = dop_id; 1960 1961 if (hash_node->entry_num == 0) { 1962 hash_node->ft_entry = dop_format; 1963 } else { 1964 fptr = hash_node->ft_entry; 1965 if (fptr == NULL) { 1966 return BCM_E_INTERNAL; 1967 } 1968 dop_format->next = (uint32 *)fptr; 1969 hash_node->ft_entry = dop_format; 1970 } 1971 1972 hash_node->entry_num++; 1973 } while ((dop_ptr != NULL) && 1974 (dop_id < MAX_ING_DOP_FORMATS(unit))); 1975 return BCM_E_NONE; 1976 } 1977 1978 STATIC 1979 int _bcm_td3_pkt_trace_hash_info_alloc(int unit, pkt_trace_hash_info_t **ph) 1980 { 1981 pkt_trace_hash_info_t *hash_info; 1982 1983 hash_info = sal_alloc(sizeof(pkt_trace_hash_info_t), 1984 "pkt_trace_hash_info_t"); 1985 if (hash_info == NULL) { 1986 goto alloc_clean_up; 1987 } 1988 hash_info->pkt_trace_hash_list = sal_alloc( 1989 (sizeof(pkt_trace_hash_node_t) *MAX_DOP_FORMATS(unit)), 1990 "pkt_trace_hash_list"); 1991 if (hash_info->pkt_trace_hash_list == NULL) { 1992 goto alloc_clean_up; 1993 } 1994 1995 sal_memset(hash_info->pkt_trace_hash_list, 0, 1996 (sizeof(pkt_trace_hash_node_t) *MAX_DOP_FORMATS(unit))); 1997 *ph = hash_info; 1998 return 0; 1999 alloc_clean_up: 2000 if (hash_info) { 2001 if (hash_info->pkt_trace_hash_list) { 2002 sal_free(hash_info->pkt_trace_hash_list); 2003 hash_info->pkt_trace_hash_list= NULL; 2004 } 2005 sal_free(hash_info); 2006 hash_info = NULL; 2007 } 2008 return BCM_E_MEMORY; 2009 } 2010 2011 /* 2012 * Function: 2013 * _bcm_td3_pkt_trace_dop_parse_init 2014 * Purpose: 2015 * DOP parsing init. 2016 * Parameters: 2017 * IN : unit 2018 * Returns: 2019 * BCM_E_XXX 2020 */ 2021 STATIC 2022 int _bcm_td3_pkt_trace_dop_parse_init(int unit) 2023 { 2024 pkt_trace_hash_info_t *ph = NULL; 2025 2026 ph = pkt_trace_hash_info[unit]; 2027 if (ph == NULL) { 2028 BCM_IF_ERROR_RETURN( 2029 _bcm_td3_pkt_trace_hash_info_alloc(unit, &ph)); 2030 ph->unit = unit; 2031 pkt_trace_hash_info[unit] = ph; 2032 } 2033 return BCM_E_NONE; 2034 } 2035 2036 /* 2037 * Function: 2038 * _bcm_td3_pkt_trace_dop_parse_deinit 2039 * Purpose: 2040 * DOP parsing deinit 2041 * Parameters: 2042 * IN : unit 2043 * Returns: 2044 * BCM_E_XXX 2045 */ 2046 STATIC 2047 void _bcm_td3_pkt_trace_dop_parse_deinit(int unit) 2048 { 2049 pkt_trace_hash_info_t *ph = pkt_trace_hash_info[unit]; 2050 2051 if (ph != NULL) { 2052 if (ph->pkt_trace_hash_list != NULL) { 2053 sal_free(ph->pkt_trace_hash_list); 2054 ph->pkt_trace_hash_list = NULL; 2055 } 2056 sal_free(ph); 2057 pkt_trace_hash_info[unit] = NULL; 2058 } 2059 } 2060 2061 /* 2062 * Function: 2063 * _bcm_td3_pkt_trace_dop_parse_deinit 2064 * Purpose: 2065 * DOP parsing deinit. 2066 * Parameters: 2067 * IN : unit 2068 * Returns: 2069 * BCM_E_XXX 2070 */ 2071 STATIC 2072 void _bcm_td3_pkt_trace_dop_parse_hash_deinit(int unit) 2073 { 2074 pkt_trace_hash_info_t *ph = NULL; 2075 pkt_trace_hash_node_t *hash_node = NULL; 2076 pkt_trace_dop_format_t *fptr = NULL; 2077 pkt_trace_dop_format_t *tmp = NULL; 2078 pkt_trace_hash_node_t *hash_list = NULL; 2079 int i = 0; 2080 2081 ph = pkt_trace_hash_info[unit]; 2082 if (ph->pkt_trace_hash_list != NULL) { 2083 hash_list = ph->pkt_trace_hash_list; 2084 for (i = 0; i < MAX_DOP_FORMATS(unit); i++) { 2085 hash_node = &hash_list[i]; 2086 if ((hash_node->ft_entry == NULL) || 2087 (!hash_node->entry_num)){ 2088 continue; 2089 } 2090 for (fptr = hash_node->ft_entry; 2091 fptr != NULL;) { 2092 tmp = fptr; 2093 fptr = (pkt_trace_dop_format_t *) fptr->next; 2094 soc_cm_sfree(unit, tmp->entry); 2095 tmp->entry = NULL; 2096 soc_cm_sfree(unit, tmp); 2097 tmp = NULL; 2098 } 2099 } 2100 } 2101 } 2102 2103 /* 2104 * Function: 2105 * _bcm_td3_pkt_trace_info_processing 2106 * Purpose: 2107 * Packet trace processing for the 2108 * processed data. 2109 * Parameters: 2110 * IN : unit 2111 * Returns: 2112 * BCM_E_XXX 2113 */ 2114 STATIC 2115 int _bcm_td3_pkt_trace_info_processing(int unit, 2116 bcm_switch_pkt_trace_info_t *pkt_trace_info) 2117 { 2118 2119 /***************************************************** 2120 1. Read from the DOP MEM entrie chunk per ingress 2121 egress pipeline 2122 2. Process each dop _id. 2123 3. Get the format per block 2124 4. Process the data. 2125 */ 2126 uint32 *ing_dop_tbl_chunk = NULL; 2127 soc_mem_t mem = ING_DOP_STORAGE_MEMm; 2128 int rv = BCM_E_NONE; 2129 int entry_dw, entry_sz, indexes; 2130 uint32 buf_size = 0; 2131 uint32 data_size = 0; 2132 int max_idx, min_idx; 2133 2134 entry_dw = soc_mem_entry_words(unit, mem); 2135 entry_sz = entry_dw * sizeof(uint32); 2136 2137 min_idx = soc_mem_index_min(unit, mem); 2138 max_idx = soc_mem_index_max(unit, mem); 2139 indexes = (max_idx - min_idx) + 1; 2140 2141 buf_size = entry_sz * indexes; 2142 2143 /* initalize the EGRESS DOPs */ 2144 BCM_IF_ERROR_RETURN( 2145 _bcm_td3_pkt_trace_dop_parse_init(unit)); 2146 2147 LOG_VERBOSE(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 2148 "Packet trace information processing - START"))); 2149 2150 ing_dop_tbl_chunk = (uint32 *) soc_cm_salloc(unit, buf_size, 2151 "flow match traverse"); 2152 if (NULL == ing_dop_tbl_chunk) { 2153 return BCM_E_MEMORY; 2154 } 2155 2156 /* Collect the ingress dop_storage memory and process */ 2157 rv = _bcm_td3_pkt_trace_dop_buffer_collect(unit, 2158 DOP_INGRESS, 2159 buf_size, 2160 ing_dop_tbl_chunk, 2161 &data_size); 2162 if (BCM_FAILURE(rv)) { 2163 goto clean_up; 2164 } 2165 2166 2167 rv = _bcm_td3_pkt_trace_dop_parse_hash_init(unit, 2168 DOP_INGRESS, 2169 ing_dop_tbl_chunk); 2170 2171 if (BCM_FAILURE(rv)) { 2172 goto clean_up; 2173 } 2174 2175 rv = _bcm_td3_pkt_trace_lookup_status_get(unit, 2176 pkt_trace_info); 2177 if (BCM_FAILURE(rv)) { 2178 goto clean_up; 2179 } 2180 2181 rv = _bcm_td3_pkt_trace_pkt_resolution_get(unit, 2182 pkt_trace_info); 2183 if (BCM_FAILURE(rv)) { 2184 goto clean_up; 2185 } 2186 2187 2188 /*HASH Resolution */ 2189 #ifdef INCLUDE_L3 2190 rv = _bcm_td3_pkt_trace_ecmp_resolution_get(unit, 2191 pkt_trace_info); 2192 if (BCM_FAILURE(rv)) { 2193 goto clean_up; 2194 } 2195 2196 #endif /* INCLUDE_L3 */ 2197 rv = _bcm_td3_pkt_trace_hg_trunk_resolution_get(unit, 2198 pkt_trace_info); 2199 if (BCM_FAILURE(rv)) { 2200 goto clean_up; 2201 } 2202 2203 rv = _bcm_td3_pkt_trace_ucast_lag_resolution_get(unit, 2204 pkt_trace_info); 2205 if (BCM_FAILURE(rv)) { 2206 goto clean_up; 2207 } 2208 2209 /* END - HASH Resolution */ 2210 #ifdef INCLUDE_L3 2211 rv = _bcm_td3_pkt_trace_fwd_dst_resolution_get(unit, 2212 pkt_trace_info); 2213 if (BCM_FAILURE(rv)) { 2214 goto clean_up; 2215 } 2216 2217 #endif /* INCLUDE_L3 */ 2218 rv = _bcm_td3_pkt_trace_drop_reason_get(unit, 2219 pkt_trace_info); 2220 if (BCM_FAILURE(rv)) { 2221 goto clean_up; 2222 } 2223 2224 rv = _bcm_td3_pkt_trace_stp_state_get(unit, 2225 pkt_trace_info); 2226 if (BCM_FAILURE(rv)) { 2227 goto clean_up; 2228 } 2229 2230 clean_up: 2231 _bcm_td3_pkt_trace_dop_parse_hash_deinit(unit); 2232 _bcm_td3_pkt_trace_dop_parse_deinit(unit); 2233 2234 if (ing_dop_tbl_chunk != NULL) { 2235 soc_cm_sfree(unit, ing_dop_tbl_chunk); 2236 } 2237 return rv; 2238 2239 } 2240 2241 /* 2242 * Function: 2243 * _bcm_td3_pkt_trace_raw_data_get 2244 * Purpose: 2245 * read results ptr buffer for 2246 * visibility packet and store into into 2247 * raw data. 2248 * Parameters: 2249 * IN : unit 2250 * Returns: 2251 * BCM_E_XXX 2252 */ 2253 2254 int _bcm_td3_pkt_trace_raw_data_get(int unit, 2255 uint32 *raw_data_size, 2256 uint8 *raw_data) 2257 2258 { 2259 uint32 *ing_dop_tbl_chunk = NULL; 2260 uint32 *egr_dop_tbl_chunk = NULL; 2261 soc_mem_t mem; 2262 int rv = BCM_E_NONE; 2263 int entry_sz, indexes; 2264 uint32 ing_buf_size = 0; 2265 uint32 egr_buf_size = 0; 2266 int max_idx, min_idx; 2267 uint32 ing_data_size = 0; 2268 uint32 egr_data_size = 0; 2269 2270 if ((raw_data == NULL) || 2271 (raw_data_size == NULL)) { 2272 return BCM_E_INTERNAL; 2273 } 2274 2275 /* INGRESS DOP STORAGE MEM */ 2276 BCM_IF_ERROR_RETURN( 2277 _bcm_td3_pkt_trace_dop_reset(unit, DOP_INGRESS)); 2278 BCM_IF_ERROR_RETURN( 2279 _bcm_td3_pkt_trace_dop_collect(unit, DOP_INGRESS)); 2280 2281 mem = ING_DOP_STORAGE_MEMm; 2282 entry_sz = 0; 2283 min_idx = max_idx = indexes = 0; 2284 entry_sz = (BCM_PKT_TRC_DOP_DATA_WORD_LEN * sizeof(uint32)); 2285 min_idx = soc_mem_index_min(unit, mem); 2286 max_idx = soc_mem_index_max(unit, mem); 2287 indexes = (max_idx - min_idx) + 1; 2288 ing_buf_size = entry_sz * indexes; 2289 2290 ing_dop_tbl_chunk = soc_cm_salloc(unit, ing_buf_size, 2291 "flow match traverse"); 2292 if (NULL == ing_dop_tbl_chunk) { 2293 rv = BCM_E_MEMORY; 2294 goto clean_up; 2295 } 2296 /* Collect the ingress dop_storage memory and process */ 2297 rv = _bcm_td3_pkt_trace_dop_buffer_collect(unit, 2298 DOP_INGRESS, 2299 ing_buf_size, 2300 ing_dop_tbl_chunk, 2301 &ing_data_size); 2302 2303 if (BCM_FAILURE(rv)) { 2304 goto clean_up; 2305 } 2306 2307 mem = EGR_DOP_STORAGE_MEMm; 2308 entry_sz = 0; 2309 min_idx = max_idx = indexes = 0; 2310 entry_sz = (BCM_PKT_TRC_DOP_DATA_WORD_LEN * sizeof(uint32)); 2311 min_idx = soc_mem_index_min(unit, mem); 2312 max_idx = soc_mem_index_max(unit, mem); 2313 indexes = (max_idx - min_idx) + 1; 2314 egr_buf_size = entry_sz * indexes; 2315 egr_dop_tbl_chunk = soc_cm_salloc(unit, egr_buf_size, 2316 "flow match traverse"); 2317 if (NULL == egr_dop_tbl_chunk) { 2318 rv = BCM_E_MEMORY; 2319 goto clean_up; 2320 } 2321 2322 /* INGRESS DOP STORAGE MEM */ 2323 rv = _bcm_td3_pkt_trace_dop_reset(unit, DOP_EGRESS); 2324 if (BCM_FAILURE(rv)) { 2325 goto clean_up; 2326 } 2327 rv = _bcm_td3_pkt_trace_dop_collect(unit, DOP_EGRESS); 2328 if (BCM_FAILURE(rv)) { 2329 goto clean_up; 2330 } 2331 2332 /* Collect the ingress dop_storage memory and process */ 2333 rv = _bcm_td3_pkt_trace_dop_buffer_collect(unit, 2334 DOP_EGRESS, 2335 egr_buf_size, 2336 egr_dop_tbl_chunk, 2337 &egr_data_size); 2338 if (BCM_FAILURE(rv)) { 2339 goto clean_up; 2340 } 2341 2342 if (*raw_data_size < (ing_buf_size + egr_buf_size)) { 2343 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 2344 "\n Insufficient raw data buffer size %d \ 2345 Expected raw data buffer size %d"), *raw_data_size, 2346 (ing_buf_size + egr_buf_size))); 2347 rv = BCM_E_PARAM; 2348 goto clean_up; 2349 } 2350 2351 sal_memcpy(raw_data, ing_dop_tbl_chunk, ing_data_size); 2352 *raw_data_size = ing_data_size; 2353 2354 sal_memcpy((raw_data + ing_data_size), 2355 egr_dop_tbl_chunk, egr_data_size); 2356 *raw_data_size += egr_data_size; 2357 2358 clean_up: 2359 if (ing_dop_tbl_chunk != NULL) { 2360 soc_cm_sfree(unit, ing_dop_tbl_chunk); 2361 } 2362 if (egr_dop_tbl_chunk != NULL) { 2363 soc_cm_sfree(unit, egr_dop_tbl_chunk); 2364 } 2365 2366 return rv; 2367 } 2368 2369 int _bcm_td3_pkt_trace_dop_config_set(int unit) 2370 { 2371 2372 /* INGRESS DOP STORAGE MEM */ 2373 BCM_IF_ERROR_RETURN( 2374 _bcm_td3_pkt_trace_dop_reset(unit, DOP_INGRESS)); 2375 BCM_IF_ERROR_RETURN( 2376 _bcm_td3_pkt_trace_dop_init(unit, DOP_INGRESS, 1)); 2377 BCM_IF_ERROR_RETURN( 2378 _bcm_td3_pkt_trace_dop_reset(unit, DOP_INGRESS)); 2379 BCM_IF_ERROR_RETURN( 2380 _bcm_td3_pkt_trace_dop_clear(unit, DOP_INGRESS)); 2381 /* EGRESS DOP STORAGE MEM */ 2382 BCM_IF_ERROR_RETURN( 2383 _bcm_td3_pkt_trace_dop_reset(unit, DOP_EGRESS)); 2384 BCM_IF_ERROR_RETURN( 2385 _bcm_td3_pkt_trace_dop_init(unit, DOP_EGRESS, 1)); 2386 BCM_IF_ERROR_RETURN( 2387 _bcm_td3_pkt_trace_dop_reset(unit, DOP_EGRESS)); 2388 BCM_IF_ERROR_RETURN( 2389 _bcm_td3_pkt_trace_dop_clear(unit, DOP_EGRESS)); 2390 2391 return BCM_E_NONE; 2392 } 2393 /* 2394 * Function: 2395 * _bcm_td3_pkt_trace_info_get 2396 * Purpose: 2397 * read results ptr buffer for 2398 * visibility packet process and 2399 * store into pkt_trace_info 2400 * Parameters: 2401 * IN : unit 2402 * Returns: 2403 * BCM_E_XXX 2404 */ 2405 2406 int _bcm_td3_pkt_trace_info_get(int unit, 2407 bcm_switch_pkt_trace_info_t *pkt_trace_info) 2408 { 2409 /* INGRESS DOP STORAGE MEM */ 2410 BCM_IF_ERROR_RETURN( 2411 _bcm_td3_pkt_trace_dop_reset(unit, DOP_INGRESS)); 2412 BCM_IF_ERROR_RETURN( 2413 _bcm_td3_pkt_trace_dop_collect(unit, DOP_INGRESS)); 2414 BCM_IF_ERROR_RETURN( 2415 _bcm_td3_pkt_trace_info_processing(unit, pkt_trace_info)); 2416 2417 return BCM_E_NONE; 2418 } 2419 /* 2420 * Function: 2421 * _bcm_td3_pkt_trace_src_port_set 2422 * Purpose: 2423 * set the source port of 2424 * visiblity packet 2425 * this must be called before visibilty packet 2426 * is sent to set the pipe to read the resuls 2427 * Parameters: 2428 * IN : unit 2429 * IN : logical_src_port 2430 * Returns: 2431 * BCM_E_XXX 2432 */ 2433 int _bcm_td3_pkt_trace_src_port_set(int unit, uint32 logical_src_port) 2434 { 2435 soc_info_t *si; 2436 si = &SOC_INFO(unit); 2437 2438 td3_pkt_trace_port_info[unit].pkt_trace_src_logical_port = logical_src_port; 2439 td3_pkt_trace_port_info[unit].pkt_trace_src_pipe = 2440 si->port_pipe[logical_src_port]; 2441 2442 return 0; 2443 } 2444 2445 /* 2446 * Function: 2447 * _bcm_td3_pkt_trace_src_port_get 2448 * Purpose: 2449 * get the source port of 2450 * visiblity packet 2451 * Parameters: 2452 * IN : unit 2453 * IN : logical_src_port 2454 * Returns: 2455 * BCM_E_XXX 2456 */ 2457 2458 int _bcm_td3_pkt_trace_src_port_get(int unit) 2459 { 2460 return td3_pkt_trace_port_info[unit].pkt_trace_src_logical_port; 2461 } 2462 2463 /* 2464 * Function: 2465 * _bcm_td3_pkt_trace_src_pipe_get 2466 * Purpose: 2467 * get the ingress pipe of 2468 * visiblity packet 2469 * Parameters: 2470 * IN : unit 2471 * IN : logical_src_port 2472 * Returns: 2473 * BCM_E_XXX 2474 */ 2475 int _bcm_td3_pkt_trace_src_pipe_get(int unit) 2476 { 2477 return td3_pkt_trace_port_info[unit].pkt_trace_src_pipe; 2478 } 2479 2480 /* 2481 * Function: 2482 * _bcm_td3_pkt_trace_cpu_profile_init 2483 * Purpose: 2484 * pre-configure CPU_PKT_PROFILE_1,2 Register according to 2485 * index : drop_egr | dropmmu | ifp | no learn 2486 * 0 0 0 0 0 2487 * 1 0 0 0 1 2488 * 2 0 0 1 0 2489 * 3 0 0 1 1 2490 * 4 0 1 0 0 2491 * 5 0 1 1 1 2492 * 6 1 0 0 0 2493 * 7 1 0 1 1 2494 * Parameters: 2495 * IN : unit 2496 * Returns: 2497 * BCM_E_XXX 2498 */ 2499 int _bcm_td3_pkt_trace_cpu_profile_init(int unit) { 2500 /* pkt_profile_1 contains control of IFP and Learning */ 2501 uint32 pkt_profile_1_w = 0xACAA; 2502 /* pkt_profile_2 contains control of forwarding */ 2503 uint32 pkt_profile_2_w = 0xC030; 2504 2505 if (SOC_REG_IS_VALID(unit, CPU_PKT_PROFILE_1r)) { 2506 WRITE_CPU_PKT_PROFILE_1r(unit, pkt_profile_1_w); 2507 } 2508 2509 if (SOC_REG_IS_VALID(unit, CPU_PKT_PROFILE_2r)) { 2510 WRITE_CPU_PKT_PROFILE_2r(unit, pkt_profile_2_w); 2511 } 2512 2513 return BCM_E_NONE; 2514 } 2515 2516 /* 2517 * Function: 2518 * _bcm_td3_pkt_trace_cpu_profile_set 2519 * Purpose: 2520 * given visibility packet behavior flags 2521 * setting the profile id for the next visiblity packet 2522 * Parameters: 2523 * IN : unit 2524 * Returns: 2525 * BCM_E_XXX 2526 */ 2527 int _bcm_td3_pkt_trace_cpu_profile_set(int unit, 2528 uint32 flags) 2529 { 2530 uint32 param_flags[1] = {0}; 2531 uint32 profile_id = 0; 2532 2533 param_flags[0] = flags; 2534 if (((flags & BCM_PKT_TRACE_FORWARD) && 2535 ((flags & BCM_PKT_TRACE_DROP_TO_MMU) || 2536 (flags & BCM_PKT_TRACE_DROP_TO_EGR))) || 2537 ((flags & BCM_PKT_TRACE_DROP_TO_MMU)&& 2538 (flags & BCM_PKT_TRACE_DROP_TO_EGR)) ) { 2539 LOG_ERROR(BSL_LS_BCM_COMMON, 2540 (BSL_META_U(unit, 2541 "\n Invalid visibility option flag's\n"))); 2542 2543 return BCM_E_PARAM; 2544 } 2545 2546 if (flags & BCM_PKT_TRACE_FORWARD) { 2547 /* This flag is equivalent of 2548 NO_MMU_DROP & NO_EGR_DROP 2549 */ 2550 SHR_BITCLR_RANGE(param_flags, 2, 1); 2551 } 2552 2553 switch (param_flags[0]) { 2554 /* special case only BCM_PKT_TRACE_FORWARD */ 2555 case 0: 2556 profile_id = 3; 2557 break; 2558 case (BCM_PKT_TRACE_NO_IFP): 2559 profile_id = 1; 2560 break; 2561 case (BCM_PKT_TRACE_LEARN): 2562 profile_id = 2; 2563 break; 2564 case (BCM_PKT_TRACE_LEARN | 2565 BCM_PKT_TRACE_NO_IFP): 2566 profile_id = 0; 2567 break; 2568 case (BCM_PKT_TRACE_DROP_TO_MMU): 2569 profile_id = 5; 2570 break; 2571 case (BCM_PKT_TRACE_LEARN | 2572 BCM_PKT_TRACE_NO_IFP | 2573 BCM_PKT_TRACE_DROP_TO_MMU): 2574 profile_id = 4; 2575 break; 2576 case (BCM_PKT_TRACE_DROP_TO_EGR): 2577 profile_id = 7; 2578 break; 2579 case (BCM_PKT_TRACE_LEARN | 2580 BCM_PKT_TRACE_NO_IFP | 2581 BCM_PKT_TRACE_DROP_TO_EGR): 2582 profile_id = 6; 2583 break; 2584 default: 2585 LOG_ERROR(BSL_LS_BCM_COMMON, 2586 (BSL_META_U(unit, 2587 "\n Invalid FLAGs\n"))); 2588 return BCM_E_PARAM; 2589 2590 } 2591 LOG_VERBOSE(BSL_LS_BCM_COMMON, 2592 (BSL_META_U(unit, 2593 "\n Visibility option FLAG's %d profile Id %d \n"), 2594 flags, profile_id)); 2595 td3_cpu_pkt_profile_id[unit] = profile_id; 2596 2597 return BCM_E_NONE; 2598 } 2599 2600 /* 2601 * Function: 2602 * _bcm_td3_pkt_trace_cpu_profile_get 2603 * Purpose: 2604 * retrieve cpu profile id to be used for 2605 * the next visibilty packet 2606 * Parameters: 2607 * IN : unit 2608 * Returns: 2609 * BCM_E_XXX 2610 */ 2611 2612 int _bcm_td3_pkt_trace_cpu_profile_get(int unit, uint32* profile_id) 2613 { 2614 if (profile_id == NULL) { 2615 return BCM_E_INTERNAL; 2616 } 2617 *profile_id = td3_cpu_pkt_profile_id[unit]; 2618 return BCM_E_NONE; 2619 } 2620 2621 /* 2622 * Function: 2623 * _bcm_td3_pkt_trace_info_init 2624 * Purpose: 2625 * Initialize the td3 packet trace. 2626 * Parameters: 2627 * IN : unit 2628 * Returns: 2629 * BCM_E_XXX 2630 */ 2631 int _bcm_td3_pkt_trace_init(int unit) 2632 { 2633 uint32 block = 0; 2634 2635 block = DOP_INGRESS; 2636 /* initalize the INGRESS DOPs */ 2637 BCM_IF_ERROR_RETURN( 2638 _bcm_td3_pkt_trace_dop_reset(unit, block)); 2639 BCM_IF_ERROR_RETURN( 2640 _bcm_td3_pkt_trace_dop_init(unit, block, 1)); 2641 2642 2643 block = DOP_EGRESS; 2644 BCM_IF_ERROR_RETURN( 2645 _bcm_td3_pkt_trace_dop_reset(unit, block)); 2646 BCM_IF_ERROR_RETURN( 2647 _bcm_td3_pkt_trace_dop_init(unit, block, 1)); 2648 return BCM_E_NONE; 2649 } 2650 2651 int _bcm_td3_pkt_trace_source_trunk_map_pp_set(int unit, 2652 bcm_module_t mod_id, 2653 bcm_port_t pp_port, 2654 uint16 reset) 2655 { 2656 int pipe_num; 2657 int loopback_port; 2658 source_trunk_map_modbase_entry_t modbase_entry; 2659 int i, lb_idx; 2660 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 2661 uint32 lb_src_ent[SOC_MAX_MEM_FIELD_WORDS]; 2662 int lport_index = 0; 2663 int lb_lport_index = 0; 2664 /* Program the SOURCE_TRUNK_MAP with packet 2665 * processing port 2666 */ 2667 SOC_IF_ERROR_RETURN( 2668 soc_port_pipe_get(unit, pp_port, &pipe_num)); 2669 loopback_port = soc_loopback_lbport_num_get(unit, pipe_num); 2670 if (loopback_port == -1) { 2671 return BCM_E_PARAM; 2672 } 2673 sal_memset(src_ent, 0, sizeof(src_ent)); 2674 sal_memset(lb_src_ent, 0, sizeof(lb_src_ent)); 2675 BCM_IF_ERROR_RETURN 2676 (soc_mem_read(unit, ING_DEVICE_PORTm, MEM_BLOCK_ANY, pp_port, 2677 src_ent)); 2678 lport_index = 2679 soc_mem_field32_get(unit, ING_DEVICE_PORTm, src_ent, LPORT_PROFILE_IDXf); 2680 2681 BCM_IF_ERROR_RETURN 2682 (soc_mem_read(unit, ING_DEVICE_PORTm, MEM_BLOCK_ANY, loopback_port, 2683 lb_src_ent)); 2684 lb_lport_index= 2685 soc_mem_field32_get(unit, ING_DEVICE_PORTm, lb_src_ent, LPORT_PROFILE_IDXf); 2686 2687 BCM_IF_ERROR_RETURN 2688 (soc_mem_read(unit, SOURCE_TRUNK_MAP_MODBASEm, MEM_BLOCK_ANY, 2689 mod_id, &modbase_entry)); 2690 2691 i = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_MODBASEm, 2692 &modbase_entry, BASEf) + pp_port; 2693 lb_idx = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_MODBASEm, 2694 &modbase_entry, BASEf) + loopback_port; 2695 if (!reset) { 2696 BCM_IF_ERROR_RETURN 2697 (soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 2698 i, PP_PORT_NUMf, pp_port)); 2699 BCM_IF_ERROR_RETURN 2700 (soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 2701 i, LPORT_PROFILE_IDXf, lport_index)); 2702 BCM_IF_ERROR_RETURN 2703 (soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 2704 lb_idx, PP_PORT_NUMf, loopback_port)); 2705 BCM_IF_ERROR_RETURN 2706 (soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 2707 lb_idx, LPORT_PROFILE_IDXf, lb_lport_index)); 2708 } else { 2709 BCM_IF_ERROR_RETURN 2710 (soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 2711 i, PP_PORT_NUMf, 0)); 2712 BCM_IF_ERROR_RETURN 2713 (soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 2714 i, LPORT_PROFILE_IDXf, 0)); 2715 BCM_IF_ERROR_RETURN 2716 (soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 2717 lb_idx, PP_PORT_NUMf, 0)); 2718 BCM_IF_ERROR_RETURN 2719 (soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 2720 lb_idx, LPORT_PROFILE_IDXf, 0)); 2721 } 2722 return BCM_E_NONE; 2723 } 2724 #endif /* BCM_INSTRUMENTATION_SUPPORT*/