shr_template.c (109682B)
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 * Global template management 9 */ 10 11 #include <shared/bsl.h> 12 13 #include <sal/core/sync.h> 14 #include <shared/shr_template.h> 15 #include <shared/error.h> 16 17 #if defined(BCM_PETRA_SUPPORT) 18 #include <soc/cm.h> 19 #include <soc/dpp/SAND/Utils/sand_os_interface.h> 20 #include <soc/dpp/SAND/Utils/sand_multi_set.h> 21 #include <bcm_int/dpp/error.h> 22 #include <shared/swstate/access/sw_state_access.h> 23 24 /*****************************************************************************/ 25 /* 26 * Internal implementation 27 */ 28 29 /* Sw state access macro. */ 30 #define TEMPLATE_ACCESS sw_state_access[unit].dpp.shr.template_info 31 32 33 #define SHR_TEMPLATE_MAX_BUFFER_SIZE_FOR_PRINT 2048 34 35 /* A handle for a non-unit-based template manager instance */ 36 typedef struct _shr_template_unit_desc_s *shr_mtemplate_handle_t; 37 38 39 /* 40 * Various function prototypes per method for the alloc managers. 41 */ 42 typedef int (*_shr_template_manage_create)(int unit, 43 int pool_id, 44 int template_low_id, 45 int template_count, 46 int max_entities, 47 uint32 global_max, 48 size_t data_size, 49 const void *extras, 50 const char *name); 51 typedef int (*_shr_template_manage_destroy)(int unit, int pool_id); 52 typedef int (*_shr_template_manage_alloc)(int unit, 53 int pool_id, 54 uint32 flags, 55 const void* data, 56 int *is_allocated, 57 int *template); 58 typedef int (*_shr_template_manage_alloc_group)(int unit, 59 int pool_id, 60 uint32 flags, 61 const void* data, 62 int nof_additions, 63 int *is_allocated, 64 int *template); 65 typedef int (*_shr_template_manage_exchange)(int unit, 66 int pool_id, 67 uint32 flags, 68 const void *data, 69 int old_template, 70 int *is_last, 71 int *template, 72 int *is_allocated); 73 typedef int (*_shr_template_manage_exchange_test)(int unit, 74 int pool_id, 75 uint32 flags, 76 const void *data, 77 int old_template, 78 int *is_last, 79 int *template, 80 int *is_allocated); 81 typedef int (*_shr_template_manage_free)(int unit, 82 int pool_id, 83 int template, 84 int *is_free); 85 typedef int (*_shr_template_manage_free_group)(int unit, 86 int pool_id, 87 int template, 88 int nof_deductions, 89 int *is_free); 90 typedef int (*_shr_template_manage_data_get)(int unit, 91 int pool_id, 92 int template, 93 void *data); 94 typedef int (*_shr_template_manage_index_get)(int unit, 95 int pool_id, 96 const void *data, 97 int *template); 98 typedef int (*_shr_template_manage_ref_count_get)(int unit, 99 int pool_id, 100 int template, 101 uint32 *ref_count); 102 typedef int (*_shr_template_manage_clear)(int unit, int pool_id); 103 104 /* 105 * This structure describes a single allocator mechanism, specifically by 106 * providing a set pointers to functions that are used to manipulate it. 107 */ 108 typedef struct _shr_template_managements_s { 109 _shr_template_manage_create create; 110 _shr_template_manage_destroy destroy; 111 _shr_template_manage_alloc alloc; 112 _shr_template_manage_alloc_group alloc_group; 113 _shr_template_manage_exchange exchange; 114 _shr_template_manage_exchange_test exchange_test; 115 _shr_template_manage_free free; 116 _shr_template_manage_free_group free_group; 117 _shr_template_manage_data_get data_get; 118 _shr_template_manage_ref_count_get ref_count_get; 119 _shr_template_manage_clear clear; 120 _shr_template_manage_index_get index_get; 121 char *name; 122 } _shr_template_managements_t; 123 124 /* 125 * These prototypes are for the global const structure below that points to 126 * all of the various implementations. 127 */ 128 static int _shr_template_hash_create(int unit, 129 int pool_id, 130 int template_low_id, 131 int template_count, 132 int max_entities, 133 uint32 global_max, 134 size_t data_size, 135 const void *extras, 136 const char *name); 137 static int _shr_template_hash_destroy(int unit, int pool_id); 138 static int _shr_template_hash_alloc(int unit, 139 int pool_id, 140 uint32 flags, 141 const void* data, 142 int *is_allocated, 143 int *template); 144 static int _shr_template_hash_alloc_group(int unit, 145 int pool_id, 146 uint32 flags, 147 const void* data, 148 int nof_additions, 149 int *is_allocated, 150 int *template); 151 static int _shr_template_hash_free(int unit, 152 int pool_id, 153 int template, 154 int *is_last); 155 static int _shr_template_hash_free_group(int unit, 156 int pool_id, 157 int template, 158 int nof_deductions, 159 int *is_last); 160 static int _shr_template_hash_exchange(int unit, 161 int pool_id, 162 uint32 flags, 163 const void *data, 164 int old_template, 165 int *is_last, 166 int *template, 167 int *is_allocated); 168 static int _shr_template_hash_exchange_test(int unit, 169 int pool_id, 170 uint32 flags, 171 const void *data, 172 int old_template, 173 int *is_last, 174 int *template, 175 int *is_allocated); 176 static int _shr_template_hash_data_get(int unit, 177 int pool_id, 178 int template, 179 void *data); 180 static int _shr_template_hash_ref_count_get(int unit, 181 int pool_id, 182 int template, 183 uint32 *ref_count); 184 static int _shr_template_hash_clear(int unit, int pool_id); 185 static int _shr_template_hash_index_get(int unit, 186 int pool_id, 187 const void *data, 188 int* template); 189 /* 190 * Global const structure describing the various allocator mechanisms. 191 */ 192 static const _shr_template_managements_t _shr_template_managements_mgrs[SHR_TEMPLATE_MANAGE_COUNT] = 193 { 194 { 195 _shr_template_hash_create, 196 _shr_template_hash_destroy, 197 _shr_template_hash_alloc, 198 _shr_template_hash_alloc_group, 199 _shr_template_hash_exchange, 200 _shr_template_hash_exchange_test, 201 _shr_template_hash_free, 202 _shr_template_hash_free_group, 203 _shr_template_hash_data_get, 204 _shr_template_hash_ref_count_get, 205 _shr_template_hash_clear, 206 _shr_template_hash_index_get, 207 "SHR_TEMPLATE_MANAGE_HASH" 208 } /* hash */ 209 }; 210 211 /* 212 * Global array holding the callbacks to the to_stream and from_stream functions. 213 * Should be filled when template manager is started. 214 */ 215 static shr_template_to_stream_t *hash_compare_to_stream_cb[BCM_MAX_NUM_UNITS]; 216 static shr_template_from_stream_t *hash_compare_from_stream_cb[BCM_MAX_NUM_UNITS]; 217 218 219 /* 220 * Basic checks performed for many functions 221 */ 222 #define SW_STATE_ACCESS_ERROR_CHECK(rv) \ 223 if (rv != _SHR_E_NONE) { \ 224 LOG_ERROR(BSL_LS_SOC_COMMON, \ 225 (BSL_META("Error in sw state access\n"))); \ 226 return _SHR_E_INTERNAL; \ 227 } 228 229 230 #define SW_STATE_ACCESS_ERROR_CHECK_NO_RET(rv) \ 231 if (rv != _SHR_E_NONE) { \ 232 LOG_ERROR(BSL_LS_SOC_COMMON, \ 233 (BSL_META("Error in sw state access\n"))); \ 234 rv = _SHR_E_INTERNAL; \ 235 goto err; \ 236 } 237 238 #define TEMPLATE_UNIT_CHECK(_unit) \ 239 {\ 240 uint8 _exists;\ 241 if ((0 > (_unit)) || (BCM_LOCAL_UNITS_MAX <= (_unit))) { \ 242 LOG_ERROR(BSL_LS_SOC_COMMON, \ 243 (BSL_META_U(_unit, \ 244 "invalid unit number %d\n"), \ 245 _unit)); \ 246 return BCM_E_PARAM; \ 247 } \ 248 SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.is_allocated(_unit, &_exists)); \ 249 if (!_exists) { \ 250 LOG_ERROR(BSL_LS_SOC_COMMON, \ 251 (BSL_META_U(_unit, \ 252 "unit %d is not initialised\n"), \ 253 _unit)); \ 254 return BCM_E_INIT; \ 255 } \ 256 } 257 258 #define TEMPLATE_POOL_VALID_CHECK(_unit, _pool) \ 259 {\ 260 uint16 _templatePoolCount;\ 261 SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.templatePoolCount.get(_unit, &_templatePoolCount)); \ 262 if ((0 > (_pool)) || (_templatePoolCount <= (_pool))) { \ 263 LOG_ERROR(BSL_LS_SOC_COMMON, \ 264 (BSL_META("unit %d pool %d does not exist\n"), \ 265 _unit, _pool)); \ 266 return BCM_E_PARAM; \ 267 }\ 268 } 269 #define TEMPLATE_POOL_EXIST_CHECK(_unit, _pool) \ 270 {\ 271 uint8 _exists;\ 272 SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.pool.is_allocated(_unit, _pool, &_exists)); \ 273 if (!_exists) { \ 274 LOG_ERROR(BSL_LS_SOC_COMMON, \ 275 (BSL_META("unit %d pool %d is not configured\n"), \ 276 _unit, _pool)); \ 277 return BCM_E_CONFIG; \ 278 }\ 279 } 280 #define TEMPLATE_TYPE_VALID_CHECK(_unit, _type) \ 281 {\ 282 uint16 _templateTypeCount;\ 283 SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.templateTypeCount.get(_unit, &_templateTypeCount)); \ 284 if ((0 > (_type)) || (_templateTypeCount <= (_type))) { \ 285 LOG_ERROR(BSL_LS_SOC_COMMON, \ 286 (BSL_META("unit %d template %d does not exist\n"), \ 287 _unit, _type)); \ 288 return BCM_E_PARAM; \ 289 }\ 290 } 291 #define TEMPLATE_TYPE_EXIST_CHECK(_unit, _type) \ 292 {\ 293 uint8 _exists;\ 294 SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.template_param.is_allocated(_unit, _type, &_exists)); \ 295 if (!_exists) { \ 296 LOG_ERROR(BSL_LS_SOC_COMMON, \ 297 (BSL_META("unit %d template %d is not configured\n"), \ 298 _unit, _type)); \ 299 return BCM_E_CONFIG; \ 300 }\ 301 } 302 #define TEMPLATE_PARAM_NULL_CHECK(_unit, _param) \ 303 if ((_param) == NULL) { \ 304 LOG_ERROR(BSL_LS_SOC_COMMON, \ 305 (BSL_META("unit %d template with obligatory argument is NULL\n"), \ 306 _unit)); \ 307 return BCM_E_PARAM; \ 308 } 309 #define TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(_unit,_thisPool,_template) \ 310 {\ 311 int _template_low_id, _template_count; \ 312 SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.pool.template_low_id.get(_unit, _thisPool, &_template_low_id)); \ 313 SW_STATE_ACCESS_ERROR_CHECK(TEMPLATE_ACCESS.pool.template_count.get(_unit, _thisPool, &_template_count)); \ 314 if (!(_template >= _template_low_id && _template <= (_template_low_id + _template_count-1))) { \ 315 LOG_ERROR(BSL_LS_SOC_COMMON, \ 316 (BSL_META("_template id %d is not in correct range. Should be between thisPool.template_low_id %d template_count %d\n") \ 317 , _template, _template_low_id, (_template_low_id + _template_count-1))); \ 318 return BCM_E_PARAM; \ 319 }\ 320 } 321 322 323 /* Mtemplate_* prototypes */ 324 static int 325 shr_mtemplate_alloc(int unit, 326 int template_type, 327 uint32 flags, 328 const void *data, 329 int *is_allocated, 330 int *template); 331 static int 332 shr_mtemplate_alloc_group(int unit, 333 int template_type, 334 uint32 flags, 335 const void *data, 336 int nof_additions, 337 int *is_allocated, 338 int *template); 339 static int 340 shr_mtemplate_free(int unit, 341 int template_type, 342 int template, 343 int *is_last); 344 static int 345 shr_mtemplate_free_group(int unit, 346 int template_type, 347 int template, 348 int nof_deductions, 349 int *is_last); 350 static int 351 shr_mtemplate_exchange(int unit, 352 int template_type, 353 uint32 flags, 354 const void *data, 355 int old_template, 356 int *is_last, 357 int *template, 358 int *is_allocated); 359 static int 360 shr_mtemplate_exchange_test(int unit, 361 int template_type, 362 uint32 flags, 363 const void *data, 364 int old_template, 365 int *is_last, 366 int *template, 367 int *is_allocated); 368 static int 369 shr_mtemplate_data_get(int unit, 370 int template_type, 371 int template, 372 void *data); 373 static int 374 shr_mtemplate_index_get(int unit, 375 int template_type, 376 const void *data, 377 int *template); 378 static int 379 shr_mtemplate_ref_count_get(int unit, 380 int template_type, 381 int template, 382 uint32 *ref_count); 383 static int 384 shr_mtemplate_create(int unit, 385 int num_template_types, 386 int num_template_pools, 387 shr_template_to_stream_t *to_stream_cb_arr, 388 shr_template_from_stream_t *from_stream_cb_arr, 389 int cb_arr_length); 390 static int 391 shr_mtemplate_get(int unit, 392 int *num_template_types, 393 int *num_template_pools); 394 static int 395 shr_mtemplate_pool_set(int unit, 396 int pool_id, 397 shr_template_manage_t manager, 398 int template_low_id, 399 int template_count, 400 int max_entities, 401 uint32 global_max, 402 size_t data_size, 403 const void *extras, 404 const char *name); 405 static int 406 shr_mtemplate_pool_get(int unit, 407 int pool_id, 408 shr_template_manage_t *manager, 409 int *template_low_id, 410 int *template_count, 411 int *max_entities, 412 size_t *data_size, 413 shr_template_manage_hash_compare_extras_t *extras, 414 sw_state_template_name_t *name); 415 static int 416 shr_mtemplate_pool_unset(int unit, 417 int pool_id); 418 static int 419 shr_mtemplate_type_set(int unit, 420 int template_type, 421 int pool_id, 422 const char *name); 423 static int 424 shr_mtemplate_type_get(int unit, 425 int template_type, 426 int *pool_id, 427 sw_state_template_name_t *name); 428 static int 429 shr_mtemplate_type_unset(int unit, 430 int template_id); 431 static int 432 _shr_mtemplate_destroy_data(int unit); 433 static int 434 shr_mtemplate_dump(int unit, int template_type); 435 static int 436 shr_mtemplate_clear(int unit, int template_type); 437 438 /*****************************************************************************/ 439 /* 440 * Exposed API implementation (unit based) 441 */ 442 443 /* 444 * Initialize the tamplate manager for the unit 445 */ 446 int 447 shr_template_init(int unit, 448 int num_template_types, 449 int num_template_pools, 450 shr_template_to_stream_t *to_stream_cb_arr, 451 shr_template_from_stream_t *from_stream_cb_arr, 452 int cb_arr_length) 453 { 454 int result = BCM_E_NONE; 455 uint8 exists; 456 457 LOG_DEBUG(BSL_LS_SOC_COMMON, 458 (BSL_META_U(unit, 459 "(%d, %d, %d) enter\n"), 460 unit, 461 num_template_types, 462 num_template_pools)); 463 464 /* a little parameter checking */ 465 if ((0 > unit) || (BCM_LOCAL_UNITS_MAX <= unit)) { 466 LOG_ERROR(BSL_LS_SOC_COMMON, 467 (BSL_META_U(unit, 468 "invalid unit number %d\n"), 469 unit)); 470 return BCM_E_PARAM; 471 } 472 473 /* get this unit's current information, mark it as destroyed */ 474 result = TEMPLATE_ACCESS.is_allocated(unit, &exists); 475 SW_STATE_ACCESS_ERROR_CHECK(result); 476 477 if (exists) { 478 /* this unit has already been initialised; tear it down */ 479 result = _shr_mtemplate_destroy_data(unit); 480 } /* if (exists) */ 481 482 483 if (BCM_E_NONE == result) { 484 result = shr_mtemplate_create(unit, 485 num_template_types, 486 num_template_pools, 487 to_stream_cb_arr, 488 from_stream_cb_arr, 489 cb_arr_length); 490 } /* if (BCM_E_NONE == result) */ 491 492 /* return the result */ 493 LOG_DEBUG(BSL_LS_SOC_COMMON, 494 (BSL_META_U(unit, 495 "(%d, %d, %d) return %d (%s)\n"), 496 unit, 497 num_template_types, 498 num_template_pools, 499 result, 500 _SHR_ERRMSG(result))); 501 return result; 502 } 503 504 /* 505 * Get number of template pools and types configured for a unit 506 */ 507 int 508 shr_template_get(int unit, 509 int *num_template_types, 510 int *num_template_pools) 511 { 512 /* a little parameter checking */ 513 TEMPLATE_UNIT_CHECK(unit); 514 515 /* perform the fetch */ 516 return shr_mtemplate_get(unit, num_template_types, num_template_pools); 517 } 518 519 /* 520 * Configure a template pool for the unit 521 */ 522 int 523 shr_template_pool_set(int unit, 524 int pool_id, 525 shr_template_manage_t manager, 526 int template_low_id, 527 int template_count, 528 int max_entities, 529 uint32 global_max, 530 size_t data_size, 531 const void *extras, 532 const char *name) 533 { 534 /* a little parameter checking */ 535 TEMPLATE_UNIT_CHECK(unit); 536 537 /* perform the action */ 538 return shr_mtemplate_pool_set(unit, 539 pool_id, 540 manager, 541 template_low_id, 542 template_count, 543 max_entities, 544 global_max, 545 data_size, 546 extras, 547 name); 548 } 549 550 /* 551 * Get configuration for a resource pool on a particular unit 552 */ 553 int 554 shr_template_pool_get(int unit, 555 int pool_id, 556 shr_template_manage_t *manager, 557 int *template_low_id, 558 int *template_count, 559 int *max_entities, 560 size_t *data_size, 561 shr_template_manage_hash_compare_extras_t *extras, 562 sw_state_template_name_t *name) 563 { 564 /* a little parameter checking */ 565 TEMPLATE_UNIT_CHECK(unit); 566 567 /* perform the action */ 568 return shr_mtemplate_pool_get(unit, 569 pool_id, 570 manager, 571 template_low_id, 572 template_count, 573 max_entities, 574 data_size, 575 extras, 576 name); 577 } 578 579 /* 580 * Destroy a template pool on a unit 581 */ 582 int 583 shr_template_pool_unset(int unit, 584 int pool_id) 585 { 586 /* a little parameter checking */ 587 TEMPLATE_UNIT_CHECK(unit); 588 589 /* perform the action */ 590 return shr_mtemplate_pool_unset(unit, pool_id); 591 } 592 593 /* 594 * Configure a template type 595 */ 596 int 597 shr_template_type_set(int unit, 598 int template_type, 599 int pool_id, 600 const char *name) 601 { 602 /* a little parameter checking */ 603 TEMPLATE_UNIT_CHECK(unit); 604 605 /* perform the action */ 606 return shr_mtemplate_type_set(unit, template_type, pool_id, name); 607 } 608 609 /* 610 * Get information about a template type 611 */ 612 extern int 613 shr_template_type_get(int unit, 614 int template_type, 615 int *pool_id, 616 sw_state_template_name_t *name) 617 { 618 /* a little parameter checking */ 619 TEMPLATE_UNIT_CHECK(unit); 620 621 /* perform the action */ 622 return shr_mtemplate_type_get(unit, template_type, pool_id, name); 623 } 624 625 626 /* 627 * Destroy a template type on a unit 628 */ 629 int 630 shr_template_type_unset(int unit, 631 int template_id) 632 { 633 /* a little parameter checking */ 634 TEMPLATE_UNIT_CHECK(unit); 635 636 /* perform the action */ 637 return shr_mtemplate_type_unset(unit, template_id); 638 } 639 640 /* 641 * Remove all template management for a unit 642 */ 643 int 644 shr_template_detach(int unit) 645 { 646 int result = BCM_E_NONE; 647 uint8 exists; 648 649 650 LOG_DEBUG(BSL_LS_SOC_COMMON, 651 (BSL_META_U(unit, 652 "(%d) enter\n"), 653 unit)); 654 655 /* get this unit's current information, mark it as destroyed */ 656 result = TEMPLATE_ACCESS.is_allocated(unit, &exists); 657 SW_STATE_ACCESS_ERROR_CHECK(result); 658 659 if (exists) { 660 /* this unit has already been initialised; tear it down */ 661 result = _shr_mtemplate_destroy_data(unit); 662 } /* if (exists) */ 663 /* else would be not inited, again, easy to detach in that case - NOP */ 664 665 /* return the result */ 666 LOG_DEBUG(BSL_LS_SOC_COMMON, 667 (BSL_META_U(unit, 668 "(%d) return %d (%s)\n"), 669 unit, 670 result, 671 _SHR_ERRMSG(result))); 672 return result; 673 } 674 675 /* 676 * Find a template to assign to the requested data. 677 */ 678 int 679 shr_template_allocate(int unit, 680 int template_type, 681 uint32 flags, 682 const void *data, 683 int *is_allocated, 684 int *template) 685 { 686 /* a little parameter checking */ 687 TEMPLATE_UNIT_CHECK(unit); 688 689 /* perform the action */ 690 return shr_mtemplate_alloc(unit, template_type, flags, data, is_allocated, template); 691 } 692 693 /* 694 * Find a template to assign to the requested data for a group of elements. 695 */ 696 int 697 shr_template_allocate_group(int unit, 698 int template_type, 699 uint32 flags, 700 const void *data, 701 int nof_additions, 702 int *is_allocated, 703 int *template) 704 { 705 /* a little parameter checking */ 706 TEMPLATE_UNIT_CHECK(unit); 707 708 /* perform the action */ 709 return shr_mtemplate_alloc_group(unit, template_type, flags, data, nof_additions, is_allocated, template); 710 } 711 712 /* 713 * Release a template (referrer no longer points to it) 714 */ 715 extern int 716 shr_template_free(int unit, 717 int template_type, 718 int template, 719 int *is_last) 720 { 721 /* a little parameter checking */ 722 TEMPLATE_UNIT_CHECK(unit); 723 724 /* perform the action */ 725 return shr_mtemplate_free(unit, template_type, template, is_last); 726 } 727 728 /* 729 * Release several template referers (referrer no longer points to it) 730 */ 731 extern int 732 shr_template_free_group(int unit, 733 int template_type, 734 int template, 735 int nof_deductions, 736 int *is_last) 737 { 738 /* a little parameter checking */ 739 TEMPLATE_UNIT_CHECK(unit); 740 741 /* perform the action */ 742 return shr_mtemplate_free_group(unit, template_type, template, nof_deductions, is_last); 743 } 744 745 /* 746 * Free a current template and allocate a new one for new data 747 */ 748 int 749 shr_template_exchange(int unit, 750 int template_type, 751 uint32 flags, 752 const void *data, 753 int old_template, 754 int *is_last, 755 int *template, 756 int *is_allocated) 757 { 758 /* a little parameter checking */ 759 TEMPLATE_UNIT_CHECK(unit); 760 761 /* perform the action */ 762 return shr_mtemplate_exchange(unit, template_type, flags, data, old_template, is_last, template, is_allocated); 763 } 764 765 /* 766 * Tests if Free a current template and allocate a new one for new data is possible 767 */ 768 int 769 shr_template_exchange_test(int unit, 770 int template_type, 771 uint32 flags, 772 const void *data, 773 int old_template, 774 int *is_last, 775 int *template, 776 int *is_allocated) 777 { 778 /* a little parameter checking */ 779 TEMPLATE_UNIT_CHECK(unit); 780 781 /* perform the action */ 782 return shr_mtemplate_exchange_test(unit, template_type, flags, data, old_template, is_last, template, is_allocated); 783 } 784 785 /* 786 * Function 787 * shr_template_data_get 788 * Purpose 789 * Get the data from a specific template 790 * Parameters 791 * (IN) unit : unit number of the device 792 * (IN) template_type : which template type to use 793 * (IN) template : which template to get 794 * (OUT) data : where to put the template's data 795 * Returns 796 * BCM_E_NONE if successful 797 * BCM_E_* as appropriate otherwise 798 * Notes 799 */ 800 int 801 shr_template_data_get(int unit, 802 int template_type, 803 int template, 804 void *data) 805 { 806 /* a little parameter checking */ 807 TEMPLATE_UNIT_CHECK(unit); 808 809 /* perform the action */ 810 return shr_mtemplate_data_get(unit, template_type, template, data); 811 } 812 813 /* 814 * Function 815 * shr_template_template_get 816 * Purpose 817 * Get the template from a specific data 818 * Parameters 819 * (IN) unit : unit number of the device 820 * (IN) template_type : which template type to use 821 * (IN) data : the template's data 822 * (OUT) template : which template 823 * Returns 824 * BCM_E_NONE if successful 825 * BCM_E_* as appropriate otherwise 826 * Notes 827 */ 828 int 829 shr_template_template_get(int unit, 830 int template_type, 831 const void *data, 832 int *template) 833 { 834 /* a little parameter checking */ 835 TEMPLATE_UNIT_CHECK(unit); 836 837 /* perform the action */ 838 return shr_mtemplate_index_get(unit, template_type, data, template); 839 } 840 841 842 /* 843 * Function 844 * shr_template_ref_count_get 845 * Purpose 846 * Get the reference counter from a specific template id 847 * Parameters 848 * (IN) unit : unit number of the device 849 * (IN) template_type : which template type to use 850 * (IN) template : which template to get the reference count 851 * (OUT) ref_count : where to put the template's reference count 852 * Returns 853 * BCM_E_NONE if successful 854 * BCM_E_* as appropriate otherwise 855 * Notes 856 */ 857 int 858 shr_template_ref_count_get(int unit, 859 int template_type, 860 int template, 861 uint32 *ref_count) 862 { 863 /* a little parameter checking */ 864 TEMPLATE_UNIT_CHECK(unit); 865 866 /* perform the action */ 867 return shr_mtemplate_ref_count_get(unit, template_type, template, ref_count); 868 } 869 870 /* 871 * Function 872 * shr_template_dump 873 * Purpose 874 * Diagnostic dump of a unit's resource management information 875 * Parameters 876 * (IN) unit : unit number of the device 877 * Returns 878 * BCM_E_NONE if successful 879 * BCM_E_* as appropriate otherwise 880 * Notes 881 * This displays the information using bsl_printf. 882 */ 883 int 884 shr_template_dump(int unit, int template_type) 885 { 886 /* a little parameter checking */ 887 TEMPLATE_UNIT_CHECK(unit); 888 889 /* perform the action */ 890 return shr_mtemplate_dump(unit, template_type); 891 } 892 893 /* 894 * Function 895 * shr_template_clear 896 * Purpose 897 * Free all templates located in this template_type 898 * (without free memory of the template resource) 899 * Parameters 900 * (IN) unit : unit number of the device 901 * (IN) template_type : which template type to use 902 * Returns 903 * BCM_E_NONE if successful 904 * BCM_E_* as appropriate otherwise 905 * Notes 906 */ 907 int 908 shr_template_clear(int unit, 909 int template_type) 910 { 911 /* a little parameter checking */ 912 TEMPLATE_UNIT_CHECK(unit); 913 914 /* perform the action */ 915 return shr_mtemplate_clear(unit,template_type); 916 } 917 918 919 static int 920 shr_mtmemplate_type_change_count(int unit, int template_type, int count){ 921 int refCount; 922 int result = _SHR_E_NONE; 923 924 result = TEMPLATE_ACCESS.template_param.refCount.get(unit, template_type, &refCount); 925 SW_STATE_ACCESS_ERROR_CHECK(result); 926 927 refCount += count; 928 929 /* 930 * A free operation on an empty template would not return any indication, but would still try to 931 * reduce the refCount. This could go below zero, which is meaningless, so pervent it. 932 */ 933 if (refCount < 0){ 934 refCount = 0; 935 } 936 937 result = TEMPLATE_ACCESS.template_param.refCount.set(unit, template_type, refCount); 938 SW_STATE_ACCESS_ERROR_CHECK(result); 939 940 return result; 941 } 942 943 /* 944 * Allocate template of a resource type 945 */ 946 static int 947 shr_mtemplate_alloc(int unit, 948 int template_type, 949 uint32 flags, 950 const void *data, 951 int *is_allocated, 952 int *template) 953 { 954 int thisPool; 955 int result = BCM_E_NONE; 956 shr_template_manage_t mngr_type; 957 958 LOG_DEBUG(BSL_LS_SOC_COMMON, 959 (BSL_META("(%d, %d, %08X) enter\n"), 960 unit, 961 template_type, 962 flags)); 963 964 965 /* a little parameter checking */ 966 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 967 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 968 969 TEMPLATE_PARAM_NULL_CHECK(unit,data); 970 TEMPLATE_PARAM_NULL_CHECK(unit,is_allocated); 971 TEMPLATE_PARAM_NULL_CHECK(unit,template); 972 973 if (flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS)) { 974 LOG_ERROR(BSL_LS_SOC_COMMON, 975 (BSL_META("invalid flags %08X\n"), 976 flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS))); 977 return BCM_E_PARAM; 978 } 979 980 /* get the pool information */ 981 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 982 SW_STATE_ACCESS_ERROR_CHECK(result); 983 984 if (flags & SHR_TEMPLATE_MANAGE_SINGLE_FLAGS) { 985 /* verify template id from pool information */ 986 TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,*template); 987 } 988 989 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 990 SW_STATE_ACCESS_ERROR_CHECK(result); 991 992 /* make the call */ 993 result = _shr_template_managements_mgrs[mngr_type].alloc(unit, 994 thisPool, 995 flags, 996 data, 997 is_allocated, 998 template); 999 1000 if (BCM_E_NONE == result) { 1001 /* account for successful allocation */ 1002 result = shr_mtmemplate_type_change_count(unit, template_type, 1); 1003 SW_STATE_ACCESS_ERROR_CHECK(result); 1004 } 1005 1006 LOG_DEBUG(BSL_LS_SOC_COMMON, 1007 (BSL_META("(%d, %d, %08X, %p, %d, %d) return %d (%s)\n"), 1008 unit, 1009 template_type, 1010 flags, 1011 data, 1012 *is_allocated, 1013 *template, 1014 result, 1015 _SHR_ERRMSG(result))); 1016 1017 return result; 1018 } 1019 1020 /* 1021 * Allocate template of a resource type for a bunch of elements 1022 */ 1023 static int 1024 shr_mtemplate_alloc_group(int unit, 1025 int template_type, 1026 uint32 flags, 1027 const void *data, 1028 int nof_additions, 1029 int *is_allocated, 1030 int *template) 1031 { 1032 shr_template_manage_t mngr_type; 1033 int thisPool; 1034 int result = BCM_E_NONE; 1035 1036 1037 LOG_DEBUG(BSL_LS_SOC_COMMON, 1038 (BSL_META("(%d, %d, %08X) enter\n"), 1039 unit, 1040 template_type, 1041 flags)); 1042 1043 1044 /* a little parameter checking */ 1045 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 1046 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 1047 1048 TEMPLATE_PARAM_NULL_CHECK(unit,data); 1049 TEMPLATE_PARAM_NULL_CHECK(unit,is_allocated); 1050 TEMPLATE_PARAM_NULL_CHECK(unit,template); 1051 1052 if (flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS)) { 1053 LOG_ERROR(BSL_LS_SOC_COMMON, 1054 (BSL_META("invalid flags %08X\n"), 1055 flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS))); 1056 return BCM_E_PARAM; 1057 } 1058 1059 1060 if ((flags & (SHR_TEMPLATE_MANAGE_SET_WITH_ID)) == 0) { 1061 LOG_ERROR(BSL_LS_SOC_COMMON, 1062 (BSL_META("WITH_ID must be specify %08X\n"), 1063 flags)); 1064 return BCM_E_PARAM; 1065 } 1066 1067 /* get the pool information */ 1068 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 1069 SW_STATE_ACCESS_ERROR_CHECK(result); 1070 1071 if (flags & SHR_TEMPLATE_MANAGE_SINGLE_FLAGS) { 1072 /* verify template id from pool information */ 1073 TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,*template); 1074 } 1075 1076 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 1077 SW_STATE_ACCESS_ERROR_CHECK(result); 1078 /* make the call */ 1079 result = _shr_template_managements_mgrs[mngr_type].alloc_group(unit, 1080 thisPool, 1081 flags, 1082 data, 1083 nof_additions, 1084 is_allocated, 1085 template); 1086 1087 if (BCM_E_NONE == result) { 1088 /* account for successful allocation */ 1089 result = shr_mtmemplate_type_change_count(unit, template_type, nof_additions); 1090 SW_STATE_ACCESS_ERROR_CHECK(result); 1091 } 1092 1093 LOG_DEBUG(BSL_LS_SOC_COMMON, 1094 (BSL_META("(%d, %d, %08X, %p, %d, %d, %d) return %d (%s)\n"), 1095 unit, 1096 template_type, 1097 flags, 1098 data, 1099 nof_additions, 1100 *is_allocated, 1101 *template, 1102 result, 1103 _SHR_ERRMSG(result))); 1104 1105 return result; 1106 } 1107 1108 /* Free template (if needed) and decrement reference of the given resource */ 1109 static int 1110 shr_mtemplate_free(int unit, 1111 int template_type, 1112 int template, 1113 int *is_last) 1114 { 1115 shr_template_manage_t mngr_type; 1116 int thisPool; 1117 int result = BCM_E_NONE; 1118 1119 LOG_DEBUG(BSL_LS_SOC_COMMON, 1120 (BSL_META("(%d, %d, %d) enter\n"), 1121 unit, 1122 template_type, 1123 template)); 1124 1125 1126 /* a little parameter checking */ 1127 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 1128 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 1129 1130 TEMPLATE_PARAM_NULL_CHECK(unit,is_last); 1131 1132 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 1133 SW_STATE_ACCESS_ERROR_CHECK(result); 1134 1135 /* verify template id from pool information */ 1136 TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,template); 1137 1138 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 1139 SW_STATE_ACCESS_ERROR_CHECK(result); 1140 1141 /* make the call */ 1142 result = _shr_template_managements_mgrs[mngr_type].free(unit, 1143 thisPool, 1144 template, 1145 is_last); 1146 1147 if (BCM_E_NONE == result) { 1148 /* account for successful deallocation */ 1149 result = shr_mtmemplate_type_change_count(unit, template_type, -1); 1150 SW_STATE_ACCESS_ERROR_CHECK(result); 1151 } 1152 1153 LOG_DEBUG(BSL_LS_SOC_COMMON, 1154 (BSL_META("(%d, %d, %d, %d) return %d (%s)\n"), 1155 unit, 1156 template_type, 1157 template, 1158 *is_last, 1159 result, 1160 _SHR_ERRMSG(result))); 1161 return result; 1162 } 1163 1164 1165 /* Free template (if needed) and decrement reference of the given resource */ 1166 static int 1167 shr_mtemplate_free_group(int unit, 1168 int template_type, 1169 int template, 1170 int nof_deductions, 1171 int *is_last) 1172 { 1173 shr_template_manage_t mngr_type; 1174 int thisPool; 1175 int result = BCM_E_NONE; 1176 1177 LOG_DEBUG(BSL_LS_SOC_COMMON, 1178 (BSL_META("(%d, %d, %d) enter\n"), 1179 unit, 1180 template_type, 1181 template)); 1182 1183 1184 /* a little parameter checking */ 1185 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 1186 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 1187 1188 TEMPLATE_PARAM_NULL_CHECK(unit,is_last); 1189 1190 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 1191 SW_STATE_ACCESS_ERROR_CHECK(result); 1192 1193 /* verify template id from pool information */ 1194 TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,template); 1195 1196 /* make the call */ 1197 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 1198 SW_STATE_ACCESS_ERROR_CHECK(result); 1199 result = _shr_template_managements_mgrs[mngr_type].free_group(unit, 1200 thisPool, 1201 template, 1202 nof_deductions, 1203 is_last); 1204 1205 if (BCM_E_NONE == result) { 1206 /* account for successful deallocation */ 1207 result = shr_mtmemplate_type_change_count(unit, template_type, -nof_deductions); 1208 SW_STATE_ACCESS_ERROR_CHECK(result); 1209 } 1210 1211 LOG_DEBUG(BSL_LS_SOC_COMMON, 1212 (BSL_META("(%d, %d, %d, %d) return %d (%s)\n"), 1213 unit, 1214 template_type, 1215 template, 1216 *is_last, 1217 result, 1218 _SHR_ERRMSG(result))); 1219 return result; 1220 } 1221 1222 static int 1223 shr_mtemplate_exchange(int unit, 1224 int template_type, 1225 uint32 flags, 1226 const void *data, 1227 int old_template, 1228 int *is_last, 1229 int *template, 1230 int *is_allocated) 1231 { 1232 shr_template_manage_t mngr_type; 1233 int thisPool; 1234 int result = BCM_E_NONE; 1235 uint32 valid_flags = SHR_TEMPLATE_MANAGE_SINGLE_FLAGS | SHR_TEMPLATE_MANAGE_SET_WITH_ID | SHR_TEMPLATE_MANAGE_IGNORE_DATA; 1236 1237 LOG_DEBUG(BSL_LS_SOC_COMMON, 1238 (BSL_META("(%d, %d, %08X, %d) enter\n"), 1239 unit, 1240 template_type, 1241 flags, 1242 old_template)); 1243 1244 1245 /* a little parameter checking */ 1246 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 1247 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 1248 1249 TEMPLATE_PARAM_NULL_CHECK(unit,data); 1250 TEMPLATE_PARAM_NULL_CHECK(unit,is_last); 1251 TEMPLATE_PARAM_NULL_CHECK(unit,is_allocated); 1252 TEMPLATE_PARAM_NULL_CHECK(unit,template); 1253 1254 if (flags & ~valid_flags) { 1255 LOG_ERROR(BSL_LS_SOC_COMMON, 1256 (BSL_META("invalid flags %08X\n"), 1257 flags & ~valid_flags)); 1258 return BCM_E_PARAM; 1259 } 1260 1261 if ((flags & SHR_TEMPLATE_MANAGE_IGNORE_DATA) && !(flags & SHR_TEMPLATE_MANAGE_SET_WITH_ID)) { 1262 LOG_ERROR(BSL_LS_SOC_COMMON, 1263 (BSL_META("SHR_TEMPLATE_MANAGE_IGNORE_DATA is only valid in combination with SHR_TEMPLATE_MANAGE_SET_WITH_ID\n"))); 1264 return BCM_E_PARAM; 1265 } 1266 1267 /* get the pool information */ 1268 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 1269 SW_STATE_ACCESS_ERROR_CHECK(result); 1270 1271 1272 /* verify template id from pool information */ 1273 TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,old_template); 1274 /* make the call */ 1275 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 1276 SW_STATE_ACCESS_ERROR_CHECK(result); 1277 result = _shr_template_managements_mgrs[mngr_type].exchange(unit, 1278 thisPool, 1279 flags, 1280 data, 1281 old_template, 1282 is_last, 1283 template, 1284 is_allocated); 1285 1286 LOG_DEBUG(BSL_LS_SOC_COMMON, 1287 (BSL_META("(%d, %d, %08X, %d, %d) return %d (%s)\n"), 1288 unit, 1289 template_type, 1290 flags, 1291 old_template, 1292 *is_last, 1293 result, 1294 _SHR_ERRMSG(result))); 1295 1296 return result; 1297 } 1298 1299 static int 1300 shr_mtemplate_exchange_test(int unit, 1301 int template_type, 1302 uint32 flags, 1303 const void *data, 1304 int old_template, 1305 int *is_last, 1306 int *template, 1307 int *is_allocated) 1308 { 1309 shr_template_manage_t mngr_type; 1310 int thisPool; 1311 int result = BCM_E_NONE; 1312 1313 LOG_DEBUG(BSL_LS_SOC_COMMON, 1314 (BSL_META("(%d, %d, %08X, %d) enter\n"), 1315 unit, 1316 template_type, 1317 flags, 1318 old_template)); 1319 1320 1321 /* a little parameter checking */ 1322 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 1323 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 1324 1325 TEMPLATE_PARAM_NULL_CHECK(unit,data); 1326 TEMPLATE_PARAM_NULL_CHECK(unit,is_last); 1327 TEMPLATE_PARAM_NULL_CHECK(unit,is_allocated); 1328 TEMPLATE_PARAM_NULL_CHECK(unit,template); 1329 1330 if (flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS)) { 1331 LOG_ERROR(BSL_LS_SOC_COMMON, 1332 (BSL_META("invalid flags %08X\n"), 1333 flags & (~SHR_TEMPLATE_MANAGE_SINGLE_FLAGS))); 1334 return BCM_E_PARAM; 1335 } 1336 1337 /* get the pool information */ 1338 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 1339 SW_STATE_ACCESS_ERROR_CHECK(result); 1340 1341 1342 /* verify template id from pool information */ 1343 TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,old_template); 1344 /* make the call */ 1345 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 1346 SW_STATE_ACCESS_ERROR_CHECK(result); 1347 result = _shr_template_managements_mgrs[mngr_type].exchange_test(unit, 1348 thisPool, 1349 flags, 1350 data, 1351 old_template, 1352 is_last, 1353 template, 1354 is_allocated); 1355 1356 LOG_DEBUG(BSL_LS_SOC_COMMON, 1357 (BSL_META("(%d, %d, %08X, %d, %d) return %d (%s)\n"), 1358 unit, 1359 template_type, 1360 flags, 1361 old_template, 1362 *is_last, 1363 result, 1364 _SHR_ERRMSG(result))); 1365 1366 return result; 1367 } 1368 1369 static int 1370 shr_mtemplate_data_get(int unit, 1371 int template_type, 1372 int template, 1373 void *data) 1374 { 1375 shr_template_manage_t mngr_type; 1376 int thisPool; 1377 int result = BCM_E_NONE; 1378 1379 LOG_DEBUG(BSL_LS_SOC_COMMON, 1380 (BSL_META("(%d, %d, %d) enter\n"), 1381 unit, 1382 template_type, 1383 template)); 1384 1385 1386 /* a little parameter checking */ 1387 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 1388 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 1389 1390 TEMPLATE_PARAM_NULL_CHECK(unit,data); 1391 /* get the pool information */ 1392 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 1393 SW_STATE_ACCESS_ERROR_CHECK(result); 1394 1395 1396 /* verify template id from pool information */ 1397 TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,template); 1398 1399 /* make the call */ 1400 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 1401 SW_STATE_ACCESS_ERROR_CHECK(result); 1402 result = _shr_template_managements_mgrs[mngr_type].data_get(unit, 1403 thisPool, 1404 template, 1405 data); 1406 1407 LOG_DEBUG(BSL_LS_SOC_COMMON, 1408 (BSL_META("(%d, %d, %d) return %d (%s)\n"), 1409 unit, 1410 template_type, 1411 template, 1412 result, 1413 _SHR_ERRMSG(result))); 1414 1415 return result; 1416 } 1417 1418 static int 1419 shr_mtemplate_index_get(int unit, 1420 int template_type, 1421 const void *data, 1422 int *template) 1423 { 1424 shr_template_manage_t mngr_type; 1425 int thisPool; 1426 int result = BCM_E_NONE; 1427 1428 LOG_DEBUG(BSL_LS_SOC_COMMON, 1429 (BSL_META("(%d, %d) enter\n"), 1430 unit, 1431 template_type)); 1432 1433 1434 /* a little parameter checking */ 1435 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 1436 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 1437 1438 TEMPLATE_PARAM_NULL_CHECK(unit,data); 1439 /* get the pool information */ 1440 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 1441 SW_STATE_ACCESS_ERROR_CHECK(result); 1442 1443 /* make the call */ 1444 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 1445 SW_STATE_ACCESS_ERROR_CHECK(result); 1446 result = _shr_template_managements_mgrs[mngr_type].index_get(unit, 1447 thisPool, 1448 data, 1449 template); 1450 1451 LOG_DEBUG(BSL_LS_SOC_COMMON, 1452 (BSL_META("(%d, %d, %d) return %d (%s)\n"), 1453 unit, 1454 template_type, 1455 *template, 1456 result, 1457 _SHR_ERRMSG(result))); 1458 1459 return result; 1460 } 1461 1462 1463 static int 1464 shr_mtemplate_ref_count_get(int unit, 1465 int template_type, 1466 int template, 1467 uint32 *ref_count) 1468 { 1469 shr_template_manage_t mngr_type; 1470 int thisPool; 1471 int result = BCM_E_NONE; 1472 1473 LOG_DEBUG(BSL_LS_SOC_COMMON, 1474 (BSL_META("(%d, %d, %d) enter\n"), 1475 unit, 1476 template_type, 1477 template)); 1478 1479 1480 /* a little parameter checking */ 1481 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 1482 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 1483 1484 TEMPLATE_PARAM_NULL_CHECK(unit,ref_count); 1485 1486 /* get the pool information */ 1487 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 1488 SW_STATE_ACCESS_ERROR_CHECK(result); 1489 1490 /* verify template id from pool information */ 1491 TEMPLATE_POOL_PARAM_TEMPLATE_ID_CHECK(unit, thisPool,template); 1492 /* make the call */ 1493 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 1494 SW_STATE_ACCESS_ERROR_CHECK(result); 1495 result = _shr_template_managements_mgrs[mngr_type].ref_count_get(unit, 1496 thisPool, 1497 template, 1498 ref_count); 1499 1500 LOG_DEBUG(BSL_LS_SOC_COMMON, 1501 (BSL_META("(%d, %d, %d) return %d (%s)\n"), 1502 unit, 1503 template_type, 1504 template, 1505 result, 1506 _SHR_ERRMSG(result))); 1507 1508 return result; 1509 } 1510 1511 static int 1512 shr_mtemplate_create(int unit, 1513 int num_template_types, 1514 int num_template_pools, 1515 shr_template_to_stream_t *to_stream_cb_arr, 1516 shr_template_from_stream_t *from_stream_cb_arr, 1517 int cb_arr_length) 1518 { 1519 int result = BCM_E_NONE; 1520 1521 LOG_DEBUG(BSL_LS_SOC_COMMON, 1522 (BSL_META("(%d, %d, %d) enter\n"), 1523 unit, 1524 num_template_types, 1525 num_template_pools)); 1526 1527 /* a little parameter checking */ 1528 if (1 > num_template_pools) { 1529 LOG_ERROR(BSL_LS_SOC_COMMON, 1530 (BSL_META("resource pools %d; must be > 0\n"), 1531 num_template_pools)); 1532 result = BCM_E_PARAM; 1533 } 1534 if (1 > num_template_types) { 1535 LOG_ERROR(BSL_LS_SOC_COMMON, 1536 (BSL_META("resource types %d; must be > 0\n"), 1537 num_template_types)); 1538 result = BCM_E_PARAM; 1539 } 1540 if (BCM_E_NONE != result) { 1541 /* displayed diagnostics above */ 1542 return result; 1543 } 1544 /* set things up */ 1545 1546 if (cb_arr_length > 0) { 1547 /* 1548 * Allocate and copy the callback arrays. We can this on warmboot because callbacks are static and don't change between runs. 1549 */ 1550 if (!hash_compare_to_stream_cb[unit]) { 1551 hash_compare_to_stream_cb[unit] = to_stream_cb_arr; 1552 } 1553 1554 if (!hash_compare_from_stream_cb[unit]) { 1555 hash_compare_from_stream_cb[unit] = from_stream_cb_arr; 1556 } 1557 } 1558 1559 1560 if (!SOC_WARM_BOOT(unit)) { 1561 result = TEMPLATE_ACCESS.alloc(unit); 1562 SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 1563 1564 result = TEMPLATE_ACCESS.pool.ptr_alloc(unit, num_template_pools); 1565 SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 1566 1567 result = TEMPLATE_ACCESS.template_param.ptr_alloc(unit, num_template_types); 1568 SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 1569 1570 result = TEMPLATE_ACCESS.templateTypeCount.set(unit, num_template_types); 1571 SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 1572 1573 result = TEMPLATE_ACCESS.templatePoolCount.set(unit, num_template_pools); 1574 SW_STATE_ACCESS_ERROR_CHECK_NO_RET(result); 1575 } 1576 err: 1577 LOG_DEBUG(BSL_LS_SOC_COMMON, 1578 (BSL_META("(%d, %d, %d) return %d (%s)\n"), 1579 unit, 1580 num_template_types, 1581 num_template_pools, 1582 result, 1583 _SHR_ERRMSG(result))); 1584 return result; 1585 } 1586 1587 1588 static int 1589 shr_mtemplate_get(int unit, 1590 int *num_template_types, 1591 int *num_template_pools) 1592 { 1593 uint16 tmp; 1594 int result = BCM_E_NONE; 1595 1596 LOG_DEBUG(BSL_LS_SOC_COMMON, 1597 (BSL_META("(%d, %p, %p) enter\n"), 1598 unit, 1599 num_template_types, 1600 num_template_pools)); 1601 1602 /* a little parameter checking */ 1603 /* return the requested information */ 1604 if (num_template_pools) { 1605 result = TEMPLATE_ACCESS.templatePoolCount.get(unit, &tmp); 1606 SW_STATE_ACCESS_ERROR_CHECK(result); 1607 *num_template_pools = tmp; 1608 } 1609 if (num_template_types) { 1610 result = TEMPLATE_ACCESS.templateTypeCount.get(unit, &tmp); 1611 SW_STATE_ACCESS_ERROR_CHECK(result); 1612 *num_template_types = tmp; 1613 } 1614 1615 LOG_DEBUG(BSL_LS_SOC_COMMON, 1616 (BSL_META("(%d, &(%d), &(%d)) return %d (%s)\n"), 1617 unit, 1618 num_template_types?*num_template_types:-1, 1619 num_template_pools?*num_template_pools:-1, 1620 result, 1621 _SHR_ERRMSG(result))); 1622 return result; 1623 } 1624 1625 static int 1626 shr_mtemplate_pool_set(int unit, 1627 int pool_id, 1628 shr_template_manage_t manager, 1629 int template_low_id, 1630 int template_count, 1631 int max_entities, 1632 uint32 global_max, 1633 size_t data_size, 1634 const void *extras, 1635 const char *name) 1636 { 1637 int result = BCM_E_NONE; 1638 uint8 exists; 1639 const char *noname = "???"; 1640 sw_state_template_name_t name_handle; 1641 int name_len; 1642 1643 sal_memset(&name_handle, 0, sizeof(name_handle)); 1644 1645 LOG_DEBUG(BSL_LS_SOC_COMMON, 1646 (BSL_META("(%d, %d, %s, %d, %d, %d, %d, %p, \"%s\") enter\n"), 1647 unit, 1648 pool_id, 1649 ((0 <= manager) && (SHR_TEMPLATE_MANAGE_COUNT > manager))?_shr_template_managements_mgrs[manager].name:"INVALID", 1650 template_low_id, 1651 template_count, 1652 max_entities, 1653 (int)data_size, 1654 extras, 1655 name?name:noname)); 1656 1657 /* a little parameter checking */ 1658 if (SOC_WARM_BOOT(unit)) { 1659 LOG_ERROR(BSL_LS_SOC_COMMON, 1660 (BSL_META("Can't create templates during init\n"))); 1661 return _SHR_E_DISABLED; 1662 } 1663 TEMPLATE_POOL_VALID_CHECK(unit,pool_id); 1664 if ((0 > manager) || (SHR_TEMPLATE_MANAGE_COUNT <= manager)) { 1665 LOG_ERROR(BSL_LS_SOC_COMMON, 1666 (BSL_META("template manager type %d not supported\n"), 1667 manager)); 1668 return BCM_E_PARAM; 1669 } 1670 if (0 >= data_size) { 1671 LOG_ERROR(BSL_LS_SOC_COMMON, 1672 (BSL_META("data size must be positive\n"))); 1673 return BCM_E_PARAM; 1674 } 1675 if (0 >= max_entities) { 1676 LOG_ERROR(BSL_LS_SOC_COMMON, 1677 (BSL_META("maximum entities must be positive\n"))); 1678 return BCM_E_PARAM; 1679 } 1680 if (0 > template_low_id) { 1681 LOG_ERROR(BSL_LS_SOC_COMMON, 1682 (BSL_META("template low id cant be negative \n"))); 1683 return BCM_E_PARAM; 1684 } 1685 if (0 >= template_count) { 1686 LOG_ERROR(BSL_LS_SOC_COMMON, 1687 (BSL_META("template count must be positive \n"))); 1688 return BCM_E_PARAM; 1689 } 1690 name_len = name ? sal_strlen(name) : 0; 1691 if (name_len>= SW_STATE_TEMPLATE_NAME_MAX_LENGTH) { 1692 LOG_ERROR(BSL_LS_SOC_COMMON, 1693 (BSL_META("Name string \"%s\" too long. Must be shorter than %d " 1694 "(including terminal \\0)\n"), 1695 name, 1696 SW_STATE_RES_NAME_MAX_LENGTH)); 1697 return _SHR_E_PARAM; 1698 } 1699 1700 1701 TEMPLATE_PARAM_NULL_CHECK(unit,extras); 1702 1703 result = TEMPLATE_ACCESS.pool.is_allocated(unit, pool_id, &exists); 1704 SW_STATE_ACCESS_ERROR_CHECK(result); 1705 1706 if (exists) { 1707 LOG_ERROR(BSL_LS_SOC_COMMON, 1708 (BSL_META("%d pool %d already exists. " 1709 "Please free it before reallocating.\n"), 1710 unit, 1711 pool_id)); 1712 return BCM_E_CONFIG; 1713 } else { 1714 /* Allocate the pool. */ 1715 result = TEMPLATE_ACCESS.pool.alloc(unit, pool_id); 1716 SW_STATE_ACCESS_ERROR_CHECK(result); 1717 } 1718 1719 /* create the new pool */ 1720 result = _shr_template_managements_mgrs[manager].create(unit, 1721 pool_id, 1722 template_low_id, 1723 template_count, 1724 max_entities, 1725 global_max, 1726 data_size, 1727 extras, 1728 name?name:noname); 1729 if (BCM_E_NONE == result) { 1730 /* New one created successfully. Fill the information. */ 1731 result = TEMPLATE_ACCESS.pool.templateManagerType.set(unit, pool_id, manager); 1732 SW_STATE_ACCESS_ERROR_CHECK(result); 1733 1734 result = TEMPLATE_ACCESS.pool.template_low_id.set(unit, pool_id, template_low_id); 1735 SW_STATE_ACCESS_ERROR_CHECK(result); 1736 1737 result = TEMPLATE_ACCESS.pool.template_count.set(unit, pool_id, template_count); 1738 SW_STATE_ACCESS_ERROR_CHECK(result); 1739 1740 result = TEMPLATE_ACCESS.pool.max_entities.set(unit, pool_id, max_entities); 1741 SW_STATE_ACCESS_ERROR_CHECK(result); 1742 1743 result = TEMPLATE_ACCESS.pool.data_size.set(unit, pool_id, data_size); 1744 SW_STATE_ACCESS_ERROR_CHECK(result); 1745 1746 sal_memcpy(name_handle.name, name?name:noname, sal_strlen(name?name:noname) + 1); 1747 1748 result = TEMPLATE_ACCESS.pool.name.set(unit, pool_id, &name_handle); 1749 SW_STATE_ACCESS_ERROR_CHECK(result); 1750 1751 } /* if (BCM_E_NONE == result) */ 1752 1753 LOG_DEBUG(BSL_LS_SOC_COMMON, 1754 (BSL_META("(%d, %d, %s, %d, %d, %d, %d, %p, \"%s\") return %d (%s)\n"), 1755 unit, 1756 pool_id, 1757 _shr_template_managements_mgrs[manager].name, 1758 template_low_id, 1759 template_count, 1760 max_entities, 1761 (int)data_size, 1762 extras, 1763 name?name:noname, 1764 result, 1765 _SHR_ERRMSG(result))); 1766 1767 return result; 1768 } 1769 1770 static int 1771 shr_mtemplate_pool_get(int unit, 1772 int pool_id, 1773 shr_template_manage_t *manager, 1774 int *template_low_id, 1775 int *template_count, 1776 int *max_entities, 1777 size_t *data_size, 1778 shr_template_manage_hash_compare_extras_t *extras, 1779 sw_state_template_name_t *name) 1780 { 1781 int result; 1782 1783 LOG_DEBUG(BSL_LS_SOC_COMMON, 1784 (BSL_META("(%d, %d, %p, %p, %p, %p, %p, %p, %p) enter\n"), 1785 unit, 1786 pool_id, 1787 manager, 1788 template_low_id, 1789 template_count, 1790 max_entities, 1791 data_size, 1792 extras, 1793 name)); 1794 1795 /* a little parameter checking */ 1796 TEMPLATE_POOL_VALID_CHECK(unit, pool_id); 1797 TEMPLATE_POOL_EXIST_CHECK(unit, pool_id); 1798 /* fill in the caller's request */ 1799 if (manager) { 1800 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, pool_id, manager); 1801 SW_STATE_ACCESS_ERROR_CHECK(result); 1802 } 1803 if (template_low_id) { 1804 result = TEMPLATE_ACCESS.pool.template_low_id.get(unit, pool_id, template_low_id); 1805 SW_STATE_ACCESS_ERROR_CHECK(result); 1806 } 1807 if (template_count) { 1808 result = TEMPLATE_ACCESS.pool.template_count.get(unit, pool_id, template_count); 1809 SW_STATE_ACCESS_ERROR_CHECK(result); 1810 } 1811 if (max_entities) { 1812 result = TEMPLATE_ACCESS.pool.max_entities.get(unit, pool_id, max_entities); 1813 SW_STATE_ACCESS_ERROR_CHECK(result); 1814 } 1815 if (data_size) { 1816 result = TEMPLATE_ACCESS.pool.data_size.get(unit, pool_id, data_size); 1817 SW_STATE_ACCESS_ERROR_CHECK(result); 1818 } 1819 if (extras) { 1820 result = TEMPLATE_ACCESS.pool.extras.get(unit, pool_id, extras); 1821 SW_STATE_ACCESS_ERROR_CHECK(result); 1822 } 1823 if (name) { 1824 result = TEMPLATE_ACCESS.pool.name.get(unit, pool_id, name); 1825 SW_STATE_ACCESS_ERROR_CHECK(result); 1826 } 1827 1828 LOG_DEBUG(BSL_LS_SOC_COMMON, 1829 (BSL_META("(%d, %d, &(%s), &(%d), &(%d), &(%d), &(%d), &(%p), &(\"%s\")) return %d (%s)\n"), 1830 unit, 1831 pool_id, 1832 manager?_shr_template_managements_mgrs[*manager].name:"NULL", 1833 template_low_id?*template_low_id:0, 1834 template_count?*template_count:0, 1835 max_entities?*max_entities:0, 1836 data_size?(int)*data_size:0, 1837 extras?extras:NULL, 1838 name?name->name:"NULL", 1839 BCM_E_NONE, 1840 _SHR_ERRMSG(BCM_E_NONE))); 1841 return BCM_E_NONE; 1842 } 1843 1844 /* 1845 * Destroy a resource pool on a unit 1846 */ 1847 static int 1848 shr_mtemplate_pool_unset(int unit, 1849 int pool_id) 1850 { 1851 _shr_template_pool_desc_t oldPool; 1852 int result = _SHR_E_NONE; 1853 uint8 exists; 1854 1855 LOG_DEBUG(BSL_LS_SOC_COMMON, 1856 (BSL_META("(%d, %d) enter\n"), 1857 unit, pool_id)); 1858 1859 /* a little parameter checking */ 1860 TEMPLATE_POOL_VALID_CHECK(unit, pool_id); 1861 1862 result = TEMPLATE_ACCESS.pool.is_allocated(unit, pool_id, &exists); 1863 SW_STATE_ACCESS_ERROR_CHECK(result); 1864 1865 if (exists) { 1866 1867 result = TEMPLATE_ACCESS.pool.get(unit, pool_id, &oldPool); 1868 SW_STATE_ACCESS_ERROR_CHECK(result); 1869 1870 if (oldPool.refCount) { 1871 LOG_ERROR(BSL_LS_SOC_COMMON, 1872 (BSL_META("unit %d: pool %d (%s) can not be destroyed because" 1873 " it has %d types that use it\n"), 1874 unit, 1875 pool_id, 1876 oldPool.name.name, 1877 oldPool.refCount)); 1878 result = _SHR_E_CONFIG; 1879 } else { /* if (oldPool->refCount) */ 1880 result = _shr_template_managements_mgrs[oldPool.templateManagerType].destroy(unit, pool_id); 1881 if (_SHR_E_NONE != result) { 1882 LOG_ERROR(BSL_LS_SOC_COMMON, 1883 (BSL_META("unit %d: unable to destroy old pool %d (%s):" 1884 " %d (%s)\n"), 1885 unit, 1886 pool_id, 1887 oldPool.name.name, 1888 result, 1889 _SHR_ERRMSG(result))); 1890 } else { 1891 result = TEMPLATE_ACCESS.pool.free(unit, pool_id); 1892 SW_STATE_ACCESS_ERROR_CHECK(result); 1893 }/* if (_SHR_E_NONE != result) */ 1894 } /* if (oldPool.refCount) */ 1895 } /* if (exists) */ 1896 1897 LOG_DEBUG(BSL_LS_SOC_COMMON, 1898 (BSL_META("(%d, %d) return %d (%s)\n"), 1899 unit, 1900 pool_id, 1901 result, 1902 _SHR_ERRMSG(result))); 1903 return result; 1904 } 1905 1906 1907 static int 1908 shr_mtemplate_type_set(int unit, 1909 int template_type, 1910 int pool_id, 1911 const char *name) 1912 { 1913 int result = BCM_E_NONE; 1914 const char *noname = "???"; 1915 int len_name = 0; 1916 uint8 exists; 1917 sw_state_template_name_t name_handle; 1918 1919 sal_memset(&name_handle, 0, sizeof(name_handle)); 1920 1921 LOG_DEBUG(BSL_LS_SOC_COMMON, 1922 (BSL_META("(%d, %d, %d, \"%s\") enter\n"), 1923 unit, 1924 template_type, 1925 pool_id, 1926 name?name:noname)); 1927 if (SOC_WARM_BOOT(unit)) { 1928 LOG_ERROR(BSL_LS_SOC_COMMON, 1929 (BSL_META("Can't create templates during init\n"))); 1930 return _SHR_E_DISABLED; 1931 } 1932 1933 /* a little parameter checking */ 1934 TEMPLATE_POOL_VALID_CHECK(unit, pool_id); 1935 TEMPLATE_POOL_EXIST_CHECK(unit, pool_id); 1936 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 1937 1938 1939 result = TEMPLATE_ACCESS.template_param.is_allocated(unit, template_type, &exists); 1940 SW_STATE_ACCESS_ERROR_CHECK(result); 1941 if (exists) { 1942 LOG_ERROR(BSL_LS_SOC_COMMON, 1943 (BSL_META("%d template type %d already exists." 1944 "Unset it before setting again.\n"), 1945 unit, 1946 template_type)); 1947 return BCM_E_CONFIG; 1948 } 1949 if (!name) { 1950 /* force a non-NULL name pointer */ 1951 name = noname; 1952 } 1953 1954 len_name = sal_strlen(name); 1955 if (len_name>= SW_STATE_TEMPLATE_NAME_MAX_LENGTH) { 1956 LOG_ERROR(BSL_LS_SOC_COMMON, 1957 (BSL_META("Name string \"%s\" too long. Must be shorter than %d " 1958 "(including terminal \\0)\n"), 1959 name, 1960 SW_STATE_RES_NAME_MAX_LENGTH)); 1961 return _SHR_E_PARAM; 1962 } 1963 1964 1965 /* note base type includes one character, so don't need to add NUL here */ 1966 result = TEMPLATE_ACCESS.template_param.alloc(unit, template_type); 1967 SW_STATE_ACCESS_ERROR_CHECK(result); 1968 1969 result = TEMPLATE_ACCESS.template_param.templatePoolId.set(unit, template_type, pool_id); 1970 SW_STATE_ACCESS_ERROR_CHECK(result); 1971 1972 sal_strncpy(name_handle.name, name, len_name + 1); 1973 1974 result = TEMPLATE_ACCESS.template_param.name.set(unit, template_type, &name_handle); 1975 SW_STATE_ACCESS_ERROR_CHECK(result); 1976 1977 1978 LOG_DEBUG(BSL_LS_SOC_COMMON, 1979 (BSL_META("(%d, %d, %d, \"%s\") return %d (%s)\n"), 1980 unit, 1981 template_type, 1982 pool_id, 1983 name?name:noname, 1984 result, 1985 _SHR_ERRMSG(result))); 1986 return result; 1987 } 1988 1989 static int 1990 shr_mtemplate_type_get(int unit, 1991 int template_type, 1992 int *pool_id, 1993 sw_state_template_name_t *name) 1994 { 1995 int result; 1996 1997 LOG_DEBUG(BSL_LS_SOC_COMMON, 1998 (BSL_META("(%d, %d, %p, %p) enter\n"), 1999 unit, 2000 template_type, 2001 pool_id, 2002 name)); 2003 2004 /* a little parameter checking */ 2005 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 2006 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 2007 /* fill in the caller's request */ 2008 if (pool_id) { 2009 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, pool_id); 2010 SW_STATE_ACCESS_ERROR_CHECK(result); 2011 } 2012 if (name) { 2013 result = TEMPLATE_ACCESS.template_param.name.get(unit, template_type, name); 2014 SW_STATE_ACCESS_ERROR_CHECK(result); 2015 } 2016 2017 LOG_DEBUG(BSL_LS_SOC_COMMON, 2018 (BSL_META("(%d, %d, &(%d), &(\"%s\")) return %d (%s)\n"), 2019 unit, 2020 template_type, 2021 pool_id ? *pool_id : 0, 2022 name ? name->name : "NULL", 2023 BCM_E_NONE, 2024 _SHR_ERRMSG(BCM_E_NONE))); 2025 return BCM_E_NONE; 2026 } 2027 2028 2029 /* 2030 * Destroy a resource type on a unit 2031 */ 2032 static int 2033 shr_mtemplate_type_unset(int unit, 2034 int template_id) 2035 { 2036 _shr_template_type_desc_t oldType; 2037 int result = _SHR_E_NONE; 2038 uint8 exists; 2039 int refCount; 2040 2041 LOG_DEBUG(BSL_LS_SOC_COMMON, 2042 (BSL_META("(%d, %d) enter\n"), 2043 unit, template_id)); 2044 2045 /* a little parameter checking */ 2046 TEMPLATE_TYPE_VALID_CHECK(unit, template_id); 2047 2048 result = TEMPLATE_ACCESS.template_param.is_allocated(unit, template_id, &exists); 2049 SW_STATE_ACCESS_ERROR_CHECK(result); 2050 if (exists) { 2051 result = TEMPLATE_ACCESS.template_param.get(unit, template_id, &oldType); 2052 SW_STATE_ACCESS_ERROR_CHECK(result); 2053 2054 if (oldType.refCount) { 2055 LOG_ERROR(BSL_LS_SOC_COMMON, 2056 (BSL_META("%d resource %d (%s) can not be destroyed" 2057 " because it has %d elements in use\n"), 2058 unit, 2059 template_id, 2060 oldType.name.name, 2061 oldType.refCount)); 2062 result = _SHR_E_CONFIG; 2063 } else { 2064 result = TEMPLATE_ACCESS.pool.refCount.get(unit, oldType.templatePoolId, &refCount); 2065 SW_STATE_ACCESS_ERROR_CHECK(result); 2066 2067 refCount--; 2068 2069 result = TEMPLATE_ACCESS.pool.refCount.set(unit, oldType.templatePoolId, refCount); 2070 SW_STATE_ACCESS_ERROR_CHECK(result); 2071 2072 result = TEMPLATE_ACCESS.template_param.free(unit, template_id); 2073 SW_STATE_ACCESS_ERROR_CHECK(result); 2074 } 2075 } /* if (oldType) */ 2076 2077 LOG_DEBUG(BSL_LS_SOC_COMMON, 2078 (BSL_META("(%d, %d) return %d (%s)\n"), 2079 unit, 2080 template_id, 2081 result, 2082 _SHR_ERRMSG(result))); 2083 return result; 2084 } 2085 2086 2087 /* 2088 * Destroys all of the resources and then pools for a unit. 2089 */ 2090 static int 2091 _shr_mtemplate_destroy_data(int unit) 2092 { 2093 int i; 2094 int result = BCM_E_NONE; 2095 uint16 templateTypeCount, templatePoolCount; 2096 uint8 exists; 2097 _shr_template_type_desc_t type; 2098 _shr_template_pool_desc_t pool; 2099 int refCount; 2100 2101 if (!SOC_IS_DETACHING(unit) && !SOC_WARM_BOOT(unit)) { 2102 result = TEMPLATE_ACCESS.templateTypeCount.get(unit, &templateTypeCount); 2103 SW_STATE_ACCESS_ERROR_CHECK(result); 2104 2105 result = TEMPLATE_ACCESS.templatePoolCount.get(unit, &templatePoolCount); 2106 SW_STATE_ACCESS_ERROR_CHECK(result); 2107 2108 2109 /* destroy resources */ 2110 for (i = 0; i < templateTypeCount; i++) { 2111 result = TEMPLATE_ACCESS.template_param.is_allocated(unit, i, &exists); 2112 SW_STATE_ACCESS_ERROR_CHECK(result); 2113 2114 if (exists) { 2115 result = TEMPLATE_ACCESS.template_param.get(unit, i, &type); 2116 SW_STATE_ACCESS_ERROR_CHECK(result); 2117 if (type.refCount) { 2118 LOG_WARN(BSL_LS_SOC_COMMON, 2119 (BSL_META("unit %d: type %d (%s): still in use (%d)\n"), 2120 unit, 2121 i, 2122 (type.name.name), 2123 type.refCount)); 2124 } 2125 2126 result = TEMPLATE_ACCESS.pool.refCount.get(unit, type.templatePoolId, &refCount); 2127 SW_STATE_ACCESS_ERROR_CHECK(result); 2128 2129 refCount--; 2130 2131 result = TEMPLATE_ACCESS.pool.refCount.set(unit, type.templatePoolId, refCount); 2132 SW_STATE_ACCESS_ERROR_CHECK(result); 2133 2134 result = TEMPLATE_ACCESS.template_param.free(unit, i); 2135 SW_STATE_ACCESS_ERROR_CHECK(result); 2136 } 2137 } /* for (all resources this unit) */ 2138 2139 /* Fress the resources pointer array. */ 2140 result = TEMPLATE_ACCESS.template_param.ptr_free(unit); 2141 SW_STATE_ACCESS_ERROR_CHECK(result); 2142 2143 2144 /* destroy pools */ 2145 for (i = 0; 2146 (i < templatePoolCount) && (BCM_E_NONE == result); 2147 i++) { 2148 2149 result = TEMPLATE_ACCESS.pool.is_allocated(unit, i, &exists); 2150 SW_STATE_ACCESS_ERROR_CHECK(result); 2151 2152 if (exists) { 2153 result = TEMPLATE_ACCESS.pool.get(unit, i, &pool); 2154 SW_STATE_ACCESS_ERROR_CHECK(result); 2155 2156 if (pool.refCount) { 2157 LOG_WARN(BSL_LS_SOC_COMMON, 2158 (BSL_META("unit %d: %d (%s): unexpectedly still" 2159 " in use (%d) - invalid condition???\n"), 2160 unit, 2161 i, 2162 (pool.name.name), 2163 pool.refCount)); 2164 } 2165 result = _shr_template_managements_mgrs[pool.templateManagerType].destroy(unit, i); 2166 if (_SHR_E_NONE != result) { 2167 LOG_ERROR(BSL_LS_SOC_COMMON, 2168 (BSL_META("unit %d: pool %d (%s): unable to destroy:" 2169 " %d (%s)\n"), 2170 unit, 2171 i, 2172 (pool.name.name), 2173 result, 2174 _SHR_ERRMSG(result))); 2175 } /* if (_SHR_E_NONE != result) */ 2176 2177 result = TEMPLATE_ACCESS.pool.free(unit, i); 2178 SW_STATE_ACCESS_ERROR_CHECK(result); 2179 2180 } /* if (unitData->pool[i]) */ 2181 } /* for (all pools as long as no errors) */ 2182 2183 /* Free the pool resources array. */ 2184 result = TEMPLATE_ACCESS.pool.ptr_free(unit); 2185 SW_STATE_ACCESS_ERROR_CHECK(result); 2186 } 2187 return result; 2188 } 2189 2190 static int 2191 shr_mtemplate_dump(int unit, int template_type) 2192 { 2193 _shr_template_pool_desc_t thisPool; 2194 _shr_template_type_desc_t thisTemplate; 2195 int index, template, start_index, last_index, buff_counter; 2196 int result = BCM_E_NONE; 2197 char buff[SHR_TEMPLATE_MAX_BUFFER_SIZE_FOR_PRINT]; 2198 uint32 ref_count; 2199 uint16 templateTypeCount, templatePoolCount; 2200 uint8 exists; 2201 int template_id, pool_idx; 2202 2203 /* a little parameter checking */ 2204 2205 result = TEMPLATE_ACCESS.templateTypeCount.get(unit, &templateTypeCount); 2206 SW_STATE_ACCESS_ERROR_CHECK(result); 2207 2208 result = TEMPLATE_ACCESS.templatePoolCount.get(unit, &templatePoolCount); 2209 SW_STATE_ACCESS_ERROR_CHECK(result); 2210 2211 if( template_type != -1) 2212 { 2213 if (template_type < 0 || template_type > templateTypeCount) 2214 { 2215 LOG_CLI((BSL_META(" templateType not exist (%d..%d)\n"), 0, templateTypeCount)); 2216 return BCM_E_PARAM; 2217 } 2218 start_index = template_type; 2219 last_index = template_type + 1; 2220 } 2221 else 2222 { 2223 /* dump information about the handle */ 2224 LOG_CLI((BSL_META(" template manager (%d)\n"), unit)); 2225 LOG_CLI((BSL_META(" template type count = %d\n"), templateTypeCount)); 2226 LOG_CLI((BSL_META(" template pool count = %d\n"), templatePoolCount)); 2227 start_index = 0; 2228 last_index = templateTypeCount; 2229 } 2230 2231 for (index = start_index; index < last_index; index++) { 2232 result = TEMPLATE_ACCESS.template_param.is_allocated(unit, index, &exists); 2233 SW_STATE_ACCESS_ERROR_CHECK(result); 2234 2235 if (exists) { 2236 result = TEMPLATE_ACCESS.template_param.get(unit, index, &thisTemplate); 2237 SW_STATE_ACCESS_ERROR_CHECK(result); 2238 2239 result = TEMPLATE_ACCESS.pool.get(unit, thisTemplate.templatePoolId, &thisPool); 2240 SW_STATE_ACCESS_ERROR_CHECK(result); 2241 2242 bcm_dpp_am_pool_id_to_template_id_get(unit, index, &template_id, &pool_idx); 2243 2244 LOG_CLI((BSL_META(" template type %d (%s) in core #%d\n"), index, thisTemplate.name.name, pool_idx)); 2245 LOG_CLI((BSL_META(" first template index = %d nof templates = %d\n"), thisPool.template_low_id, thisPool.template_count)); 2246 LOG_CLI((BSL_META(" number of elements using this template type = %d\n"), thisTemplate.refCount)); 2247 LOG_CLI((BSL_META(" template data size %d \n"), (int)(thisPool.data_size))); 2248 2249 if(template_type != -1) { 2250 for (template = thisPool.template_low_id; template < thisPool.template_low_id + thisPool.template_count; template++) { 2251 result = _shr_template_managements_mgrs[thisPool.templateManagerType].ref_count_get(unit, thisTemplate.templatePoolId, template, &ref_count); 2252 if (BCM_E_NONE != result) { 2253 LOG_CLI((BSL_META(" error retriving ref counter \n"))); 2254 return BCM_E_FAIL; 2255 } 2256 2257 if (ref_count > 0 && SHR_TEMPLATE_MAX_BUFFER_SIZE_FOR_PRINT >= thisPool.data_size) { 2258 result = _shr_template_managements_mgrs[thisPool.templateManagerType].data_get(unit, thisTemplate.templatePoolId, template, buff); 2259 if (BCM_E_NONE != result) { 2260 LOG_CLI((BSL_META(" error geting data for template ID %d\n"), template)); 2261 } else{ 2262 LOG_CLI((BSL_META(" template id = %d ref counter = %d \n"), template, ref_count)); 2263 if (_bcm_dpp_am_template_print_func[template_id] == NULL ) { 2264 LOG_CLI((BSL_META(" template data (hex): "))); 2265 for (buff_counter = 0; buff_counter < thisPool.data_size; buff_counter++) { 2266 /* %02hhx means print an unsigned char with at least two numbers in hexa. */ 2267 LOG_CLI((BSL_META("%02hhx"), buff[buff_counter])); 2268 } 2269 LOG_CLI((BSL_META("\n\n"))); 2270 } else { 2271 (_bcm_dpp_am_template_print_func[template_id]) (unit, buff); 2272 } 2273 } 2274 } 2275 } 2276 } 2277 } else { 2278 LOG_CLI((BSL_META(" template type %d is not in use\n"), index)); 2279 } 2280 LOG_CLI((BSL_META("\n"))); 2281 } 2282 return result; 2283 } 2284 2285 static int 2286 shr_mtemplate_clear(int unit, 2287 int template_type) 2288 { 2289 shr_template_manage_t mngr_type; 2290 int thisPool; 2291 int result = BCM_E_NONE; 2292 2293 LOG_DEBUG(BSL_LS_SOC_COMMON, 2294 (BSL_META("(%d, %d) enter\n"), 2295 unit, 2296 template_type)); 2297 2298 /* a little parameter checking */ 2299 TEMPLATE_TYPE_VALID_CHECK(unit, template_type); 2300 TEMPLATE_TYPE_EXIST_CHECK(unit, template_type); 2301 2302 /* get the pool information */ 2303 result = TEMPLATE_ACCESS.template_param.templatePoolId.get(unit, template_type, &thisPool); 2304 SW_STATE_ACCESS_ERROR_CHECK(result); 2305 2306 result = TEMPLATE_ACCESS.pool.templateManagerType.get(unit, thisPool, &mngr_type); 2307 SW_STATE_ACCESS_ERROR_CHECK(result); 2308 2309 /* make the call */ 2310 result = _shr_template_managements_mgrs[mngr_type].clear(unit, thisPool); 2311 2312 LOG_DEBUG(BSL_LS_SOC_COMMON, 2313 (BSL_META("(%d, %d) return %d (%s)\n"), 2314 unit, 2315 template_type, 2316 result, 2317 _SHR_ERRMSG(result))); 2318 2319 return result; 2320 } 2321 /* ******************************************************************/ 2322 2323 /* Hash Utils functions } */ 2324 2325 static int _shr_template_hash_create(int unit, 2326 int pool_id, 2327 int template_low_id, 2328 int template_count, 2329 int max_entities, 2330 uint32 global_max, 2331 size_t data_size, 2332 const void *extras, 2333 const char *name) 2334 { 2335 /* need the base descriptor */ 2336 int result = BCM_E_NONE; 2337 const shr_template_manage_hash_compare_extras_t *info = extras; 2338 uint32 soc_sand_rv = 0; 2339 SOC_SAND_MULTI_SET_PTR multi_set_info; 2340 SOC_SAND_MULTI_SET_INIT_INFO multi_set_init_info; 2341 2342 /* Set the pool's extras. */ 2343 result = TEMPLATE_ACCESS.pool.extras.set(unit, pool_id, *info); 2344 SW_STATE_ACCESS_ERROR_CHECK(result); 2345 2346 /* Clear structures */ 2347 2348 /* Init hash template */ 2349 soc_sand_os_memset(&multi_set_init_info, 0x0, sizeof(SOC_SAND_MULTI_SET_INIT_INFO)); 2350 multi_set_init_info.get_entry_fun = NULL; 2351 multi_set_init_info.set_entry_fun = NULL; 2352 multi_set_init_info.max_duplications = max_entities; 2353 multi_set_init_info.member_size = data_size; 2354 multi_set_init_info.nof_members = template_count; 2355 multi_set_init_info.sec_handle = 0; 2356 multi_set_init_info.prime_handle = 0; 2357 2358 soc_sand_rv = soc_sand_multi_set_create( 2359 unit, 2360 &multi_set_info, 2361 multi_set_init_info 2362 ); 2363 2364 result = TEMPLATE_ACCESS.pool.templateHandle.set(unit, pool_id, multi_set_info); 2365 SW_STATE_ACCESS_ERROR_CHECK(result); 2366 2367 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2368 /* Init failed */ 2369 return BCM_E_MEMORY; 2370 } 2371 2372 /* all's well if we got here */ 2373 return result; 2374 } 2375 2376 static int _shr_template_hash_destroy(int unit, int pool_id) 2377 { 2378 int res = BCM_E_NONE; 2379 uint32 soc_sand_rv; 2380 SOC_SAND_MULTI_SET_PTR hash_handle; 2381 2382 res = TEMPLATE_ACCESS.pool.templateHandle.get(unit, pool_id, &hash_handle); 2383 SW_STATE_ACCESS_ERROR_CHECK(res); 2384 2385 soc_sand_rv = soc_sand_multi_set_destroy(unit, hash_handle); 2386 SOC_SAND_IF_ERR_RETURN(soc_sand_rv); 2387 2388 return res; 2389 } 2390 2391 static int _shr_template_hash_alloc(int unit, 2392 int pool_id, 2393 uint32 flags, 2394 const void* data, 2395 int *is_allocated, 2396 int *template) 2397 { 2398 _shr_template_pool_desc_t desc; 2399 int res = BCM_E_NONE; 2400 SOC_SAND_MULTI_SET_KEY * val; 2401 SOC_SAND_MULTI_SET_PTR hash_handle; 2402 uint8 add_success; 2403 shr_template_manage_hash_compare_extras_t extra; 2404 uint32 soc_sand_rv = SOC_SAND_OK; 2405 uint8 first_appear; 2406 int template_alloc = 0; 2407 shr_template_to_stream_t *hcts_cb = NULL; 2408 2409 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 2410 SW_STATE_ACCESS_ERROR_CHECK(res); 2411 2412 hash_handle = desc.templateHandle; 2413 extra = desc.extras; 2414 2415 val = sal_alloc((desc.data_size),"Data buffer"); 2416 2417 if (!val) { 2418 /* alloc failed */ 2419 LOG_ERROR(BSL_LS_SOC_COMMON, 2420 (BSL_META("unable to allocate %u bytes for info\n"), 2421 (unsigned int) 2422 ((desc.data_size)))); 2423 res = BCM_E_MEMORY; 2424 } else { 2425 sal_memset(val,0x0,(desc.data_size)); 2426 2427 /* move to buffer */ 2428 hcts_cb = hash_compare_to_stream_cb[unit]; 2429 res = hcts_cb[extra](data,val,desc.data_size); 2430 if (res != BCM_E_NONE) { 2431 goto exit; 2432 } 2433 2434 if (flags & SHR_TEMPLATE_MANAGE_SET_WITH_ID) { 2435 template_alloc = *template - desc.template_low_id; 2436 soc_sand_rv = soc_sand_multi_set_member_add_at_index( 2437 unit, 2438 hash_handle, 2439 val, 2440 template_alloc, 2441 &first_appear, 2442 &add_success); 2443 } else { 2444 /* Add new data */ 2445 soc_sand_rv = soc_sand_multi_set_member_add( 2446 unit, 2447 hash_handle, 2448 val, 2449 (uint32 *)&template_alloc, 2450 &first_appear, 2451 &add_success); 2452 *template = template_alloc + desc.template_low_id; 2453 } 2454 2455 *is_allocated = first_appear; 2456 2457 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2458 res = BCM_E_INTERNAL; 2459 goto exit; 2460 } 2461 2462 if (!add_success) { 2463 res = BCM_E_MEMORY; 2464 goto exit; 2465 } 2466 2467 } 2468 2469 exit: 2470 if (val) { 2471 sal_free(val); 2472 } 2473 2474 return res; 2475 } 2476 2477 static int _shr_template_hash_alloc_group(int unit, 2478 int pool_id, 2479 uint32 flags, 2480 const void* data, 2481 int nof_additions, 2482 int *is_allocated, 2483 int *template) 2484 { 2485 _shr_template_pool_desc_t desc; 2486 int res = BCM_E_NONE; 2487 SOC_SAND_MULTI_SET_KEY * val; 2488 SOC_SAND_MULTI_SET_PTR hash_handle; 2489 uint8 add_success; 2490 shr_template_manage_hash_compare_extras_t extra; 2491 uint32 soc_sand_rv = SOC_SAND_OK; 2492 uint8 first_appear; 2493 int template_alloc = 0; 2494 shr_template_to_stream_t *hcts_cb = NULL; 2495 2496 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 2497 SW_STATE_ACCESS_ERROR_CHECK(res); 2498 2499 hash_handle = desc.templateHandle; 2500 extra = desc.extras; 2501 2502 val = sal_alloc((desc.data_size),"Data buffer"); 2503 2504 if (!val) { 2505 /* alloc failed */ 2506 LOG_ERROR(BSL_LS_SOC_COMMON, 2507 (BSL_META("unable to allocate %u bytes for info\n"), 2508 (unsigned int) 2509 ((desc.data_size)))); 2510 res = BCM_E_MEMORY; 2511 } else { 2512 sal_memset(val,0x0,(desc.data_size)); 2513 2514 /* move to buffer */ 2515 hcts_cb = hash_compare_to_stream_cb[unit]; 2516 res = hcts_cb[extra](data,val,desc.data_size); 2517 if (res != BCM_E_NONE) { 2518 goto exit; 2519 } 2520 2521 if (flags & SHR_TEMPLATE_MANAGE_SET_WITH_ID) { 2522 template_alloc = *template - desc.template_low_id; 2523 soc_sand_rv = soc_sand_multi_set_member_add_at_index_nof_additions( 2524 unit, 2525 hash_handle, 2526 val, 2527 template_alloc, 2528 nof_additions, 2529 &first_appear, 2530 &add_success); 2531 } else { 2532 2533 res = BCM_E_INTERNAL; 2534 goto exit; 2535 } 2536 2537 *is_allocated = first_appear; 2538 2539 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2540 res = BCM_E_INTERNAL; 2541 goto exit; 2542 } 2543 2544 if (!add_success) { 2545 res = BCM_E_MEMORY; 2546 goto exit; 2547 } 2548 2549 } 2550 2551 exit: 2552 if (val) { 2553 sal_free(val); 2554 } 2555 2556 return res; 2557 } 2558 2559 static int _shr_template_hash_free(int unit, 2560 int pool_id, 2561 int template, 2562 int *is_last) 2563 { 2564 _shr_template_pool_desc_t desc; 2565 int res = BCM_E_NONE; 2566 SOC_SAND_MULTI_SET_PTR hash_handle; 2567 uint8 last_appear = 0; 2568 uint32 soc_sand_rv; 2569 int template_alloc; 2570 2571 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 2572 SW_STATE_ACCESS_ERROR_CHECK(res); 2573 2574 hash_handle = desc.templateHandle; 2575 2576 /* Remove old template */ 2577 template_alloc = template - desc.template_low_id; 2578 soc_sand_rv = soc_sand_multi_set_member_remove_by_index( 2579 unit, 2580 hash_handle, 2581 template_alloc, 2582 &last_appear); 2583 2584 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2585 res = BCM_E_INTERNAL; 2586 } else { 2587 if (last_appear) { 2588 *is_last = 1; 2589 } else { 2590 *is_last = 0; 2591 } 2592 } 2593 2594 return res; 2595 } 2596 2597 static int _shr_template_hash_free_group(int unit, 2598 int pool_id, 2599 int template, 2600 int nof_deductions, 2601 int *is_last) 2602 { 2603 _shr_template_pool_desc_t desc; 2604 int res = BCM_E_NONE; 2605 SOC_SAND_MULTI_SET_PTR hash_handle; 2606 uint8 last_appear = 0; 2607 uint32 soc_sand_rv; 2608 int template_alloc; 2609 2610 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 2611 SW_STATE_ACCESS_ERROR_CHECK(res); 2612 2613 hash_handle = desc.templateHandle; 2614 2615 /* Remove old template */ 2616 template_alloc = template - desc.template_low_id; 2617 soc_sand_rv = soc_sand_multi_set_member_remove_by_index_multiple( 2618 unit, 2619 hash_handle, 2620 template_alloc, 2621 nof_deductions, 2622 &last_appear); 2623 2624 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2625 res = BCM_E_INTERNAL; 2626 } else { 2627 if (last_appear) { 2628 *is_last = 1; 2629 } else { 2630 *is_last = 0; 2631 } 2632 } 2633 2634 return res; 2635 } 2636 2637 static int _shr_template_hash_exchange(int unit, 2638 int pool_id, 2639 uint32 flags, 2640 const void *data, 2641 int old_template, 2642 int *is_last, 2643 int *template, 2644 int *is_allocated) 2645 { 2646 _shr_template_pool_desc_t desc; 2647 int res = BCM_E_NONE; 2648 SOC_SAND_MULTI_SET_KEY * val; 2649 SOC_SAND_MULTI_SET_KEY * old_val; 2650 SOC_SAND_MULTI_SET_PTR hash_handle; 2651 uint8 add_success; 2652 uint8 first_appear = 0; 2653 uint8 last_appear = 0; 2654 int template_alloc = 0; 2655 int old_template_alloc; 2656 2657 shr_template_manage_hash_compare_extras_t extra; 2658 uint32 soc_sand_rv; 2659 uint32 ref_count_old; 2660 shr_template_to_stream_t *hcts_cb = NULL; 2661 2662 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 2663 SW_STATE_ACCESS_ERROR_CHECK(res); 2664 2665 hash_handle = desc.templateHandle; 2666 extra = desc.extras; 2667 2668 old_template_alloc = old_template - desc.template_low_id; 2669 2670 val = sal_alloc((desc.data_size),"Data buffer"); 2671 old_val = sal_alloc((desc.data_size),"Data buffer old"); 2672 if (!val || !old_val) { 2673 /* alloc failed */ 2674 LOG_ERROR(BSL_LS_SOC_COMMON, 2675 (BSL_META("unable to allocate %u bytes for info\n"), 2676 (unsigned int) 2677 ((desc.data_size)))); 2678 res = BCM_E_MEMORY; 2679 goto exit; 2680 } else { 2681 sal_memset(val,0x0,(desc.data_size)); 2682 2683 /* move to buffer */ 2684 hcts_cb = hash_compare_to_stream_cb[unit]; 2685 res = hcts_cb[extra](data,val,(desc.data_size)); 2686 if (res != BCM_E_NONE) { 2687 goto exit; 2688 } 2689 2690 /* Save old data in case of failure */ 2691 soc_sand_rv = soc_sand_multi_set_get_by_index( 2692 unit, 2693 hash_handle, 2694 old_template_alloc, 2695 old_val, 2696 &ref_count_old); 2697 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2698 /* Get old data failed */ 2699 res = BCM_E_INTERNAL; 2700 goto exit; 2701 } 2702 2703 if (ref_count_old == 0 && !(flags & SHR_TEMPLATE_MANAGE_IGNORE_NOT_EXIST_OLD_TEMPLATE)) { 2704 /* User gave old template that was empty */ 2705 res = BCM_E_PARAM; 2706 goto exit; 2707 } 2708 2709 if (ref_count_old != 0) { 2710 /* Remove old template */ 2711 soc_sand_rv = soc_sand_multi_set_member_remove_by_index( 2712 unit, 2713 hash_handle, 2714 old_template_alloc, 2715 &last_appear); 2716 2717 *is_last = last_appear; 2718 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2719 /* Remove failed */ 2720 res = BCM_E_INTERNAL; 2721 goto exit; 2722 } 2723 } 2724 2725 /* WITH_ID means that the user would like to exchange the current template for a specific new template */ 2726 /* (as opposed to changing the template to any new template containing the supplied data). */ 2727 /* If IGNORE_DATA is not specified, then the user would also like to change the value of the new template. */ 2728 if (flags & SHR_TEMPLATE_MANAGE_SET_WITH_ID) { 2729 uint32 new_template = (uint32) *template - desc.template_low_id; 2730 uint32 old_data_ref_count; 2731 2732 if (!(flags & SHR_TEMPLATE_MANAGE_IGNORE_DATA)) { 2733 uint32 new_data_ref_count; 2734 uint32 old_template_of_new_data; 2735 2736 /* Make sure that the new data does not exist already for another index. */ 2737 /* This check is actually made inside the insert by index as well. */ 2738 /* However no distinguishable error is returned for it. */ 2739 soc_sand_rv = soc_sand_multi_set_member_lookup( 2740 unit, 2741 hash_handle, 2742 val, 2743 &old_template_of_new_data, 2744 &new_data_ref_count); 2745 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2746 /* Get data failed */ 2747 res = BCM_E_INTERNAL; 2748 goto exit; 2749 } 2750 2751 if ((old_template_of_new_data != new_template) && (new_data_ref_count > 0)) { 2752 res = BCM_E_EXISTS; 2753 goto exit; 2754 } 2755 2756 } 2757 2758 /* Get the current data at index (and the ref count to it) and put it into the buffer (val). */ 2759 soc_sand_rv = soc_sand_multi_set_get_by_index( 2760 unit, 2761 hash_handle, 2762 new_template, 2763 val, 2764 &old_data_ref_count); 2765 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2766 /* Get data failed */ 2767 res = BCM_E_INTERNAL; 2768 goto exit; 2769 } 2770 2771 if ((flags & SHR_TEMPLATE_MANAGE_IGNORE_DATA) && (old_data_ref_count == 0)) { 2772 /* WITH_ID and IGNORE_DATA are invalid if the template does not exist - because we don't know where to get */ 2773 /* the new value from. */ 2774 res = BCM_E_NOT_FOUND; 2775 goto exit; 2776 } 2777 2778 /* If we ignore the data or we have a new template, then we need not change the existing template value. */ 2779 if ((flags & SHR_TEMPLATE_MANAGE_IGNORE_DATA) || (old_data_ref_count == 0)) { 2780 /* Add data by index. */ 2781 soc_sand_rv = soc_sand_multi_set_member_add_at_index( 2782 unit, 2783 hash_handle, 2784 val, 2785 new_template, 2786 &first_appear, 2787 &add_success 2788 ); 2789 } else /* We need to change the current template value. */ { 2790 uint8 last_appear; 2791 2792 /* Free all members using the old data. */ 2793 soc_sand_rv = soc_sand_multi_set_member_remove_by_index_multiple( 2794 unit, 2795 hash_handle, 2796 new_template, 2797 old_data_ref_count, 2798 &last_appear); 2799 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2800 /* Get data failed */ 2801 res = BCM_E_INTERNAL; 2802 goto exit; 2803 } 2804 2805 /* VERIFY(data_template == new_template); */ 2806 /* VERIFY(last_appear); */ 2807 2808 /* Move the new data to the buffer. */ 2809 hcts_cb = hash_compare_to_stream_cb[unit]; 2810 res = hcts_cb[extra](data,val,(desc.data_size)); 2811 if (res != BCM_E_NONE) { 2812 goto exit; 2813 } 2814 2815 /* Add ref_count + 1 members using the new data at the required index. */ 2816 soc_sand_rv = soc_sand_multi_set_member_add_at_index_nof_additions( 2817 unit, 2818 hash_handle, 2819 val, 2820 new_template, 2821 old_data_ref_count + 1, 2822 &first_appear, 2823 &add_success 2824 ); 2825 2826 } 2827 } else /* if (!WITH_ID) */ { 2828 /* Add new data. */ 2829 soc_sand_rv = soc_sand_multi_set_member_add( 2830 unit, 2831 hash_handle, 2832 val, 2833 (uint32 *)&template_alloc, 2834 &first_appear, 2835 &add_success 2836 ); 2837 2838 *template = template_alloc + desc.template_low_id; 2839 } 2840 2841 *is_allocated = first_appear; 2842 2843 if (SOC_SAND_FAILURE(soc_sand_rv) || !add_success) { 2844 /* Add new failed, return old data */ 2845 if (!add_success) { 2846 res = BCM_E_MEMORY; 2847 } else { 2848 /* General error */ 2849 res = BCM_E_INTERNAL; 2850 } 2851 2852 if (ref_count_old != 0) { 2853 2854 soc_sand_rv = soc_sand_multi_set_member_add_at_index( 2855 unit, 2856 hash_handle, 2857 old_val, 2858 old_template_alloc, 2859 &first_appear, 2860 &add_success); 2861 2862 if (SOC_SAND_FAILURE(soc_sand_rv) || !add_success) { 2863 /* Internal error */ 2864 res = BCM_E_INTERNAL; 2865 } 2866 } 2867 2868 goto exit; 2869 } 2870 2871 } 2872 2873 exit: 2874 if (val) { 2875 sal_free(val); 2876 } 2877 if (old_val) { 2878 sal_free(old_val); 2879 } 2880 2881 2882 return res; 2883 } 2884 2885 static int _shr_template_hash_exchange_test(int unit, 2886 int pool_id, 2887 uint32 flags, 2888 const void *data, 2889 int old_template, 2890 int *is_last, 2891 int *template, 2892 int *is_allocated) 2893 { 2894 _shr_template_pool_desc_t desc; 2895 int res = BCM_E_NONE; 2896 SOC_SAND_MULTI_SET_KEY * val; 2897 SOC_SAND_MULTI_SET_KEY * old_val; 2898 SOC_SAND_MULTI_SET_PTR hash_handle; 2899 uint8 add_success; 2900 uint8 first_appear = 0; 2901 uint8 last_appear = 0; 2902 int old_template_alloc = 0; 2903 int new_template_alloc = 0; 2904 2905 shr_template_manage_hash_compare_extras_t extra; 2906 uint32 soc_sand_rv; 2907 uint32 ref_count_old; 2908 shr_template_to_stream_t *hcts_cb = NULL; 2909 2910 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 2911 SW_STATE_ACCESS_ERROR_CHECK(res); 2912 2913 hash_handle = desc.templateHandle; 2914 extra = desc.extras; 2915 2916 old_template_alloc = old_template - desc.template_low_id; 2917 2918 val = sal_alloc((desc.data_size),"Data buffer"); 2919 old_val = sal_alloc((desc.data_size),"Data buffer old"); 2920 if (!val || !old_val) { 2921 /* alloc failed */ 2922 LOG_ERROR(BSL_LS_SOC_COMMON, 2923 (BSL_META("unable to allocate %u bytes for info\n"), 2924 (unsigned int) 2925 ((desc.data_size)))); 2926 res = BCM_E_MEMORY; 2927 goto exit; 2928 } else { 2929 sal_memset(val,0x0,(desc.data_size)); 2930 2931 /* move to buffer */ 2932 hcts_cb = hash_compare_to_stream_cb[unit]; 2933 res = hcts_cb[extra](data,val,(desc.data_size)); 2934 if (res != BCM_E_NONE) { 2935 goto exit; 2936 } 2937 2938 /* Save old data in case of failure */ 2939 soc_sand_rv = soc_sand_multi_set_get_by_index( 2940 unit, 2941 hash_handle, 2942 old_template_alloc, 2943 old_val, 2944 &ref_count_old); 2945 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2946 /* Get old data failed */ 2947 res = BCM_E_INTERNAL; 2948 goto exit; 2949 } 2950 2951 if (ref_count_old == 0 && !(flags & SHR_TEMPLATE_MANAGE_IGNORE_NOT_EXIST_OLD_TEMPLATE)) { 2952 /* User gave old template that was empty */ 2953 res = BCM_E_PARAM; 2954 goto exit; 2955 } 2956 2957 if (ref_count_old != 0) { 2958 soc_sand_rv = soc_sand_multi_set_member_remove_by_index( 2959 unit, 2960 hash_handle, 2961 old_template_alloc, 2962 &last_appear); 2963 2964 *is_last = last_appear; 2965 2966 if (SOC_SAND_FAILURE(soc_sand_rv)) { 2967 res = BCM_E_INTERNAL; 2968 goto exit; 2969 } 2970 } 2971 2972 /* Add new data */ 2973 soc_sand_rv = soc_sand_multi_set_member_add( 2974 unit, 2975 hash_handle, 2976 val, 2977 (uint32 *)&new_template_alloc, 2978 &first_appear, 2979 &add_success 2980 ); 2981 *template = new_template_alloc + desc.template_low_id; 2982 2983 *is_allocated = first_appear; 2984 2985 if (SOC_SAND_FAILURE(soc_sand_rv) || !add_success) { 2986 if (!add_success) { 2987 res = BCM_E_MEMORY; 2988 } else { 2989 /* General error */ 2990 res = BCM_E_INTERNAL; 2991 } 2992 } 2993 else { 2994 /* Remove new data */ 2995 soc_sand_rv = soc_sand_multi_set_member_remove_by_index( 2996 unit, 2997 hash_handle, 2998 new_template_alloc, 2999 &last_appear); 3000 if (SOC_SAND_FAILURE(soc_sand_rv)) { 3001 LOG_ERROR(BSL_LS_SOC_COMMON, 3002 (BSL_META("Failed to release new allocated data.\n"))); 3003 res = BCM_E_INTERNAL; 3004 goto exit; 3005 } 3006 } 3007 3008 if (ref_count_old != 0) { 3009 soc_sand_rv = soc_sand_multi_set_member_add_at_index( 3010 unit, 3011 hash_handle, 3012 old_val, 3013 old_template_alloc, 3014 &first_appear, 3015 &add_success); 3016 3017 if (SOC_SAND_FAILURE(soc_sand_rv)) { 3018 res = BCM_E_INTERNAL; 3019 goto exit; 3020 } 3021 } 3022 } 3023 3024 exit: 3025 if (val) { 3026 sal_free(val); 3027 } 3028 if (old_val) { 3029 sal_free(old_val); 3030 } 3031 3032 3033 return res; 3034 } 3035 3036 static int _shr_template_hash_data_get(int unit, 3037 int pool_id, 3038 int template, 3039 void *data) 3040 { 3041 _shr_template_pool_desc_t desc; 3042 int res = BCM_E_NONE; 3043 SOC_SAND_MULTI_SET_KEY * val; 3044 SOC_SAND_MULTI_SET_PTR hash_handle; 3045 uint32 ref_count; 3046 shr_template_manage_hash_compare_extras_t extra; 3047 uint32 soc_sand_rv; 3048 int template_alloc; 3049 shr_template_from_stream_t *hcfs_cb = NULL; 3050 3051 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 3052 SW_STATE_ACCESS_ERROR_CHECK(res); 3053 3054 hash_handle = desc.templateHandle; 3055 extra = desc.extras; 3056 3057 template_alloc = template - desc.template_low_id; 3058 3059 val = sal_alloc((desc.data_size),"Data buffer"); 3060 3061 if (!val) { 3062 /* alloc failed */ 3063 LOG_ERROR(BSL_LS_SOC_COMMON, 3064 (BSL_META("unable to allocate %u bytes for info\n"), 3065 (unsigned int) 3066 ((desc.data_size)))); 3067 res = BCM_E_MEMORY; 3068 } else { 3069 sal_memset(val,0x0,(desc.data_size)); 3070 3071 soc_sand_rv = soc_sand_multi_set_get_by_index( 3072 unit, 3073 hash_handle, 3074 template_alloc, 3075 val, 3076 &ref_count); 3077 3078 3079 if (!SOC_SAND_FAILURE(soc_sand_rv) && ref_count != 0) { 3080 hcfs_cb = hash_compare_from_stream_cb[unit]; 3081 res = (hcfs_cb[extra](data,val,(desc.data_size))); 3082 if (res != BCM_E_NONE) { 3083 /* Problem with from stream */ 3084 res = BCM_E_INTERNAL; 3085 } 3086 } else { 3087 /* No data */ 3088 res = BCM_E_NOT_FOUND; 3089 } 3090 } 3091 3092 if (val) { 3093 sal_free(val); 3094 } 3095 return res; 3096 } 3097 3098 static int _shr_template_hash_index_get(int unit, 3099 int pool_id, 3100 const void *data, 3101 int* template) 3102 { 3103 _shr_template_pool_desc_t desc; 3104 int res = BCM_E_NONE; 3105 SOC_SAND_MULTI_SET_KEY * val; 3106 SOC_SAND_MULTI_SET_PTR hash_handle; 3107 uint32 ref_count; 3108 shr_template_manage_hash_compare_extras_t extra; 3109 uint32 soc_sand_rv; 3110 uint32 template_alloc; 3111 shr_template_to_stream_t *hcts_cb = NULL; 3112 3113 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 3114 SW_STATE_ACCESS_ERROR_CHECK(res); 3115 3116 hash_handle = desc.templateHandle; 3117 extra = desc.extras; 3118 3119 val = sal_alloc((desc.data_size),"Data buffer"); 3120 3121 if (!val) { 3122 /* alloc failed */ 3123 LOG_ERROR(BSL_LS_SOC_COMMON, 3124 (BSL_META("unable to allocate %u bytes for info\n"), 3125 (unsigned int) 3126 ((desc.data_size)))); 3127 res = BCM_E_MEMORY; 3128 } else { 3129 sal_memset(val,0x0,(desc.data_size)); 3130 3131 /* move to buffer */ 3132 hcts_cb = hash_compare_to_stream_cb[unit]; 3133 res = hcts_cb[extra](data,val,(desc.data_size)); 3134 if (res != BCM_E_NONE) { 3135 goto exit; 3136 } 3137 3138 /* Make sure that the new data does not exist already for another index. */ 3139 /* This check is actually made inside the insert by index as well. */ 3140 /* However no distinguishable error is returned for it. */ 3141 soc_sand_rv = soc_sand_multi_set_member_lookup( 3142 unit, 3143 hash_handle, 3144 val, 3145 &template_alloc, 3146 &ref_count); 3147 if (SOC_SAND_FAILURE(soc_sand_rv)) { 3148 /* Get data failed */ 3149 res = BCM_E_INTERNAL; 3150 goto exit; 3151 } 3152 3153 if (ref_count == 0) { 3154 res = BCM_E_NOT_FOUND; 3155 } else { 3156 *template = template_alloc + desc.template_low_id; 3157 } 3158 } 3159 3160 exit: 3161 if (val) { 3162 sal_free(val); 3163 } 3164 return res; 3165 } 3166 3167 3168 static int _shr_template_hash_ref_count_get(int unit, 3169 int pool_id, 3170 int template, 3171 uint32 *ref_count) 3172 { 3173 _shr_template_pool_desc_t desc; 3174 int res = BCM_E_NONE; 3175 SOC_SAND_MULTI_SET_KEY * val; 3176 SOC_SAND_MULTI_SET_PTR hash_handle; 3177 uint32 soc_sand_rv; 3178 uint32 tmp_ref_count = 0; 3179 int template_alloc; 3180 3181 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 3182 SW_STATE_ACCESS_ERROR_CHECK(res); 3183 3184 hash_handle = desc.templateHandle; 3185 3186 template_alloc = template - desc.template_low_id; 3187 3188 val = sal_alloc((desc.data_size),"Data buffer"); 3189 3190 if (!val) { 3191 /* alloc failed */ 3192 LOG_ERROR(BSL_LS_SOC_COMMON, 3193 (BSL_META("unable to allocate %u bytes for info\n"), 3194 (unsigned int) 3195 ((desc.data_size)))); 3196 res = BCM_E_MEMORY; 3197 } else { 3198 sal_memset(val,0x0,(desc.data_size)); 3199 3200 soc_sand_rv = soc_sand_multi_set_get_by_index( 3201 unit, 3202 hash_handle, 3203 template_alloc, 3204 val, 3205 &tmp_ref_count); 3206 3207 3208 if (!SOC_SAND_FAILURE(soc_sand_rv)) { 3209 /* Update reference count */ 3210 *ref_count = tmp_ref_count; 3211 } else { 3212 /* Got error */ 3213 res = BCM_E_INTERNAL; 3214 } 3215 } 3216 3217 if (val) { 3218 sal_free(val); 3219 } 3220 return res; 3221 } 3222 3223 static int _shr_template_hash_clear(int unit, int pool_id) 3224 { 3225 _shr_template_pool_desc_t desc; 3226 int res = BCM_E_NONE; 3227 SOC_SAND_MULTI_SET_PTR hash_handle; 3228 uint32 soc_sand_rv; 3229 3230 res = TEMPLATE_ACCESS.pool.get(unit, pool_id, &desc); 3231 SW_STATE_ACCESS_ERROR_CHECK(res); 3232 3233 hash_handle = desc.templateHandle; 3234 3235 soc_sand_rv = soc_sand_multi_set_clear(unit, hash_handle); 3236 SOC_SAND_IF_ERR_RETURN(soc_sand_rv); 3237 3238 return res; 3239 } 3240 #endif /* BCM_PETRA_SUPPORT || BCM_DFE_SUPPORT */