pstats.c (15248B)
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 * Packetized Statistic 8 * Purpose: API to set Packetized Statistic registers. 9 */ 10 11 #if defined(INCLUDE_PSTATS) 12 13 #include <sal/core/libc.h> 14 15 #include <soc/drv.h> 16 #include <soc/mem.h> 17 #include <soc/debug.h> 18 19 #include <bcm/error.h> 20 #include <bcm/pstats.h> 21 22 #include <bcm_int/esw/pstats.h> 23 #include <bcm_int/esw/trident3.h> 24 #include <bcm_int/esw/tomahawk2.h> 25 #include <bcm_int/esw/helix5.h> 26 #include <bcm_int/esw/tomahawk3.h> 27 #include <bcm_int/esw_dispatch.h> 28 29 #ifdef BCM_WARM_BOOT_SUPPORT 30 #include <bcm_int/esw/switch.h> 31 #endif /* BCM_WARM_BOOT_SUPPORT */ 32 33 _bcm_pstats_unit_driver_t *_bcm_pstats_unit_driver[BCM_MAX_NUM_UNITS]; 34 35 36 /* 37 * Function: 38 * _bcm_pstats_deinit 39 * Purpose: 40 * Deinitialize PSTATS driver functions. 41 * Parameters: 42 * unit - (IN) StrataSwitch unit number. 43 * Returns: 44 * BCM_E_XXX 45 */ 46 void _bcm_pstats_deinit(int unit) 47 { 48 _bcm_pstats_unit_driver_t *pstats_driver; 49 50 pstats_driver = _BCM_PSTATS_UNIT_DRIVER(unit); 51 if (pstats_driver == NULL) { 52 return; 53 } 54 55 #if defined(BCM_HELIX5_SUPPORT) 56 if (SOC_IS_HELIX5(unit)) { 57 (void )bcm_hx5_pstats_deinit(unit); 58 } 59 #endif 60 61 #if defined(BCM_TRIDENT3_SUPPORT) 62 if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_HELIX5(unit)) { 63 (void )bcm_td3_pstats_deinit(unit); 64 } 65 #endif 66 67 #if defined(BCM_TOMAHAWK2_SUPPORT) 68 if (SOC_IS_TOMAHAWK2(unit)) { 69 (void )bcm_th2_pstats_deinit(unit); 70 } 71 #endif 72 #if defined(BCM_TOMAHAWK3_SUPPORT) 73 if (SOC_IS_TOMAHAWK3(unit)) { 74 (void )bcm_th3_pstats_deinit(unit); 75 } 76 #endif 77 78 if (NULL != pstats_driver->pstats_lock) { 79 sal_mutex_destroy(pstats_driver->pstats_lock); 80 } 81 82 if (NULL != pstats_driver) { 83 sal_free(pstats_driver); 84 } 85 _BCM_PSTATS_UNIT_DRIVER(unit) = NULL; 86 87 return; 88 } 89 90 91 /* 92 * Function: 93 * _bcm_pstats_init 94 * Purpose: 95 * Initialize PSTATS driver functions. 96 * Parameters: 97 * unit - (IN) StrataSwitch unit number. 98 * Returns: 99 * BCM_E_XXX 100 */ 101 int _bcm_pstats_init(int unit) 102 { 103 _bcm_pstats_unit_driver_t *pstats_driver; 104 int pstats_supported = 0; 105 int rv = BCM_E_NONE; 106 _bcm_pstats_deinit(unit); 107 pstats_driver = _BCM_PSTATS_UNIT_DRIVER(unit); 108 109 if (NULL == pstats_driver) { 110 pstats_driver = sal_alloc(sizeof(_bcm_pstats_unit_driver_t), "pstats_unit_driver"); 111 if (pstats_driver == NULL) { 112 return BCM_E_MEMORY; 113 } 114 } 115 116 sal_memset(pstats_driver, 0, sizeof(_bcm_pstats_unit_driver_t)); 117 118 _BCM_PSTATS_UNIT_DRIVER(unit) = pstats_driver; 119 120 if (NULL == pstats_driver->pstats_lock) { 121 pstats_driver->pstats_lock = sal_mutex_create("pstats_lock"); 122 } 123 124 if (NULL == pstats_driver->pstats_lock) { 125 (void)_bcm_pstats_deinit(unit); 126 return BCM_E_MEMORY; 127 } 128 129 #if defined(BCM_HELIX5_SUPPORT) 130 if (SOC_IS_HELIX5(unit)) { 131 rv = bcm_hx5_pstats_init(unit); 132 if (BCM_FAILURE(rv)) { 133 (void)_bcm_pstats_deinit(unit); 134 return rv; 135 } 136 pstats_supported = 1; 137 } 138 #endif 139 140 #if defined(BCM_TRIDENT3_SUPPORT) 141 if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_HELIX5(unit)) { 142 rv = bcm_td3_pstats_init(unit); 143 if (BCM_FAILURE(rv)) { 144 (void)_bcm_pstats_deinit(unit); 145 return rv; 146 } 147 pstats_supported = 1; 148 } 149 #endif 150 151 #if defined(BCM_TOMAHAWK2_SUPPORT) 152 if (SOC_IS_TOMAHAWK2(unit)) { 153 rv = bcm_th2_pstats_init(unit); 154 if (BCM_FAILURE(rv)) { 155 (void)_bcm_pstats_deinit(unit); 156 return rv; 157 } 158 pstats_supported = 1; 159 } 160 #endif 161 162 #if defined(BCM_TOMAHAWK3_SUPPORT) 163 if (SOC_IS_TOMAHAWK3(unit)) { 164 rv = bcm_th3_pstats_init(unit); 165 if (BCM_FAILURE(rv)) { 166 (void)_bcm_pstats_deinit(unit); 167 return rv; 168 } 169 pstats_supported = 1; 170 } 171 #endif 172 173 if (pstats_supported == 0) { 174 return BCM_E_UNAVAIL; 175 } 176 return rv; 177 } 178 /* 179 * Function: 180 * bcm_esw_pstats_session_create 181 * Purpose: 182 * Create a PSTATS session instance for SDK management. 183 * Parameters: 184 * unit - (IN) StrataSwitch unit number. 185 * options - (IN) BCM_PSTATS_OPTIONS_REPLACE: replace existing. 186 * BCM_PSTATS_OPTIONS_WITH_ID: session_id argument is given. 187 * array_count - (IN) Number of elements in array. 188 * element_array - (IN) PSTATS session element array. 189 * session_id - (INOUT) id of a PSTATS session created via this API. 190 * Returns: 191 * BCM_E_XXX 192 */ 193 int 194 bcm_esw_pstats_session_create(int unit, int options, int array_count, 195 bcm_pstats_session_element_t *element_array, 196 bcm_pstats_session_id_t *session_id) 197 { 198 int rv = BCM_E_NONE; 199 if (!soc_feature(unit, soc_feature_pstats)) { 200 return BCM_E_UNAVAIL; 201 } 202 203 if (_bcm_pstats_unit_driver[unit]->session_create == NULL) { 204 return BCM_E_UNAVAIL; 205 } 206 207 PSTATS_LOCK(unit); 208 rv = _bcm_pstats_unit_driver[unit]->session_create(unit, options, 209 array_count, 210 element_array, 211 session_id); 212 PSTATS_UNLOCK(unit); 213 return rv; 214 } 215 216 /* 217 * Function: 218 * bcm_esw_pstats_session_destroy 219 * Purpose: 220 * Destroy an existing PSTATS session. 221 * Parameters: 222 * unit - (IN) StrataSwitch unit number. 223 * session_id - (IN) id of a PSTATS session created via the 224 * bcm_pstats_session_create 225 * Returns: 226 * BCM_E_XXX 227 */ 228 int 229 bcm_esw_pstats_session_destroy(int unit, 230 bcm_pstats_session_id_t session_id) 231 { 232 int rv = BCM_E_NONE; 233 if (!soc_feature(unit, soc_feature_pstats)) { 234 return BCM_E_UNAVAIL; 235 } 236 237 if (_bcm_pstats_unit_driver[unit]->session_destroy == NULL) { 238 return BCM_E_UNAVAIL; 239 } 240 241 PSTATS_LOCK(unit); 242 rv = _bcm_pstats_unit_driver[unit]->session_destroy(unit, session_id); 243 PSTATS_UNLOCK(unit); 244 return rv; 245 } 246 247 /* 248 * Function: 249 * bcm_esw_pstats_session_get 250 * Purpose: 251 * Get an existing PSTATS session info. 252 * Parameters: 253 * unit - (IN) StrataSwitch unit number. 254 * session_id - (IN) id of a PSTATS session created via the 255 * bcm_pstats_session_create 256 * array_max - (IN) Maximum number of elements in array. 257 * element_array - (OUT) session elemnts array of a PSTATS session. 258 * array_count - (OUT) Number of elements in array. 259 * Returns: 260 * BCM_E_XXX 261 */ 262 int 263 bcm_esw_pstats_session_get(int unit, 264 bcm_pstats_session_id_t session_id, 265 int array_max, 266 bcm_pstats_session_element_t *element_array, 267 int *array_count) 268 { 269 int rv = BCM_E_NONE; 270 if (!soc_feature(unit, soc_feature_pstats)) { 271 return BCM_E_UNAVAIL; 272 } 273 274 if (_bcm_pstats_unit_driver[unit]->session_get == NULL) { 275 return BCM_E_UNAVAIL; 276 } 277 278 PSTATS_LOCK(unit); 279 rv = _bcm_pstats_unit_driver[unit]->session_get(unit, session_id, array_max, 280 element_array, 281 array_count); 282 PSTATS_UNLOCK(unit); 283 return rv; 284 } 285 286 /* 287 * Function: 288 * bcm_esw_pstats_data_sync 289 * Purpose: 290 * Start a pstats sync operation. 291 * Parameters: 292 * unit - (IN) StrataSwitch unit number 293 * Returns: 294 * BCM_E_XXX 295 */ 296 int 297 bcm_esw_pstats_data_sync(int unit) 298 { 299 int rv = BCM_E_NONE; 300 if (!soc_feature(unit, soc_feature_pstats)) { 301 return BCM_E_UNAVAIL; 302 } 303 304 if (_bcm_pstats_unit_driver[unit]->data_sync == NULL) { 305 return BCM_E_UNAVAIL; 306 } 307 308 PSTATS_LOCK(unit); 309 rv = _bcm_pstats_unit_driver[unit]->data_sync(unit); 310 PSTATS_UNLOCK(unit); 311 return rv; 312 } 313 314 /* 315 * Function: 316 * bcm_esw_pstats_session_data_get 317 * Purpose: 318 * Get an existing PSTATS session data. 319 * Parameters: 320 * unit - (IN) StrataSwitch unit number 321 * session_id - (IN) id of a PSTATS session created via the 322 * bcm_pstats_session_create 323 * timestamp - (OUT) time stamp info. 324 * array_max - (IN) Maximum number of elements in array. 325 * data - (OUT) array of use count data. 326 * array_count - (OUT) Number of elements in array. 327 * Returns: 328 * BCM_E_XXX 329 */ 330 int 331 bcm_esw_pstats_session_data_get(int unit, bcm_pstats_session_id_t session_id, 332 bcm_pstats_timestamp_t *timestamp, 333 int array_max, 334 bcm_pstats_data_t *data_array, 335 int *array_count) 336 { 337 int rv = BCM_E_NONE; 338 if (!soc_feature(unit, soc_feature_pstats)) { 339 return BCM_E_UNAVAIL; 340 } 341 342 if (_bcm_pstats_unit_driver[unit]->session_data_get == NULL) { 343 return BCM_E_UNAVAIL; 344 } 345 346 PSTATS_LOCK(unit); 347 rv = _bcm_pstats_unit_driver[unit]->session_data_get(unit, session_id, 348 FALSE, 349 timestamp, 350 array_max, 351 data_array, 352 array_count); 353 PSTATS_UNLOCK(unit); 354 return rv; 355 } 356 357 /* 358 * Function: 359 * bcm_esw_pstats_session_data_sync_get 360 * Purpose: 361 * Get an existing PSTATS session data. 362 * Parameters: 363 * unit - (IN) StrataSwitch unit number 364 * session_id - (IN) id of a PSTATS session created via the 365 * bcm_pstats_session_create 366 * timestamp - (OUT) time stamp info. 367 * array_max - (IN) Maximum number of elements in array. 368 * data - (OUT) array of use count data. 369 * array_count - (OUT) Number of elements in array. 370 * Returns: 371 * BCM_E_XXX 372 */ 373 int 374 bcm_esw_pstats_session_data_sync_get(int unit, bcm_pstats_session_id_t session_id, 375 bcm_pstats_timestamp_t *timestamp, 376 int array_max, 377 bcm_pstats_data_t *data_array, 378 int *array_count) 379 { 380 int rv = BCM_E_NONE; 381 if (!soc_feature(unit, soc_feature_pstats)) { 382 return BCM_E_UNAVAIL; 383 } 384 385 if (_bcm_pstats_unit_driver[unit]->session_data_get == NULL) { 386 return BCM_E_UNAVAIL; 387 } 388 389 PSTATS_LOCK(unit); 390 rv = _bcm_pstats_unit_driver[unit]->session_data_get(unit, session_id, 391 TRUE, 392 timestamp, 393 array_max, 394 data_array, 395 array_count); 396 PSTATS_UNLOCK(unit); 397 return rv; 398 } 399 400 /* 401 * Function: 402 * bcm_pstats_session_data_clear 403 * Purpose: 404 * Clear an existing PSTATS session hw use counts and sw use counts buffer. 405 * Parameters: 406 * unit - (IN) StrataSwitch unit number. 407 * session_id - (IN) id of a PSTATS session created via the 408 * bcm_pstats_session_create. 409 * Returns: 410 * BCM_E_XXX 411 */ 412 int 413 bcm_esw_pstats_session_data_clear(int unit, bcm_pstats_session_id_t session_id) 414 { 415 int rv = BCM_E_NONE; 416 if (!soc_feature(unit, soc_feature_pstats)) { 417 return BCM_E_UNAVAIL; 418 } 419 420 if (_bcm_pstats_unit_driver[unit]->session_data_clear == NULL) { 421 return BCM_E_UNAVAIL; 422 } 423 424 PSTATS_LOCK(unit); 425 rv = _bcm_pstats_unit_driver[unit]->session_data_clear(unit, session_id); 426 PSTATS_UNLOCK(unit); 427 return rv; 428 } 429 430 #ifdef BCM_WARM_BOOT_SUPPORT 431 /* 432 * Function: 433 * _bcm_esw_pstats_scache_size_get 434 * Purpose: 435 * Get scache size of PSTATS module persisitent info for Level 2 Warm Boot. 436 * Parameters: 437 * unit - StrataSwitch unit number. 438 * scache_size - scache size. 439 * Returns: 440 * BCM_E_XXX 441 */ 442 int 443 _bcm_esw_pstats_scache_size_get(int unit, uint32 *scache_size) 444 { 445 if (!soc_feature(unit, soc_feature_pstats)) { 446 return BCM_E_UNAVAIL; 447 } 448 if (_bcm_pstats_unit_driver[unit]->scache_size_get == NULL) { 449 return BCM_E_UNAVAIL; 450 } 451 return _bcm_pstats_unit_driver[unit]->scache_size_get(unit, scache_size); 452 } 453 /* 454 * Function: 455 * _bcm_esw_pstats_reinit 456 * Purpose: 457 * Reinit PSTATS module persisitent info for Level 2 Warm Boot. 458 * Parameters: 459 * unit - StrataSwitch unit number. 460 * scache_ptr - scache pointer 461 * Returns: 462 * BCM_E_XXX 463 */ 464 int 465 _bcm_esw_pstats_reinit(int unit, uint8 **scache_ptr) 466 { 467 if (!soc_feature(unit, soc_feature_pstats)) { 468 return BCM_E_UNAVAIL; 469 } 470 if (_bcm_pstats_unit_driver[unit]->pstats_reinit == NULL) { 471 return BCM_E_UNAVAIL; 472 } 473 return _bcm_pstats_unit_driver[unit]->pstats_reinit(unit, scache_ptr); 474 } 475 /* 476 * Function: 477 * _bcm_esw_pstats_sync 478 * Purpose: 479 * Record PSTATS module persisitent info for Level 2 Warm Boot. 480 * Parameters: 481 * unit - StrataSwitch unit number. 482 * Returns: 483 * BCM_E_XXX 484 */ 485 int 486 _bcm_esw_pstats_sync(int unit, uint8 **scache_ptr) 487 { 488 if (!soc_feature(unit, soc_feature_pstats)) { 489 return BCM_E_UNAVAIL; 490 } 491 if (_bcm_pstats_unit_driver[unit]->pstats_sync == NULL) { 492 return BCM_E_UNAVAIL; 493 } 494 return _bcm_pstats_unit_driver[unit]->pstats_sync(unit, scache_ptr); 495 } 496 #endif 497 498 /* 499 * Function: 500 * bcm_esw_pstats_session_traverse 501 * Purpose: 502 * Traverse through the pstats sessions and run callback at each session. 503 * Parameters: 504 * unit - (IN) StrataSwitch unit number. 505 * cb - (IN) bcm_pstats_session_traverse_cb. 506 * user_data - (IN) User data to be passed to callback function. 507 * Returns: 508 * BCM_E_XXX 509 */ 510 int 511 bcm_esw_pstats_session_traverse(int unit, bcm_pstats_session_traverse_cb cb, 512 void *user_data) 513 { 514 int rv = BCM_E_NONE; 515 if (!soc_feature(unit, soc_feature_pstats)) { 516 return BCM_E_UNAVAIL; 517 } 518 519 if (_bcm_pstats_unit_driver[unit]->session_traverse == NULL) { 520 return BCM_E_UNAVAIL; 521 } 522 523 PSTATS_LOCK(unit); 524 rv = _bcm_pstats_unit_driver[unit]->session_traverse(unit, cb, user_data); 525 PSTATS_UNLOCK(unit); 526 return rv; 527 } 528 529 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP 530 /* 531 * Function: 532 * bcm_esw_pstats_sw_dump 533 * Purpose: 534 * Displays PSTATS information maintained by software. 535 * Parameters: 536 * unit - Device unit number 537 * Returns: 538 * None 539 */ 540 void 541 _bcm_esw_pstats_sw_dump(int unit) 542 { 543 if (!soc_feature(unit, soc_feature_pstats)) { 544 return; 545 } 546 if (_bcm_pstats_unit_driver[unit]->pstats_sw_dump == NULL) { 547 return; 548 } 549 return _bcm_pstats_unit_driver[unit]->pstats_sw_dump(unit); 550 } 551 #endif 552 553 #else /* INCLUDE_PSTATS */ 554 int bcm_esw_pstats_not_empty; 555 #endif /* INCLUDE_PSTATS */