instrumentation.c (21377B)
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 <sal/types.h> 19 #include <sal/core/sync.h> 20 #include <sal/core/time.h> 21 #include <bcm/types.h> 22 #include <bcm/error.h> 23 #include <bcm/port.h> 24 #include <bcm/switch.h> 25 #include <bcm/tx.h> 26 #include <bcm_int/esw_dispatch.h> 27 #include <bcm_int/esw/tx.h> 28 #include <bcm_int/esw/port.h> 29 #include <bcm_int/esw_dispatch.h> 30 #include <bcm_int/esw/instrumentation.h> 31 32 /* Flag to check initialized status */ 33 STATIC int _pkt_trace_initialized[BCM_MAX_NUM_UNITS]; 34 35 /* Protection mutexes for each unit */ 36 sal_mutex_t _pkt_trace_mlock[BCM_MAX_NUM_UNITS]; 37 38 #define PKT_TRACE_LOCK(unit) sal_mutex_take(_pkt_trace_mlock[unit], sal_mutex_FOREVER) 39 #define PKT_TRACE_UNLOCK(unit) sal_mutex_give(_pkt_trace_mlock[unit]) 40 41 #define UNIT_VALID_CHECK(unit) \ 42 if (((unit) < 0) || ((unit) >= BCM_MAX_NUM_UNITS)) { return BCM_E_UNIT; } 43 44 #define PKT_TRACE_INIT_DONE(unit) (_pkt_trace_mlock[unit] != NULL) 45 46 #define PKT_TRACE_INIT_CHECK(unit) \ 47 do { \ 48 UNIT_VALID_CHECK(unit); \ 49 if (_pkt_trace_mlock[unit] == NULL) { return BCM_E_INIT; } \ 50 } while (0) 51 52 /* 53 * Function: 54 * bcm_esw_pkt_trace_hw_reset 55 * Purpose: 56 * clean PTR_RESULTS_BUFFER_IVP/ISW1/ISW2 registers 57 * call this functio before sending a 58 * visibilty packet 59 * Parameters: 60 * IN : unit 61 * Returns: 62 * BCM_E_XXX 63 */ 64 int _bcm_esw_pkt_trace_hw_reset(int unit) 65 { 66 #if defined(BCM_TOMAHAWK3_SUPPORT) 67 if (SOC_IS_TOMAHAWK3(unit)) { 68 /* Call low level routine to reset HW memories for all pipes */ 69 return _bcm_th3_pkt_trace_hw_reset(unit, -1); 70 } else 71 #endif 72 if (SOC_IS_TOMAHAWKX(unit)) { 73 return _bcm_th_pkt_trace_hw_reset(unit); 74 } 75 return BCM_E_UNAVAIL; 76 } 77 78 /* 79 * Function: 80 * _bcm_esw_pkt_trace_src_port_set 81 * Purpose: 82 * set the destination port of 83 * visiblity packet 84 * this must be called before visibilty packet 85 * is sent to set the pipe to read the resuls 86 * Parameters: 87 * IN : unit 88 * IN : logical_dst_port 89 * Returns: 90 * BCM_E_XXX 91 */ 92 int _bcm_esw_pkt_trace_src_port_set(int unit, uint32 logical_dst_port) 93 { 94 if (SOC_IS_TOMAHAWKX(unit)) { 95 return _bcm_th_pkt_trace_src_port_set(unit, logical_dst_port); 96 } else if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 97 return _bcm_td3_pkt_trace_src_port_set(unit, logical_dst_port); 98 } 99 return BCM_E_UNAVAIL; 100 } 101 102 /* 103 * Function: 104 * _bcm_esw_pkt_trace_src_port_get 105 * Purpose: 106 * get the destination port of 107 * visiblity packet 108 * Parameters: 109 * IN : unit 110 * IN : logical_dst_port 111 * Returns: 112 * BCM_E_XXXd 113 */ 114 115 int _bcm_esw_pkt_trace_src_port_get(int unit) 116 { 117 if (SOC_IS_TOMAHAWKX(unit)) { 118 return _bcm_th_pkt_trace_src_port_get(unit); 119 } else if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 120 return _bcm_td3_pkt_trace_src_port_get(unit); 121 } 122 return BCM_E_UNAVAIL; 123 } 124 125 /* 126 * Function: 127 * _bcm_esw_pkt_trace_src_pipe_get 128 * Purpose: 129 * get the destination pipe of 130 * visiblity packet 131 * Parameters: 132 * IN : unit 133 * IN : logical_dst_port 134 * Returns: 135 * BCM_E_XXXd 136 */ 137 int _bcm_esw_pkt_trace_src_pipe_get(int unit) 138 { 139 if (SOC_IS_TOMAHAWKX(unit)) { 140 return _bcm_th_pkt_trace_src_pipe_get(unit); 141 } else if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 142 return _bcm_td3_pkt_trace_src_pipe_get(unit); 143 } 144 return BCM_E_UNAVAIL; 145 } 146 147 /* 148 * Function: 149 * _bcm_esw_pkt_trace_pkt_profile_set 150 * Purpose: 151 * given visibility packet behavior options 152 * setting the profile id for the next visibility packet 153 * Parameters: 154 * IN : unit 155 * IN : options (BCM_PKT_TRACE_LEARN/NO_IFP/FORWARD) 156 * Returns: 157 * BCM_E_XXX 158 */ 159 int _bcm_esw_pkt_trace_cpu_profile_set(int unit,uint32 options) 160 { 161 if (SOC_IS_TOMAHAWKX(unit)){ 162 return _bcm_th_pkt_trace_cpu_profile_set(unit, options); 163 } else if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 164 return _bcm_td3_pkt_trace_cpu_profile_set(unit, options); 165 } 166 return BCM_E_UNAVAIL; 167 } 168 169 /* 170 * Function: 171 * _bcm_esw_pkt_trace_cpu_pkt_profile_get 172 * Purpose: 173 * retrieve cpu profile id to be used for the 174 * next visibility packet 175 * Parameters: 176 * IN : unit 177 * INOUT : profile id 178 * Returns: 179 * BCM_E_XXX 180 */ 181 182 int _bcm_esw_pkt_trace_cpu_profile_get(int unit, uint32* profile_id) 183 { 184 if (SOC_IS_TOMAHAWKX(unit)) { 185 return _bcm_th_pkt_trace_cpu_profile_get(unit, profile_id); 186 } else if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 187 return _bcm_td3_pkt_trace_cpu_profile_get(unit, profile_id); 188 } 189 return BCM_E_UNAVAIL; 190 } 191 192 /* 193 * Function: 194 * _bcm_esw_pkt_trace_info_get 195 * Purpose: 196 * Read visibility packet process data from PTR_RESULTS_BUFFER_IVP, ISW1, 197 * and ISW2 and store into bcm_switch_pkt_trace_info_s * 198 * Parameters: 199 * unit - (IN) Unit number. 200 * pkt_trace_info - (INOUT) visibility pkt trace prcoess result 201 * Returns: 202 * BCM_E_xxx 203 * Notes: 204 */ 205 int _bcm_esw_pkt_trace_info_get(int unit, 206 uint32 options, uint8 port, 207 int len, uint8 *data, 208 bcm_switch_pkt_trace_info_t *pkt_trace_info) 209 { 210 bcm_pkt_t *pkt; 211 int rv = BCM_E_UNAVAIL; 212 int values[6] = {0, 0, 0, 0, 0, 0}; 213 bcm_module_t mod_id = -1; 214 bcm_port_t pp_port = -1; 215 bcm_gport_t gport; 216 bcm_trunk_t tgid; 217 int id; 218 UNIT_VALID_CHECK(unit); 219 220 if (soc_feature(unit, soc_feature_visibility)) { 221 soc_timeout_t to; 222 uint8 num_trial = 0; 223 224 if (pkt_trace_info == NULL || 225 data == NULL) { 226 return BCM_E_PARAM; 227 } 228 memset(pkt_trace_info, 0x0, sizeof(bcm_switch_pkt_trace_info_t)); 229 PKT_TRACE_INIT_CHECK(unit); 230 231 /* mutex lock*/ 232 PKT_TRACE_LOCK(unit); 233 rv = bcm_pkt_alloc(unit, len, 0, &pkt); 234 if (BCM_FAILURE(rv)) { 235 goto clean_up; 236 } 237 pkt->call_back = 0; 238 pkt->blk_count = 1; 239 pkt->unit = unit; 240 241 rv = bcm_pkt_memcpy(pkt, 0, data, len); 242 /*new flag indicating that the packet is for visibility or masquerade */ 243 pkt->flags2 = BCM_PKT_F2_RX_PORT; 244 /* adding visibility option to packet flag */ 245 pkt->flags2 |= BCM_PKT_F2_VISIBILITY_PKT; 246 /* setting pkt trace src port number and profile id on the packet */ 247 pkt->rx_port = port; 248 249 /* Option 'BCM_PKT_TRACE_RETRIEVE_DATA_ONLY' is only supported on 250 * TH3. All other devices should ignore the option. Hence remove it. 251 */ 252 options &= ~BCM_PKT_TRACE_RETRIEVE_DATA_ONLY; 253 254 /* store profile info to be used during tx*/ 255 _bcm_esw_pkt_trace_cpu_profile_set(unit, options); 256 /* Software workaround for TH */ 257 if (SOC_IS_TOMAHAWK(unit) && 258 soc_feature(unit, soc_feature_th_pkt_trace_sw_war)) { 259 rv = _bcm_th_pkt_trace_int_lbport_set(unit, port, 1, values); 260 if (BCM_FAILURE(rv)) { 261 goto clean_up; 262 } 263 } else if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 264 rv = bcm_esw_port_gport_get(unit, 265 port, 266 &gport); 267 268 if (BCM_FAILURE(rv)) { 269 goto clean_up; 270 } 271 rv = _bcm_esw_gport_resolve(unit, gport, 272 &mod_id, &pp_port, 273 &tgid, &id); 274 if (BCM_FAILURE(rv)) { 275 goto clean_up; 276 } 277 rv = _bcm_td3_pkt_trace_source_trunk_map_pp_set(unit, 278 mod_id, 279 pp_port, 280 0); 281 282 if (BCM_FAILURE(rv)) { 283 goto clean_up; 284 } 285 rv =_bcm_td3_pkt_trace_init(unit); 286 if (BCM_FAILURE(rv)) { 287 goto clean_up; 288 } 289 290 rv = _bcm_td3_pkt_trace_dop_config_set(unit); 291 if (BCM_FAILURE(rv)) { 292 goto clean_up; 293 } 294 } 295 296 /* transmit packet -- support only synchronous mode */ 297 rv = bcm_esw_tx(unit, pkt, NULL); 298 if (BCM_FAILURE(rv)) { 299 goto clean_up; 300 } 301 302 /* Software workaround for TH, recover the original configuration */ 303 if (SOC_IS_TOMAHAWK(unit) && 304 soc_feature(unit, soc_feature_th_pkt_trace_sw_war)) { 305 rv =_bcm_th_pkt_trace_int_lbport_set(unit, port, 0, values); 306 if (BCM_FAILURE(rv)) { 307 goto clean_up; 308 } 309 } 310 soc_timeout_init(&to, SECOND_USEC, 0); 311 312 if (SOC_IS_TOMAHAWKX(unit)) { 313 for (;;num_trial++) { 314 rv = _bcm_th_pkt_trace_info_get(unit, pkt_trace_info); 315 if (rv == BCM_E_NONE) { 316 break; 317 } 318 if (soc_timeout_check(&to)) { 319 rv = BCM_E_TIMEOUT; 320 break; 321 } 322 sal_usleep(SECOND_USEC/4); 323 } 324 } else if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 325 for (;;num_trial++) { 326 rv = _bcm_td3_pkt_trace_info_get(unit, pkt_trace_info); 327 if (rv == BCM_E_NONE) { 328 break; 329 } 330 if (soc_timeout_check(&to)) { 331 rv = BCM_E_TIMEOUT; 332 break; 333 } 334 sal_usleep(SECOND_USEC/4); 335 } 336 } 337 if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 338 if (BCM_SUCCESS(rv) && (pp_port > 0)) { 339 rv = _bcm_td3_pkt_trace_source_trunk_map_pp_set(unit, 340 mod_id, 341 pp_port, 342 1); 343 if (BCM_FAILURE(rv)) { 344 goto clean_up; 345 } 346 } 347 } 348 } 349 clean_up: 350 if (soc_feature(unit, soc_feature_visibility)) { 351 if (pkt != NULL) { 352 bcm_pkt_free(unit, pkt); 353 } 354 /*mutex unlock */ 355 PKT_TRACE_UNLOCK(unit); 356 return rv; 357 } 358 359 return rv; 360 } 361 362 /* 363 * Function: 364 * _bcm_esw_pkt_trace_raw_data_get 365 * Purpose: 366 * Read visibility packet trace 367 * debug information as raw data. 368 * Parameters: 369 * unit - (IN) Unit number. 370 * options - (IN) CPU packet profile options for loopback port. 371 * port - (IN) Source Masquered port. 372 * len - (IN) Visibility packet data buffer length. 373 * data - (IN) Visibility packet data buffer. 374 * raw_data_size - (INOUT) Raw data length. 375 * raw_data - (INOUT) Visibility pkt trace raw data. 376 * Returns: 377 * BCM_E_xxx 378 * Notes: 379 */ 380 int _bcm_esw_pkt_trace_raw_data_get(int unit, 381 uint32 options, 382 uint8 port, 383 int len, 384 uint8 *data, 385 uint32 raw_data_buf_size, 386 uint8 *raw_data, 387 uint32 *raw_data_size) 388 { 389 390 bcm_pkt_t *pkt; 391 int rv = BCM_E_UNAVAIL; 392 uint8 num_trial = 0; 393 bcm_module_t mod_id; 394 bcm_port_t pp_port; 395 bcm_gport_t gport; 396 bcm_trunk_t tgid; 397 int id; 398 399 UNIT_VALID_CHECK(unit); 400 401 #if defined(BCM_TOMAHAWK3_SUPPORT) 402 if (SOC_IS_TOMAHAWK3(unit)) { 403 return BCM_E_UNAVAIL; 404 } 405 #endif 406 407 if (soc_feature(unit, soc_feature_visibility)) { 408 soc_timeout_t to; 409 410 if ((raw_data == NULL) || 411 (data == NULL) || 412 (raw_data_size == NULL)) { 413 return BCM_E_PARAM; 414 } 415 if (raw_data_buf_size == 0) { 416 return BCM_E_PARAM; 417 } 418 memset(raw_data, 0x0, raw_data_buf_size); 419 *raw_data_size = raw_data_buf_size; 420 PKT_TRACE_INIT_CHECK(unit); 421 422 /* mutex lock*/ 423 PKT_TRACE_LOCK(unit); 424 BCM_IF_ERROR_RETURN(bcm_pkt_alloc(unit, len, 0, &pkt)); 425 pkt->call_back = 0; 426 pkt->blk_count = 1; 427 pkt->unit = unit; 428 429 rv = bcm_pkt_memcpy(pkt, 0, data, len); 430 /*new flag indicating that the packet is for visibility or masquerade */ 431 pkt->flags2 = BCM_PKT_F2_RX_PORT; 432 /* adding visibility option to packet flag */ 433 pkt->flags2 |= BCM_PKT_F2_VISIBILITY_PKT; 434 /* setting pkt trace src port number and profile id on the packet */ 435 pkt->rx_port = port; 436 437 /* store profile info to be used during tx*/ 438 _bcm_esw_pkt_trace_cpu_profile_set(unit, options); 439 if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 440 SOC_IF_ERROR_RETURN(bcm_esw_port_gport_get(unit, port, 441 &gport)); 442 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, 443 &mod_id, &pp_port, 444 &tgid, &id)); 445 BCM_IF_ERROR_RETURN( 446 _bcm_td3_pkt_trace_source_trunk_map_pp_set(unit, 447 mod_id, 448 pp_port, 449 0)); 450 BCM_IF_ERROR_RETURN(_bcm_td3_pkt_trace_init(unit)); 451 BCM_IF_ERROR_RETURN( 452 _bcm_td3_pkt_trace_dop_config_set(unit)); 453 } 454 455 /* transmit packet -- support only synchronous mode */ 456 BCM_IF_ERROR_RETURN(bcm_esw_tx(unit, pkt, NULL)); 457 soc_timeout_init(&to, SECOND_USEC, 0); 458 459 if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 460 for (;;num_trial++) { 461 rv = _bcm_td3_pkt_trace_raw_data_get(unit, 462 raw_data_size, 463 raw_data); 464 if (rv == BCM_E_NONE) { 465 break; 466 } 467 if (soc_timeout_check(&to)) { 468 rv = BCM_E_TIMEOUT; 469 break; 470 } 471 sal_usleep(SECOND_USEC/4); 472 } 473 } 474 bcm_pkt_free(unit, pkt); 475 if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 476 BCM_IF_ERROR_RETURN( 477 _bcm_td3_pkt_trace_source_trunk_map_pp_set(unit, 478 mod_id, 479 pp_port, 480 1)); 481 482 } 483 /*mutex unlock */ 484 PKT_TRACE_UNLOCK(unit); 485 return rv; 486 } 487 return BCM_E_NONE; 488 } 489 /* 490 * Function: _bcm_esw_pkt_trace_free_resources 491 * Purpose: Free pkt trace resources 492 * Parameters: unit - SOC unit number 493 * Returns: Nothing 494 */ 495 STATIC void 496 _bcm_esw_pkt_trace_free_resources(int unit) 497 { 498 if (_pkt_trace_mlock[unit]) { 499 sal_mutex_destroy(_pkt_trace_mlock[unit]); 500 _pkt_trace_mlock[unit] = NULL; 501 } 502 } 503 504 /* De-initialize pkt trace module */ 505 STATIC int 506 _bcm_esw_pkt_trace_cleanup(int unit) 507 { 508 if (soc_feature(unit, soc_feature_visibility)) { 509 _bcm_esw_pkt_trace_free_resources(unit); 510 511 _pkt_trace_initialized[unit] = FALSE; 512 513 return BCM_E_NONE; 514 } 515 516 return BCM_E_UNAVAIL; 517 } 518 519 /* Initialize pkt trace cpu profile table */ 520 int 521 _bcm_esw_cpu_pkt_profile_init(int unit) 522 { 523 if (SOC_IS_TOMAHAWKX(unit)) { 524 BCM_IF_ERROR_RETURN(_bcm_th_pkt_trace_cpu_profile_init(unit)); 525 return BCM_E_NONE; 526 } else if (SOC_IS_TRIDENT3X(unit)) { 527 BCM_IF_ERROR_RETURN(_bcm_td3_pkt_trace_cpu_profile_init(unit)); 528 return BCM_E_NONE; 529 } 530 return BCM_E_UNAVAIL; 531 } 532 533 /* Initialize pkt trace module */ 534 int 535 bcm_esw_pkt_trace_init(int unit) 536 { 537 UNIT_VALID_CHECK(unit); 538 if (soc_feature(unit, soc_feature_visibility)) { 539 if (_pkt_trace_initialized[unit]) { 540 BCM_IF_ERROR_RETURN(_bcm_esw_pkt_trace_cleanup(unit)); 541 } 542 if (_pkt_trace_mlock[unit] == NULL) { 543 _pkt_trace_mlock[unit] = sal_mutex_create("packet trace mutex"); 544 if (_pkt_trace_mlock[unit] == NULL) { 545 _bcm_esw_pkt_trace_cleanup(unit); 546 return BCM_E_MEMORY; 547 } 548 } 549 _pkt_trace_initialized[unit] = TRUE; 550 551 BCM_IF_ERROR_RETURN(_bcm_esw_cpu_pkt_profile_init(unit)); 552 553 if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 554 BCM_IF_ERROR_RETURN(_bcm_td3_pkt_trace_init(unit)); 555 } 556 return BCM_E_NONE; 557 } 558 return BCM_E_UNAVAIL; 559 } 560 561 #if defined(BCM_TOMAHAWK3_SUPPORT) 562 /* 563 * Function: 564 * _bcm_th3_pkt_trace_info_get 565 * 566 * Purpose: 567 * Generate a visibility packet from the given payload and inject it. 568 * And/Or read the visibility packet's ingress pipeline processing 569 * information from PTR_RESULTS_BUFFER_XXX. Provide back the raw data 570 * and decoded information into the given bcm_switch_pkt_trace_info_t * 571 * 572 * Parameters: 573 * unit - (IN) Unit number. 574 * options - (IN) FLAGS to select pre-configured cpu_pkt_profile register 575 * values and to provide additional instructions to the SDK. 576 * port - (IN) Logical port # to inject and/or read visibility data from. 577 * len - (IN) Length, in bytes, of the given packet. 578 * data - (IN) Packet bytes including the ETH Header. 579 * pkt_trace_info - (OUT) Visibility pkt trace process result 580 * 581 * Returns: 582 * BCM_E_xxx 583 * 584 * Notes: 585 * When options flag - 'BCM_PKT_TRACE_RETRIEVE_DATA_ONLY' is set, 586 * 1) SDK would just retrieve the captured instrumentation data and not 587 * generate/inject any visibility packet. Hence, parameters 'data' and 588 * 'len' are ignored. 589 * 2) Parameter 'port' would accept value '-1'. In such scenario, SDK would 590 * poll data on each ingress pipe and return the first available data. 591 */ 592 int _bcm_th3_pkt_trace_info_get(int unit, uint32 options, 593 uint8 port, int len, uint8 *data, 594 bcm_switch_pkt_trace_info_t *pkt_trace_info) 595 { 596 int rv = BCM_E_UNAVAIL; 597 int pipe = -1; 598 bcm_pkt_t *pkt = NULL; 599 soc_timeout_t to; 600 601 UNIT_VALID_CHECK(unit); 602 603 if (soc_feature(unit, soc_feature_visibility)) { 604 605 /* Check for invalid input */ 606 if (pkt_trace_info == NULL) { 607 return BCM_E_PARAM; 608 } 609 PKT_TRACE_INIT_CHECK(unit); 610 611 if (!(options & BCM_PKT_TRACE_RETRIEVE_DATA_ONLY)) { 612 /* Check if packet payload is not given */ 613 if (NULL == data) { 614 return BCM_E_PARAM; 615 } 616 617 /* Check if the given port is invalid or not addressable */ 618 if (((uint8)-1) == port) { 619 return BCM_E_PORT; 620 } 621 if (!IS_ALL_PORT(unit, port)) { 622 return BCM_E_PORT; 623 } 624 } 625 626 /* If the port is a valid port then extract the pipe from it */ 627 if (((uint8)-1) != port) { 628 if (SOC_FAILURE(soc_port_pipe_get(unit, port, &pipe))) { 629 return BCM_E_PORT; 630 } 631 } 632 633 /* Clear the given buffer to begin-with */ 634 memset(pkt_trace_info, 0x0, sizeof(bcm_switch_pkt_trace_info_t)); 635 636 /* Mutex lock*/ 637 PKT_TRACE_LOCK(unit); 638 639 /* If Caller asked for synchronous mode then send the packet too */ 640 if (!(options & BCM_PKT_TRACE_RETRIEVE_DATA_ONLY)) { 641 642 /* Allocate and fill-in pkt data structure */ 643 BCM_IF_ERROR_RETURN(bcm_pkt_alloc(unit, len, 0, &pkt)); 644 pkt->call_back = 0; 645 pkt->blk_count = 1; 646 pkt->unit = unit; 647 rv = bcm_pkt_memcpy(pkt, 0, data, len); 648 649 /* New flag indicating that the packet is for visibility or masquerade */ 650 pkt->flags2 = BCM_PKT_F2_RX_PORT | BCM_PKT_F2_VISIBILITY_PKT; 651 /* Setting pkt trace src port number in the packet */ 652 pkt->rx_port = port; 653 654 /* Store profile info to be used during tx*/ 655 _bcm_esw_pkt_trace_cpu_profile_set(unit, options); 656 657 /* Transmit packet -- only in synchronous mode */ 658 BCM_IF_ERROR_RETURN(bcm_esw_tx(unit, pkt, NULL)); 659 } 660 661 /* Set the time for timeout */ 662 soc_timeout_init(&to, SECOND_USEC, 0); 663 664 /* Start retrieving the captured information */ 665 for (;;) { 666 rv = 667 _bcm_th3_pkt_trace_info_retrieve_data(unit, pipe, pkt_trace_info); 668 if (rv == BCM_E_NONE) { 669 break; 670 } 671 if (soc_timeout_check(&to)) { 672 rv = BCM_E_TIMEOUT; 673 break; 674 } 675 sal_usleep(SECOND_USEC/4); 676 } 677 678 /* De-allocate the packet if allocated */ 679 if (NULL != pkt) { 680 bcm_pkt_free(unit, pkt); 681 } 682 683 /* Mutex unlock */ 684 PKT_TRACE_UNLOCK(unit); 685 } 686 return rv; 687 } 688 #endif /* BCM_TOMAHAWK3_SUPPORT */ 689 #endif /* BCM_INSTRUMENTATION_SUPPORT */