rx_pool.c (18872B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: rx_pool.c 8 * Purpose: Receive packet pool code 9 * Requires: 10 */ 11 12 #include <shared/bsl.h> 13 14 #include <sal/core/libc.h> 15 16 #include <soc/drv.h> 17 #include <soc/higig.h> 18 #include <soc/property.h> 19 20 #include <bcm_int/common/rx.h> 21 #include <bcm_int/control.h> 22 #include <bcm/rx.h> 23 #include <bcm/stack.h> 24 25 26 /**************************************************************** 27 * 28 * RX POOL CODE: 29 * 30 * Default allocation and free routines 31 * 32 * This code sets up a very simple pool of packet buffers for RX. 33 * The buffer pool holds a fixed number of fixed size packets. 34 * If the pool is exhausted, the allocation returns NULL. 35 */ 36 37 static uint8 *rxp_all_bufs; /* Allocation pointer */ 38 #if defined(BCM_RXP_DEBUG) 39 static uint8 *rxp_end_bufs; /* Points to first byte after all bufs */ 40 #endif 41 static uint8 *rxp_free_list; /* Free list pointer */ 42 static int rxp_pkt_size; /* Base packet size */ 43 static int rxp_pkt_count; /* How many packets in pool */ 44 45 static sal_mutex_t rxp_mutex; 46 47 int rxp_memory_source_heap = 0; /* Mem source is not heap to begin-with */ 48 static void *bcm_rx_pool_memory_alloc(unsigned int size, char *locus); 49 static void bcm_rx_pool_memory_free(void *rx_pool_addr); 50 51 #ifdef BCM_RX_REFILL_FROM_INTR 52 /* Must be interrupt-safe in this mode */ 53 #define RXP_LOCK RX_INTR_LOCK 54 #define RXP_UNLOCK RX_INTR_UNLOCK 55 #else 56 #define RXP_LOCK sal_mutex_take(rxp_mutex, sal_mutex_FOREVER) 57 #define RXP_UNLOCK sal_mutex_give(rxp_mutex) 58 #endif 59 60 /* 61 * Define buffer alignment in physical memory. 62 * 63 * This is a system-specific parameter, but it is currently not possible 64 * to retrieve this information through the SAL or BDE interfaces. 65 */ 66 #ifndef BCM_CACHE_LINE_BYTES 67 #define BCM_CACHE_LINE_BYTES 128 /* Should be fine on most platforms */ 68 #endif 69 #define RXP_ALIGN(_a) \ 70 ((_a + (BCM_CACHE_LINE_BYTES - 1)) & ~(BCM_CACHE_LINE_BYTES - 1)) 71 72 #define RXP_INIT \ 73 if (rxp_mutex == NULL && \ 74 (rxp_mutex = sal_mutex_create("rx_pool")) == NULL) \ 75 return BCM_E_MEMORY 76 77 /* Define function interfaces to RX pool memory allocator 78 79 External functions must provide the same interface as 80 sal_dma_alloc() and sal_dma_free(). 81 82 BCM_RX_POOL_MEM_ALLOC() is called once during bcm_rx_pool_setup() 83 to allocate RX buffer memory. 84 85 BCM_RX_POOL_MEM_FREE() is called once during bcm_rx_pool_cleanup() 86 to release allocated RX buffer memory if memory was allocated. Once 87 allocated memory is freed, BCM_RX_POOL_MEM_FREE() will not be 88 called again until after the next call to bcm_rx_pool_setup(). 89 90 */ 91 #ifndef BCM_RX_POOL_MEM_ALLOC 92 #define BCM_RX_POOL_MEM_ALLOC bcm_rx_pool_memory_alloc 93 #endif 94 95 #ifndef BCM_RX_POOL_MEM_FREE 96 #define BCM_RX_POOL_MEM_FREE bcm_rx_pool_memory_free 97 #endif 98 99 /* Any byte in a buffer may be used to reference that buffer when freeing */ 100 101 /* Buffer index; use any byte in buffer to get proper index */ 102 #define RXP_BUF_IDX(buf) \ 103 ( ((buf) - rxp_all_bufs) / rxp_pkt_size ) 104 105 /* 106 * Get the start/end addresses of a buffer given the index of the pkt 107 */ 108 109 #define RXP_BUF_START(idx) \ 110 (rxp_all_bufs + ((idx) * rxp_pkt_size)) 111 112 /* 113 * Get the start address of a buffer given a pointer to any byte in the 114 * buffer. 115 */ 116 117 #define RXP_PTR_TO_START(ptr) RXP_BUF_START(RXP_BUF_IDX(ptr)) 118 119 /* 120 * When buffers are not allocated, the first word is used as a pointer 121 * for linked lists. Requires alignment of the buffers. 122 */ 123 #define RXP_PKT_NEXT(buf) ( ((uint8 **)(RXP_PTR_TO_START(buf)))[0]) 124 125 #if defined(BCM_RXP_DEBUG) 126 127 /* 128 * Does "val" point into the buffer space at all? 129 */ 130 131 #define RXP_IN_BUFFER_SPACE(val) \ 132 (((val) < rxp_end_bufs) && ((val) >= rxp_all_bufs)) 133 134 /* 135 * Does "val" point to the start of a buffer? 136 */ 137 138 #define RXP_IS_BUF_START(val) \ 139 (RXP_IN_BUFFER_SPACE(val) && \ 140 (((val) - rxp_all_bufs) % rxp_pkt_size == 0)) 141 142 /* 143 * Keep pointer to "owner" for each packet 144 * 145 * Buffers are filled with 0xee (empty) when on free list; 146 * Filled with 0xaa when allocated 147 */ 148 149 typedef struct { 150 int state; 151 const char *owner; 152 int alloc; 153 int free; 154 } RXP_TRACK_t; 155 156 static RXP_TRACK_t *rxp_tracker; 157 static int rxp_tot_alloc_count; 158 static int rxp_tot_free_count; 159 static int rxp_alloc_fail; 160 161 static int bcm_rx_pool_free_buf_verify(void *buf); 162 static int bcm_rx_pool_free_verify_p(void); 163 164 #endif /* BCM_RXP_DEBUG */ 165 166 static int rxp_alloc_count; 167 168 /* 169 * Function: 170 * bcm_rx_pool_memory_alloc 171 * Purpose: 172 * Allocate memory for RX Pool 173 * Parameters: 174 * size - Number of bytes to be allocated 175 * locus - User defined memory description 176 * Returns: 177 * Valid Address, if allocation successful else NULL. 178 * Notes: 179 * The function allocates the memory from heap if directed 180 * so based on the global variable rxp_memory_source_heap. 181 */ 182 static void * 183 bcm_rx_pool_memory_alloc(unsigned int size, char *locus) 184 { 185 return (rxp_memory_source_heap ? 186 sal_alloc(size, locus) : sal_dma_alloc(size, locus)); 187 } 188 189 /* 190 * Function: 191 * bcm_rx_pool_memory_free 192 * Purpose: 193 * Deallocate given memory from RX Pool 194 * Parameters: 195 * ptr - Address of the RX pool 196 * Returns: 197 * None 198 * Notes: 199 * 1) Function assumes given address is valid RX pool buffer address 200 * 2) It releases memory to heap instead of DMA pool if directed so 201 */ 202 static void 203 bcm_rx_pool_memory_free(void *rx_pool_addr) 204 { 205 rxp_memory_source_heap ? 206 sal_free(rx_pool_addr) : sal_dma_free(rx_pool_addr); 207 } 208 209 210 /* 211 * Function: 212 * bcm_rx_pool_setup 213 * Purpose: 214 * Setup the RX packet pool 215 * Parameters: 216 * pkt_count - How many pkts in pool. < 0 ==> default 217 * bytes_per_pkt - Packet allocation size 218 * Returns: 219 * BCM_E_XXX 220 * Notes: 221 * Force alignment of the words so the pointers are safe 222 * 223 * The pool cannot be setup up twice without calling cleanup 224 * to deallocate pointers. 225 */ 226 227 int 228 bcm_rx_pool_setup(int pkt_count, int bytes_per_pkt) 229 { 230 uint8 *buf, *next_buf; 231 int i; 232 233 RXP_INIT; 234 235 if (rxp_all_bufs != NULL) { 236 return BCM_E_BUSY; 237 } 238 239 if (pkt_count < 0) { 240 pkt_count = BCM_RX_POOL_COUNT_DEFAULT; 241 } 242 if (bytes_per_pkt < 0) { 243 bytes_per_pkt = BCM_RX_POOL_BYTES_DEFAULT; 244 } else { 245 /* Add 14 dwords worth extra space for HG and other Module headers */ 246 bytes_per_pkt += 56; 247 } 248 249 /* Force packet alignment */ 250 bytes_per_pkt = RXP_ALIGN(bytes_per_pkt); 251 rxp_pkt_size = bytes_per_pkt; 252 rxp_pkt_count = pkt_count; 253 rxp_all_bufs = BCM_RX_POOL_MEM_ALLOC(pkt_count * rxp_pkt_size, "bcm_rx_pool"); 254 if (rxp_all_bufs == NULL) { 255 return BCM_E_MEMORY; 256 } 257 /* Set to all 0xee for RXP debug */ 258 sal_memset(rxp_all_bufs, 0xee, rxp_pkt_count * rxp_pkt_size); 259 260 RXP_LOCK; 261 buf = rxp_all_bufs; 262 rxp_free_list = buf; 263 for (i = 0; i < pkt_count - 1; i++) { 264 next_buf = buf + rxp_pkt_size; 265 RXP_PKT_NEXT(buf) = next_buf; 266 buf = next_buf; 267 } 268 269 RXP_PKT_NEXT(buf) = NULL; 270 271 #if defined(BCM_RXP_DEBUG) 272 { 273 int bytes; 274 int idx; 275 bytes = sizeof(RXP_TRACK_t) * pkt_count; 276 rxp_tracker = sal_alloc(bytes, "rx_pool_dbg"); 277 for (idx = 0; idx < pkt_count; idx++) { 278 rxp_tracker[idx].owner = ""; 279 rxp_tracker[idx].state = 0; 280 rxp_tracker[idx].alloc = 0; 281 rxp_tracker[idx].free = 0; 282 } 283 rxp_tot_alloc_count = 0; 284 rxp_tot_free_count = 0; 285 rxp_alloc_fail = 0; 286 rxp_end_bufs = rxp_all_bufs + rxp_pkt_count * rxp_pkt_size; 287 } 288 #endif 289 rxp_alloc_count = 0; 290 RXP_UNLOCK; 291 292 return BCM_E_NONE; 293 } 294 295 296 /* 297 * Function: 298 * bcm_rx_pool_setup_done 299 * Purpose: 300 * Indicate if setup is complete 301 * Returns: 302 * Boolean: True if setup is done 303 */ 304 305 int 306 bcm_rx_pool_setup_done(void) 307 { 308 return rxp_all_bufs != NULL; 309 } 310 311 312 /* 313 * Function: 314 * bcm_rx_pool_cleanup 315 * Purpose: 316 * Deallocate the rx buffer pool 317 * Returns: 318 * BCM_E_XXX 319 * Notes: 320 * No checking is done to see if pointers are outstanding. 321 */ 322 323 int 324 bcm_rx_pool_cleanup(void) 325 { 326 if (rxp_all_bufs == NULL) { 327 return BCM_E_NONE; 328 } 329 330 RXP_LOCK; 331 332 #ifndef BCM_SAND_SUPPORT 333 /* If any pkt data block is still in use then return BUSY err code */ 334 if (rxp_alloc_count) { 335 RXP_UNLOCK; 336 return BCM_E_BUSY; 337 } 338 #endif 339 340 BCM_RX_POOL_MEM_FREE(rxp_all_bufs); 341 342 rxp_all_bufs = NULL; 343 rxp_free_list = NULL; 344 345 #if defined(BCM_RXP_DEBUG) 346 sal_free(rxp_tracker); 347 rxp_tracker = NULL; 348 #endif 349 RXP_UNLOCK; 350 351 return BCM_E_NONE; 352 } 353 354 /* 355 * Function: 356 * bcm_rx_pool_alloc 357 * Purpose: 358 * Allocate a buffer from a fixed pool configured 359 * by bcm_rx_pool_setup. 360 * Parameters: 361 * unit - Ignored 362 * size - Size of buffer to allocate 363 * flags - Ignored 364 * Returns: 365 * Pointer to buffer if successful, NULL if failure. 366 * Notes: 367 * Can fail for: 368 * 369 * 1. One size fits all....if size > how the list was set up, 370 * then the function fails. 371 * 2. Not initialized 372 * 3. No free buffers 373 * 374 * The first word of the buffer is used as a "next" pointer when 375 * the buffer is in the free list. 376 */ 377 378 int 379 bcm_rx_pool_alloc(int unit, int size, uint32 flags, void **pool) 380 { 381 uint8 *rv; 382 383 COMPILER_REFERENCE(unit); 384 COMPILER_REFERENCE(flags); 385 386 if (rxp_mutex == NULL) { 387 *pool = NULL; 388 return BCM_E_TIMEOUT; 389 } 390 391 if (rxp_pkt_size > 0) { 392 size = rxp_pkt_size; 393 } 394 395 if (size > rxp_pkt_size) { 396 LOG_ERROR(BSL_LS_BCM_COMMON, 397 (BSL_META_U(unit, 398 "bcm_rx_pool_alloc: %d > %d\n"), 399 size, rxp_pkt_size)); 400 *pool = NULL; 401 return BCM_E_MEMORY; 402 } 403 404 RXP_LOCK; 405 if (rxp_free_list == NULL) { 406 #if defined(BCM_RXP_DEBUG) 407 ++rxp_alloc_fail; 408 #endif 409 RXP_UNLOCK; 410 *pool = NULL; 411 return BCM_E_MEMORY; 412 } 413 rv = rxp_free_list; 414 rxp_free_list = RXP_PKT_NEXT(rxp_free_list); 415 416 #if defined(BCM_RXP_DEBUG) 417 { 418 int idx; 419 static const char *track_name = "rx_pool_alloc"; 420 421 assert(RXP_IS_BUF_START(rv)); 422 if (rxp_free_list != NULL) { 423 assert(RXP_IS_BUF_START(rxp_free_list)); 424 } 425 426 idx = RXP_BUF_IDX(rv); 427 rxp_tracker[idx].owner = track_name; 428 rxp_tracker[idx].state = 1; 429 rxp_tracker[idx].alloc++; 430 if (bcm_rx_pool_free_buf_verify(rv) != BCM_E_NONE) { 431 assert(0); 432 } 433 434 /* Fill allocated buffer with 0xaa */ 435 sal_memset(rv, 0xaa, rxp_pkt_size); 436 ++rxp_tot_alloc_count; 437 } 438 #endif /* BCM_RXP_DEBUG */ 439 ++rxp_alloc_count; 440 441 RXP_UNLOCK; 442 443 *pool = (void *)rv; 444 return BCM_E_NONE; 445 } 446 447 /* 448 * Function: 449 * bcm_rx_pool_free 450 * Purpose: 451 * Return a buffer allocated by bcm_rx_pool_alloc to the free list 452 * Parameters: 453 * unit - Ignored 454 * buf - The buffer to free 455 * Returns: 456 * BCM_E_XXX 457 */ 458 459 int 460 bcm_rx_pool_free(int unit, void *buf) 461 { 462 uint8 *start; 463 uint8 *buf8; 464 465 COMPILER_REFERENCE(unit); 466 467 RXP_LOCK; 468 469 if (rxp_all_bufs == NULL) { /* not running */ 470 RXP_UNLOCK; 471 return BCM_E_MEMORY; 472 } 473 474 buf8 = (uint8 *)buf; 475 start = RXP_PTR_TO_START(buf8); 476 477 #if defined(BCM_RXP_DEBUG) 478 { 479 int idx, i; 480 uint32 *ptr; 481 482 COMPILER_REFERENCE(ptr); 483 COMPILER_REFERENCE(i); 484 idx = RXP_BUF_IDX(buf8); 485 assert((idx >= 0 && idx < rxp_pkt_count)); 486 rxp_tracker[idx].free++; 487 if (rxp_tracker[idx].state == 0) { 488 /* Buffers should never be freed more than once, but 489 distinguish the error between a freed buffer that gets 490 reused vs. one that doesn't. */ 491 LOG_WARN(BSL_LS_BCM_COMMON, 492 (BSL_META_U(unit, 493 "Double free of buffer %d\n"), 494 idx)); 495 if (bcm_rx_pool_free_buf_verify(buf) != BCM_E_NONE) { 496 assert(0); 497 } 498 assert(0); 499 } 500 rxp_tracker[idx].state = 0; 501 /* Fill buffer with 0xee, except for first word */ 502 sal_memset(RXP_BUF_START(idx) + sizeof(void *), 0xee, 503 rxp_pkt_size - sizeof(void *)); 504 #if 1 /* Turn this on to verify the entire free list */ 505 if (bcm_rx_pool_free_verify_p() != BCM_E_NONE) { 506 LOG_WARN(BSL_LS_BCM_COMMON, 507 (BSL_META_U(unit, 508 "RX Pool error while checking %d\n"), 509 idx)); 510 assert(0); 511 } 512 #else 513 /* Check head of free list for good measure */ 514 if (rxp_free_list != NULL) { 515 if (bcm_rx_pool_free_buf_verify(rxp_free_list) != BCM_E_NONE) { 516 assert(0); 517 } 518 } 519 #endif 520 ++rxp_tot_free_count; 521 } 522 #endif /* BCM_RXP_DEBUG */ 523 524 rxp_alloc_count--; 525 526 RXP_PKT_NEXT(start) = rxp_free_list; 527 rxp_free_list = start; 528 RXP_UNLOCK; 529 530 return BCM_E_NONE; 531 } 532 533 534 #if defined(BCM_RXP_DEBUG) 535 536 void 537 bcm_rx_pool_dump(int min, int max) 538 { 539 int i; 540 uint32 *ptr; 541 542 if (min < 0) { 543 min = 0; 544 } 545 if (max > rxp_pkt_count) { 546 max = rxp_pkt_count; 547 } 548 for (i = min; i < max; i++) { 549 ptr = (uint32 *)RXP_BUF_START(i); 550 LOG_WARN(BSL_LS_BCM_COMMON, 551 (BSL_META("Pkt %d: %p. [0] 0x%x [1] 0x%x [2] 0x%x\n"), 552 i, 553 ptr, ptr[0], ptr[1], ptr[2])); 554 } 555 } 556 557 /* Check a buffer in the free pool */ 558 559 #define FREE_STATE 0xeeeeeeee 560 #define ALLOC_STATE 0xaaaaaaaa 561 562 void 563 bcm_rx_pool_buf_dump(void *buf, int until) 564 { 565 int i; 566 uint32 *ptr; 567 568 ptr = ((uint32 *)RXP_PTR_TO_START((uint8 *)buf)) + 1; 569 for (i = 0; i < rxp_pkt_size - sizeof(void *); i += sizeof(uint32)) { 570 if ((i & 31) == 0) { 571 if (i > until && (*ptr == FREE_STATE || *ptr == ALLOC_STATE)) { 572 break; 573 } 574 LOG_ERROR(BSL_LS_BCM_COMMON, 575 (BSL_META("\n%p:"), 576 ptr)); 577 } 578 LOG_ERROR(BSL_LS_BCM_COMMON, 579 (BSL_META(" %08x"), 580 *ptr)); 581 ptr++; 582 } 583 LOG_ERROR(BSL_LS_BCM_COMMON, 584 (BSL_META("\n"))); 585 } 586 587 588 static int 589 bcm_rx_pool_free_buf_verify(void *buf) 590 { 591 int i; 592 uint32 *ptr; 593 594 ptr = (uint32 *)(RXP_PTR_TO_START((uint8 *)buf) + sizeof (void *)); 595 for (i = 0; i < rxp_pkt_size - sizeof(void *); i += sizeof(uint32)) { 596 if (*ptr != FREE_STATE) { 597 return BCM_E_INTERNAL; 598 } 599 ptr++; 600 } 601 return BCM_E_NONE; 602 } 603 604 /* Check the entire free pool and return BCM_E_NONE if OK or BCM_E_INTERNAL if there 605 was some sort of inconsistency detected. */ 606 static int 607 bcm_rx_pool_free_verify_p(void) 608 { 609 uint8 *buf; 610 uint8 *last_buf = NULL; 611 int idx; 612 int rc = BCM_E_NONE; 613 614 for (buf = rxp_free_list; buf != NULL; buf = RXP_PKT_NEXT(buf)) { 615 idx = RXP_BUF_IDX(buf); 616 if (!(idx >= 0 && idx < rxp_pkt_count)) { 617 LOG_WARN(BSL_LS_BCM_COMMON, 618 (BSL_META("RXP BAD BUFFER %p. idx %d\n"), 619 buf, idx)); 620 if (last_buf != NULL) { 621 LOG_WARN(BSL_LS_BCM_COMMON, 622 (BSL_META("RXP BAD BUFFER: Previous buf %p idx %d\n"), 623 last_buf, RXP_BUF_IDX(last_buf))); 624 } else { 625 LOG_WARN(BSL_LS_BCM_COMMON, 626 (BSL_META("RXP BAD BUFFER: First elt of free list\n"))); 627 } 628 if (idx >= 0 && idx < rxp_pkt_count) { 629 LOG_WARN(BSL_LS_BCM_COMMON, 630 (BSL_META("RXP IDX %d out of range (0,%d)"), 631 idx, rxp_pkt_count)); 632 } 633 return BCM_E_INTERNAL; 634 } 635 last_buf = buf; 636 if ((rc=bcm_rx_pool_free_buf_verify(buf)) != BCM_E_NONE) { 637 return rc; 638 } 639 } 640 return rc; 641 } 642 643 /* API call */ 644 void 645 bcm_rx_pool_free_verify(void) 646 { 647 (void)bcm_rx_pool_free_verify_p(); 648 } 649 650 void 651 bcm_rx_pool_own(void *buf, void *owner) 652 { 653 #if defined(LINUX) || defined(__KERNEL__) 654 /* Need to fix this */ 655 return; 656 #else 657 int idx; 658 idx = RXP_BUF_IDX((uint8 *)buf); 659 660 #if 1 /* Turn this off to give warning rather than assert */ 661 assert((idx >= 0) && (idx < rxp_pkt_count)); 662 rxp_tracker[idx].owner = (char *)owner; 663 #else 664 if ((idx < 0) || (idx >= rxp_pkt_count)) { 665 LOG_WARN(BSL_LS_BCM_COMMON, 666 (BSL_META("RXP: Buffer %p (idx %d) out of range " 667 "max %d, owner %s\n"), buf, idx, 668 rxp_pkt_count, (char *)owner)); 669 } else { 670 /* assert((idx > 0) && (idx < rxp_pkt_count)); */ 671 rxp_tracker[idx].owner = (char *)owner; 672 } 673 #endif 674 #endif 675 } 676 677 #define _ISALPHA(c) \ 678 ((c[0] >= 'A' && c[0] <= 'Z') || (c[0] >= 'a' && c[0] <= 'z')) 679 680 /* Check that a buffer is in use, or free and not corrupted */ 681 static int rx_pool_buf_ok(int idx) 682 { 683 if (rxp_tracker[idx].state == 0) { 684 return bcm_rx_pool_free_buf_verify(RXP_BUF_START(idx)); 685 } 686 return BCM_E_NONE; 687 } 688 689 void 690 bcm_rx_pool_report(int min, int max) 691 { 692 int i, count = 0; 693 const char *str; 694 695 for (i = 0; i < rxp_pkt_count; i++) { 696 if (rxp_tracker[i].state != 0) { 697 count++; 698 } 699 } 700 LOG_ERROR(BSL_LS_BCM_COMMON, 701 (BSL_META(" # s alloc free owner\n"))); 702 LOG_ERROR(BSL_LS_BCM_COMMON, 703 (BSL_META("--- - -------- -------- ------------\n"))); 704 for (i = min; i < max; i++) { 705 str = rxp_tracker[i].owner; 706 LOG_ERROR(BSL_LS_BCM_COMMON, 707 (BSL_META("%3d %1d%s %8d %8d %p %s\n"), 708 i, 709 rxp_tracker[i].state, 710 rx_pool_buf_ok(i)? "?" : " ", 711 rxp_tracker[i].alloc, 712 rxp_tracker[i].free, 713 str, 714 _ISALPHA(str) ? str : "?")); 715 } 716 717 LOG_ERROR(BSL_LS_BCM_COMMON, 718 (BSL_META(" RXPool Used %d. Failed %d. Tot alloc %d. " 719 "Tot free %d. Size %d. Count %d.\n"), rxp_alloc_count, rxp_alloc_fail, 720 rxp_tot_alloc_count, rxp_tot_free_count, rxp_pkt_size, rxp_pkt_count)); 721 if (count != rxp_alloc_count) { 722 LOG_ERROR(BSL_LS_BCM_COMMON, 723 (BSL_META(" RXP WARNING: Alloc %d, counted %d\n"), 724 rxp_alloc_count, count)); 725 } 726 } 727 #undef _ISALPHA 728 729 #endif /* BCM_RXP_DEBUG */