1 /******************************************************************************
3 * Copyright (c) 2019 Intel.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *******************************************************************************/
20 * @file This file has Shared Memory interface functions between FAPI and PHY
21 * @defgroup nr5g_fapi_source_framework_wls_lib_group
24 #include "nr5g_fapi_framework.h"
25 #include "nr5g_fapi_internal.h"
26 #include "nr5g_fapi_wls.h"
27 #include "nr5g_fapi_config_loader.h"
28 #include "nr5g_fapi_log.h"
29 #include "nr5g_fapi_memory.h"
31 nr5g_fapi_wls_context_t g_wls_ctx;
33 static uint32_t g_to_free_send_list_cnt[TO_FREE_SIZE] = { 0 };
34 static uint64_t g_to_free_send_list[TO_FREE_SIZE][TOTAL_FREE_BLOCKS] = { {0L} };
35 static uint32_t g_to_free_recv_list_cnt[TO_FREE_SIZE] = { 0 };
36 static uint64_t g_to_free_recv_list[TO_FREE_SIZE][TOTAL_FREE_BLOCKS] = { {0L} };
38 static uint8_t alloc_track[ALLOC_TRACK_SIZE];
40 //------------------------------------------------------------------------------
41 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
45 * @return A pointer to WLS Context stucture
48 * This function returns the WLS Context structure which has WLS related parameters
51 //------------------------------------------------------------------------------
52 inline p_nr5g_fapi_wls_context_t nr5g_fapi_wls_context(
58 //------------------------------------------------------------------------------
59 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
61 * @param[in] ptr Pointer to display
62 * @param[in] size Size of data
67 * This function displays content of Buffer - Used for debugging
70 //------------------------------------------------------------------------------
71 void nr5g_fapi_wls_show_data(
78 for (i = 0; i < size; i++) {
81 printf("%02x ", d[i]);
86 //------------------------------------------------------------------------------
87 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
94 * This function prints to the console FAPI stats
97 //------------------------------------------------------------------------------
98 void nr5g_fapi_wls_print_stats(
101 p_nr5g_fapi_wls_context_t pWls = nr5g_fapi_wls_context();
102 printf(" nTotalBlocks[%5d] nAllocBlocks[%5d] nFreeBlocks[%5d]\n",
103 pWls->nTotalBlocks, pWls->nAllocBlocks,
104 (pWls->nTotalBlocks - pWls->nAllocBlocks));
105 printf(" nTotalAllocCnt[%5d] nTotalFreeCnt[%5d] Diff[%5d]\n",
106 pWls->nTotalAllocCnt, pWls->nTotalFreeCnt,
107 (pWls->nTotalAllocCnt - pWls->nTotalFreeCnt));
108 uint32_t nFinalTotalDlBufAllocCnt = 0, nFinalTotalDlBufFreeCnt = 0, idx;
110 //#define PRINTF_DEBUG(fmt, args...) //printf(fmt, ## args)
111 #define PRINTF_DEBUG(fmt, args...)
113 PRINTF_DEBUG("\n nDlBufAllocCnt: \n");
114 for (idx = 0; idx < MEM_STAT_DEFAULT; idx++) {
115 nFinalTotalDlBufAllocCnt += pWls->nTotalDlBufAllocCnt[idx];
116 PRINTF_DEBUG("[%3d:%5d] ", idx, pWls->nTotalDlBufAllocCnt[idx]);
119 PRINTF_DEBUG("\n nDlBufFreeCnt: \n");
120 for (idx = 0; idx < MEM_STAT_DEFAULT; idx++) {
121 nFinalTotalDlBufFreeCnt += pWls->nTotalDlBufFreeCnt[idx];
122 PRINTF_DEBUG("[%3d:%5d] ", idx, pWls->nTotalDlBufFreeCnt[idx]);
124 PRINTF_DEBUG("\n\n");
126 printf(" nDlBufAllocCnt[%5d] nDlBufFreeCnt[%5d] Diff[%5d]\n",
127 nFinalTotalDlBufAllocCnt, nFinalTotalDlBufFreeCnt,
128 (nFinalTotalDlBufAllocCnt - nFinalTotalDlBufFreeCnt));
130 (" nUlBufAllocCnt[%5d] nUlBufFreeCnt[%5d] Diff[%5d]\n\n",
131 pWls->nTotalUlBufAllocCnt, pWls->nTotalUlBufFreeCnt,
132 (pWls->nTotalUlBufAllocCnt - pWls->nTotalUlBufFreeCnt));
135 //------------------------------------------------------------------------------
136 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
138 * @param[in] ptr Address to convert
140 * @return Converted address
143 * This function converts Virtual Address to Physical Address
146 //------------------------------------------------------------------------------
147 uint64_t nr5g_fapi_wls_va_to_pa(
151 return ((uint64_t) WLS_VA2PA(h_wls, ptr));
154 //------------------------------------------------------------------------------
155 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
157 * @param[in] ptr Address to convert
159 * @return Converted address
162 * This function converts Physical Address to Virtual Address
165 //------------------------------------------------------------------------------
166 void *nr5g_fapi_wls_pa_to_va(
170 return ((void *)WLS_PA2VA(h_wls, ptr));
173 //------------------------------------------------------------------------------
174 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
178 * @return Number of blocks added
181 * This function add WLS blocks to the L1 Array which will be used by L1 in
182 * every TTI to populate and send back APIs to the MAC
185 //------------------------------------------------------------------------------
186 uint8_t wls_fapi_add_blocks_to_ul(
190 p_nr5g_fapi_wls_context_t pWls = nr5g_fapi_wls_context();
191 WLS_HANDLE h_wls = pWls->h_wls[NR5G_FAPI2PHY_WLS_INST];
193 void *pMsg = wls_fapi_alloc_buffer(0, MIN_UL_BUF_LOCATIONS);
198 /* allocate blocks for UL transmittion */
199 while (WLS_EnqueueBlock(h_wls, nr5g_fapi_wls_va_to_pa(h_wls, pMsg)) > 0) {
201 pMsg = wls_fapi_alloc_buffer(0, MIN_UL_BUF_LOCATIONS);
206 // free not enqueued block
208 wls_fapi_free_buffer(pMsg, MIN_UL_BUF_LOCATIONS);
214 //------------------------------------------------------------------------------
215 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
217 * @param A pointer to the phy instance table.
219 * @return 0 if SUCCESS
221 * @description This function initializes WLS layer primitives and allocates
222 * memory needed to exchange APIs between FAPI and PHY.
224 //------------------------------------------------------------------------------
225 uint8_t nr5g_fapi_wls_init(
226 p_nr5g_fapi_cfg_t cfg)
228 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
229 const char *dev_name = "wls";
231 if (p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST] &&
232 p_wls_ctx->h_wls[NR5G_FAPI2MAC_WLS_INST]) {
233 // NR5G_FAPI_LOG(ERROR_LOG, ("WLS instance already opened!"));
237 p_wls_ctx->shmem_size = cfg->wls.shmem_size;
238 p_wls_ctx->h_wls[NR5G_FAPI2MAC_WLS_INST] =
239 WLS_Open_Dual(dev_name /*"wls"cfg->wls.device_name */ ,
241 cfg->wls.shmem_size, &p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST]);
242 if ((NULL == p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST]) &&
243 (NULL == p_wls_ctx->h_wls[NR5G_FAPI2MAC_WLS_INST])) {
244 // NR5G_FAPI_LOG(ERROR_LOG,("[NR5G_FAPI_ WLS] WLS instance connected."));
247 // Issue WLS_Alloc() for FAPI2MAC
248 p_wls_ctx->shmem = WLS_Alloc(p_wls_ctx->h_wls[NR5G_FAPI2MAC_WLS_INST],
249 p_wls_ctx->shmem_size);
251 if (NULL == p_wls_ctx->shmem) {
252 printf("Unable to alloc WLS Memory for FAPI2MAC\n");
256 p_wls_ctx->shmem = WLS_Alloc(p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST],
257 p_wls_ctx->shmem_size);
258 p_wls_ctx->pWlsMemBase = p_wls_ctx->shmem;
259 p_wls_ctx->nTotalMemorySize = p_wls_ctx->shmem_size;
260 if (NULL == p_wls_ctx->shmem) {
261 printf("Unable to alloc WLS Memory\n");
265 pthread_mutex_init((pthread_mutex_t *)
266 &p_wls_ctx->fapi2phy_lock_send, NULL);
267 pthread_mutex_init((pthread_mutex_t *)
268 &p_wls_ctx->fapi2phy_lock_alloc, NULL);
269 pthread_mutex_init((pthread_mutex_t *)
270 &p_wls_ctx->fapi2mac_lock_send, NULL);
271 pthread_mutex_init((pthread_mutex_t *)
272 &p_wls_ctx->fapi2mac_lock_alloc, NULL);
276 //-------------------------------------------------------------------------------------------
277 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
279 * @param[in] pMemArray Pointer to WLS Memory Management Structure
280 * @param[in] pMemArrayMmeory pointer to flat buffer that was allocated
281 * @param[in] totalSize total size of flat buffer allocated
282 * @param[in] nBlockSize Size of each block that needs to be partitoned by the memory manager
284 * @return 0 if SUCCESS
287 * This function creates memory blocks from a flat buffer which will be used for communication between FAPI and PHY
290 //-------------------------------------------------------------------------------------------
291 uint32_t wls_fapi_create_mem_array(
292 PWLS_FAPI_MEM_STRUCT pMemArray,
293 void *pMemArrayMemory,
298 int numBlocks = totalSize / nBlockSize;
303 ("wls_fapi_create_mem_array: pMemArray[%p] pMemArrayMemory[%p] totalSize[%d] nBlockSize[%d] numBlocks[%d]\n",
304 pMemArray, pMemArrayMemory, totalSize, nBlockSize, numBlocks);
306 // Can't be less than pointer size
307 if (nBlockSize < sizeof(void *)) {
310 // Can't be less than one block
311 if (totalSize < sizeof(void *)) {
315 pMemArray->ppFreeBlock = (void **)pMemArrayMemory;
316 pMemArray->pStorage = pMemArrayMemory;
317 pMemArray->pEndOfStorage =
318 ((unsigned long *)pMemArrayMemory) +
319 numBlocks * nBlockSize / sizeof(unsigned long);
320 pMemArray->nBlockSize = nBlockSize;
321 pMemArray->nBlockCount = numBlocks;
323 // Initialize single-linked list of free blocks;
324 ptr = (void **)pMemArrayMemory;
325 for (i = 0; i < pMemArray->nBlockCount; i++) {
326 #ifdef MEMORY_CORRUPTION_DETECT
327 // Fill with some pattern
328 uint8_t *p = (uint8_t *) ptr;
331 p += (nBlockSize - 16);
332 for (j = 0; j < 16; j++) {
333 p[j] = MEMORY_CORRUPTION_DETECT_FLAG;
337 if (i == pMemArray->nBlockCount - 1) {
338 *ptr = NULL; // End of list
340 // Points to the next block
341 *ptr = (void **)(((uint8_t *) ptr) + nBlockSize);
342 ptr += nBlockSize / sizeof(unsigned long);
346 NR5G_FAPI_MEMSET(alloc_track, sizeof(uint8_t) * ALLOC_TRACK_SIZE, 0,
347 sizeof(uint8_t) * ALLOC_TRACK_SIZE);
352 //-------------------------------------------------------------------------------------------
353 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
355 * @param[in] pWls Pointer to the nr5g_fapi_wls_ctx structure
357 * @return 0 if SUCCESS
360 * This function created a partition and blocks of WLS memory for API exchange between FAPI and PHY
363 //-------------------------------------------------------------------------------------------
364 int wls_fapi_create_partition(
365 p_nr5g_fapi_wls_context_t pWls)
367 #define WLS_HUGE_DEF_PAGE_SIZEA 0x40000000LL
368 static long hugePageSize = WLS_HUGE_DEF_PAGE_SIZEA;
369 // NR5G_FAPI_MEMSET(pWls->pWlsMemBase , 0xCC, pWls->nTotalMemorySize); // This is done by the Master Only
370 pWls->pPartitionMemBase =
371 (void *)(((uint8_t *) pWls->pWlsMemBase) + hugePageSize);
372 pWls->nPartitionMemSize = (pWls->nTotalMemorySize - hugePageSize);
374 pWls->nTotalBlocks = pWls->nPartitionMemSize / MSG_MAXSIZE;
375 return wls_fapi_create_mem_array(&pWls->sWlsStruct, pWls->pPartitionMemBase,
376 pWls->nPartitionMemSize, MSG_MAXSIZE);
379 //------------------------------------------------------------------------------
380 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
382 * @param[in] A pointer to the FAPI Memory Structure (Initialized by L2)
383 * @param[out] ppBlock Pointer where the allocated memory block is stored
385 * @return 0 if SUCCESS
387 * @description This function allocates a memory block from the pool
390 //------------------------------------------------------------------------------
391 uint32_t wls_fapi_alloc_mem_array(
392 PWLS_FAPI_MEM_STRUCT pMemArray,
397 if (pMemArray->ppFreeBlock == NULL) {
398 printf("wls_fapi_alloc_mem_array pMemArray->ppFreeBlock = NULL\n");
401 // FIXME: Remove after debugging
402 if (((void *)pMemArray->ppFreeBlock < pMemArray->pStorage) ||
403 ((void *)pMemArray->ppFreeBlock >= pMemArray->pEndOfStorage)) {
405 ("wls_fapi_alloc_mem_array ERROR: Corrupted MemArray;Arr=%p,Stor=%p,Free=%p\n",
406 pMemArray, pMemArray->pStorage, pMemArray->ppFreeBlock);
410 pMemArray->ppFreeBlock =
411 (void **)((unsigned long)pMemArray->ppFreeBlock & 0xFFFFFFFFFFFFFFF0);
412 *pMemArray->ppFreeBlock =
413 (void **)((unsigned long)*pMemArray->ppFreeBlock & 0xFFFFFFFFFFFFFFF0);
415 if ((*pMemArray->ppFreeBlock != NULL) &&
416 (((*pMemArray->ppFreeBlock) < pMemArray->pStorage) ||
417 ((*pMemArray->ppFreeBlock) >= pMemArray->pEndOfStorage))) {
419 "ERROR: Corrupted MemArray;Arr=%p,Stor=%p,Free=%p,Curr=%p\n",
420 pMemArray, pMemArray->pStorage, pMemArray->ppFreeBlock,
421 *pMemArray->ppFreeBlock);
425 *ppBlock = (void *)pMemArray->ppFreeBlock;
426 pMemArray->ppFreeBlock = (void **)(*pMemArray->ppFreeBlock);
429 (((uint64_t) * ppBlock -
430 (uint64_t) pMemArray->pStorage)) / pMemArray->nBlockSize;
431 if (alloc_track[idx]) {
433 ("wls_fapi_alloc_mem_array Double alloc Arr=%p,Stor=%p,Free=%p,Curr=%p\n",
434 pMemArray, pMemArray->pStorage, pMemArray->ppFreeBlock,
435 *pMemArray->ppFreeBlock);
438 #ifdef MEMORY_CORRUPTION_DETECT
439 uint32_t nBlockSize = pMemArray->nBlockSize, i;
440 uint8_t *p = (uint8_t *) * ppBlock;
442 p += (nBlockSize - 16);
443 for (i = 0; i < 16; i++) {
444 p[i] = MEMORY_CORRUPTION_DETECT_FLAG;
447 alloc_track[idx] = 1;
450 //printf("Block allocd [%p,%p]\n", pMemArray, *ppBlock);
455 //------------------------------------------------------------------------------
456 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
458 * @param[in] A pointer to the FAPI Memory Structure (Initialized by L2)
459 * @param[in] pBlock Pointer where the allocated memory block is stored
461 * @return 0 if SUCCESS
463 * @description This function frees a WLS block of memory and adds
464 * it back to the pool
467 //------------------------------------------------------------------------------
468 uint32_t wls_fapi_free_mem_array(
469 PWLS_FAPI_MEM_STRUCT pMemArray,
473 unsigned long mask = (((unsigned long)pMemArray->nBlockSize) - 1);
475 pBlock = (void *)((unsigned long)pBlock & ~mask);
477 if ((pBlock < pMemArray->pStorage) || (pBlock >= pMemArray->pEndOfStorage)) {
479 ("wls_fapi_free_mem_array WARNING: Trying to free foreign block;Arr=%p,Blk=%p pStorage [%p .. %p]\n",
480 pMemArray, pBlock, pMemArray->pStorage, pMemArray->pEndOfStorage);
485 (int)(((uint64_t) pBlock -
486 (uint64_t) pMemArray->pStorage)) / pMemArray->nBlockSize;
488 if (alloc_track[idx] == 0) {
490 ("wls_fapi_free_mem_array ERROR: Double free Arr=%p,Stor=%p,Free=%p,Curr=%p\n",
491 pMemArray, pMemArray->pStorage, pMemArray->ppFreeBlock, pBlock);
494 #ifdef MEMORY_CORRUPTION_DETECT
495 uint32_t nBlockSize = pMemArray->nBlockSize, i;
496 uint8_t *p = (uint8_t *) pBlock;
498 p += (nBlockSize - 16);
499 for (i = 0; i < 16; i++) {
500 if (p[i] != MEMORY_CORRUPTION_DETECT_FLAG) {
501 printf("ERROR: Corruption\n");
502 nr5g_fapi_wls_print_stats();
507 alloc_track[idx] = 0;
510 if (((void *)pMemArray->ppFreeBlock) == pBlock) {
511 // Simple protection against freeing of already freed block
514 // FIXME: Remove after debugging
515 if ((pMemArray->ppFreeBlock != NULL)
516 && (((void *)pMemArray->ppFreeBlock < pMemArray->pStorage)
517 || ((void *)pMemArray->ppFreeBlock >= pMemArray->pEndOfStorage))) {
519 ("wls_fapi_free_mem_array ERROR: Corrupted MemArray;Arr=%p,Stor=%p,Free=%p\n",
520 pMemArray, pMemArray->pStorage, pMemArray->ppFreeBlock);
523 // FIXME: Remove after debugging
524 if ((pBlock < pMemArray->pStorage) || (pBlock >= pMemArray->pEndOfStorage)) {
525 printf("wls_fapi_free_mem_array ERROR: Invalid block;Arr=%p,Blk=%p\n",
531 (void **)((unsigned long)pMemArray->ppFreeBlock & 0xFFFFFFFFFFFFFFF0);
532 pMemArray->ppFreeBlock =
533 (void **)((unsigned long)pBlock & 0xFFFFFFFFFFFFFFF0);
535 //printf("Block freed [%p,%p]\n", pMemArray, pBlock);
540 //------------------------------------------------------------------------------
541 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
543 * @param size (if 0 fixed size from pool)
544 * @param Number of locations
546 * @return 0 if SUCCESS
548 * @description This function initializes WLS layer primitives and allocates
549 * memory needed to exchange APIs between FAPI and PHY.
551 //------------------------------------------------------------------------------
552 void *wls_fapi_alloc_buffer(
557 p_nr5g_fapi_wls_context_t pWls = nr5g_fapi_wls_context();
559 if (pthread_mutex_lock((pthread_mutex_t *) & pWls->fapi2phy_lock_alloc)) {
560 NR5G_FAPI_LOG(ERROR_LOG, ("unable to get lock alloc pthread mutex"));
564 if (wls_fapi_alloc_mem_array(&pWls->sWlsStruct, &pBlock) != SUCCESS) {
565 printf("wls_fapi_alloc_buffer alloc error size[%d] loc[%d]\n", size,
567 nr5g_fapi_wls_print_stats();
570 pWls->nAllocBlocks++;
573 //printf("----------------wls_fapi_alloc_buffer: size[%d] loc[%d] buf[%p] nAllocBlocks[%d]\n", size, loc, pBlock, pWls->nAllocBlocks);
575 //printf("[%p]\n", pBlock);
577 pWls->nTotalAllocCnt++;
578 if (loc < MAX_DL_BUF_LOCATIONS)
579 pWls->nTotalDlBufAllocCnt[loc]++;
580 else if (loc < MAX_UL_BUF_LOCATIONS)
581 pWls->nTotalUlBufAllocCnt++;
583 if (pthread_mutex_unlock((pthread_mutex_t *) & pWls->fapi2phy_lock_alloc)) {
584 NR5G_FAPI_LOG(ERROR_LOG, ("unable to unlock alloc pthread mutex"));
591 //------------------------------------------------------------------------------
592 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
594 * @param[in] *pMsg Pointer to free
598 * @descriptioni This function frees a block of memory and adds it back to
602 //------------------------------------------------------------------------------
603 void wls_fapi_free_buffer(
607 p_nr5g_fapi_wls_context_t pWls = nr5g_fapi_wls_context();
609 if (pthread_mutex_lock((pthread_mutex_t *) & pWls->fapi2phy_lock_alloc)) {
610 NR5G_FAPI_LOG(ERROR_LOG, ("unable to lock alloc pthread mutex"));
613 //printf("----------------wls_fapi_free_buffer: buf[%p] loc[%d]\n", pMsg, loc);
614 if (wls_fapi_free_mem_array(&pWls->sWlsStruct, (void *)pMsg) == SUCCESS) {
615 pWls->nAllocBlocks--;
617 printf("wls_fapi_free_buffer Free error\n");
618 nr5g_fapi_wls_print_stats();
622 pWls->nTotalFreeCnt++;
623 if (loc < MAX_DL_BUF_LOCATIONS)
624 pWls->nTotalDlBufFreeCnt[loc]++;
625 else if (loc < MAX_UL_BUF_LOCATIONS)
626 pWls->nTotalUlBufFreeCnt++;
628 if (pthread_mutex_unlock((pthread_mutex_t *) & pWls->fapi2phy_lock_alloc)) {
629 NR5G_FAPI_LOG(ERROR_LOG, ("unable to unlock alloc pthread mutex"));
634 //------------------------------------------------------------------------------
635 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
637 * @param A pointer to a wls instance
639 * @return 0 if SUCCESS
641 * @description This function initializes the WLS layer FAPI2PHY interface
642 * primitives and allocates memory needed to exchange APIs
643 * between FAPI and PHY.
645 //------------------------------------------------------------------------------
646 uint8_t nr5g_fapi2Phy_wls_init(
647 p_nr5g_fapi_wls_context_t pwls)
650 uint8_t retval = SUCCESS;
652 retval = wls_fapi_create_partition(pwls);
653 if ((nBlocks = wls_fapi_add_blocks_to_ul()) == 0) {
660 uint8_t get_stats_location(
665 case MSG_TYPE_PHY_CONFIG_REQ:
666 loc = MEM_STAT_CONFIG_REQ;
668 case MSG_TYPE_PHY_START_REQ:
669 loc = MEM_STAT_START_REQ;
671 case MSG_TYPE_PHY_STOP_REQ:
672 loc = MEM_STAT_STOP_REQ;
674 case MSG_TYPE_PHY_SHUTDOWN_REQ:
675 loc = MEM_STAT_SHUTDOWN_REQ;
677 case MSG_TYPE_PHY_DL_CONFIG_REQ:
678 loc = MEM_STAT_DL_CONFIG_REQ;
680 case MSG_TYPE_PHY_UL_CONFIG_REQ:
681 loc = MEM_STAT_UL_CONFIG_REQ;
683 case MSG_TYPE_PHY_UL_DCI_REQ:
684 loc = MEM_STAT_UL_DCI_REQ;
686 case MSG_TYPE_PHY_TX_REQ:
687 loc = MEM_STAT_TX_REQ;
689 case MSG_TYPE_PHY_DL_IQ_SAMPLES:
690 loc = MEM_STAT_DL_IQ_SAMPLES;
692 case MSG_TYPE_PHY_UL_IQ_SAMPLES:
693 loc = MEM_STAT_UL_IQ_SAMPLES;
696 loc = MEM_STAT_DEFAULT;
702 //------------------------------------------------------------------------------
703 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
705 * @param[in] pListElem Pointer to List element header
706 * @param[in] idx Subframe Number
708 * @return Number of blocks freed
710 * @description This function Frees all the blocks in a List Element Linked
711 * List coming from L1 by storing them into an array to be
712 * freed at a later point in time.
714 //------------------------------------------------------------------------------
715 void wls_fapi_add_recv_apis_to_free(
716 PMAC2PHY_QUEUE_EL pListElem,
719 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
720 L1L2MessageHdr *p_msg_header = NULL;
721 PRXULSCHIndicationStruct p_phy_rx_ulsch_ind = NULL;
726 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
727 h_wls = p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST];
729 count = g_to_free_recv_list_cnt[idx];
730 pNextMsg = pListElem;
732 if (count >= TOTAL_FREE_BLOCKS) {
733 NR5G_FAPI_LOG(ERROR_LOG, ("%s: Reached max capacity of free list.\n"
734 "\t\t\t\tlist index: %d list count: %d max list count: %d",
735 __func__, idx, count, TOTAL_FREE_BLOCKS));
739 g_to_free_recv_list[idx][count++] = (uint64_t) pNextMsg;
740 p_msg_header = (PL1L2MessageHdr) (pNextMsg + 1);
741 if (p_msg_header->nMessageType == MSG_TYPE_PHY_RX_ULSCH_IND) {
742 p_phy_rx_ulsch_ind = (PRXULSCHIndicationStruct) p_msg_header;
743 for (i = 0; i < p_phy_rx_ulsch_ind->nUlsch; i++) {
744 ptr = p_phy_rx_ulsch_ind->sULSCHPDUDataStruct[i].pPayload;
745 ptr = (uint8_t *) nr5g_fapi_wls_pa_to_va(h_wls, (uint64_t) ptr);
748 g_to_free_recv_list[idx][count++] = (uint64_t) ptr;
752 pNextMsg = pNextMsg->pNext;
755 g_to_free_recv_list[idx][count] = 0L;
756 g_to_free_recv_list_cnt[idx] = count;
758 NR5G_FAPI_LOG(DEBUG_LOG, ("To Free %d\n", count));
761 //------------------------------------------------------------------------------
762 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
764 * @param[in] idx subframe Number
766 * @return Number of blocks freed
768 * @description This function frees all blocks that have been added to the
771 //------------------------------------------------------------------------------
772 void wls_fapi_free_recv_free_list(
775 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
778 if (idx >= TO_FREE_SIZE) {
779 NR5G_FAPI_LOG(ERROR_LOG, ("%s: list index: %d\n", __func__, idx));
783 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_recv_list[idx][count];
785 wls_fapi_free_buffer(pNextMsg, MIN_UL_BUF_LOCATIONS);
786 g_to_free_recv_list[idx][count++] = 0L;
787 if (g_to_free_recv_list[idx][count])
788 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_recv_list[idx][count];
793 NR5G_FAPI_LOG(DEBUG_LOG, ("Free %d\n", count));
794 g_to_free_recv_list_cnt[idx] = 0;
799 //------------------------------------------------------------------------------
800 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
802 * @param[in] pListElem Pointer to List element header
803 * @param[in] idx Subframe Number
805 * @return Number of blocks freed
807 * @description This function Frees all the blocks in a List Element Linked
808 * List coming from L1 by storing them into an array to be
809 * freed at a later point in time.
811 //------------------------------------------------------------------------------
812 void wls_fapi_add_send_apis_to_free(
813 PMAC2PHY_QUEUE_EL pListElem,
816 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
817 L1L2MessageHdr *p_msg_header = NULL;
818 PRXULSCHIndicationStruct p_phy_rx_ulsch_ind = NULL;
822 count = g_to_free_send_list_cnt[idx];
823 pNextMsg = pListElem;
825 if (count >= TOTAL_FREE_BLOCKS) {
826 NR5G_FAPI_LOG(ERROR_LOG, ("%s: Reached max capacity of free list.\n"
827 "\t\t\t\tlist index: %d list count: %d max list count: %d",
828 __func__, idx, count, TOTAL_FREE_BLOCKS));
832 g_to_free_send_list[idx][count++] = (uint64_t) pNextMsg;
833 p_msg_header = (PL1L2MessageHdr) (pNextMsg + 1);
834 if (p_msg_header->nMessageType == MSG_TYPE_PHY_RX_ULSCH_IND) {
835 p_phy_rx_ulsch_ind = (PRXULSCHIndicationStruct) p_msg_header;
836 for (i = 0; i < p_phy_rx_ulsch_ind->nUlsch; i++) {
837 ptr = p_phy_rx_ulsch_ind->sULSCHPDUDataStruct[i].pPayload;
839 g_to_free_send_list[idx][count++] = (uint64_t) ptr;
843 pNextMsg = pNextMsg->pNext;
846 g_to_free_send_list[idx][count] = 0L;
847 g_to_free_send_list_cnt[idx] = count;
849 NR5G_FAPI_LOG(DEBUG_LOG, ("To Free %d\n", count));
852 //------------------------------------------------------------------------------
853 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
855 * @param[in] idx subframe Number
857 * @return Number of blocks freed
859 * @description This function frees all blocks that have been added to the
862 //------------------------------------------------------------------------------
863 void wls_fapi_free_send_free_list(
866 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
867 L1L2MessageHdr *p_msg_header = NULL;
868 int count = 0, loc = 0;
870 if (idx >= TO_FREE_SIZE) {
871 NR5G_FAPI_LOG(ERROR_LOG, ("%s: list index: %d\n", __func__, idx));
875 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list[idx][count];
877 p_msg_header = (PL1L2MessageHdr) (pNextMsg + 1);
878 loc = get_stats_location(p_msg_header->nMessageType);
879 wls_fapi_free_buffer(pNextMsg, loc);
880 g_to_free_send_list[idx][count++] = 0L;
881 if (g_to_free_send_list[idx][count])
882 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list[idx][count];
887 NR5G_FAPI_LOG(DEBUG_LOG, ("Free %d\n", count));
888 g_to_free_send_list_cnt[idx] = 0;
893 //------------------------------------------------------------------------------
894 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
896 * @param[in] idx subframe Number
898 * @return Number of blocks freed
900 * @description This function frees all blocks that have been added to the
903 //------------------------------------------------------------------------------
904 void wls_fapi_free_list_all(
909 for (idx = 0; idx < TO_FREE_SIZE; idx++) {
910 wls_fapi_free_send_free_list(idx);
911 wls_fapi_free_recv_free_list(idx);
914 nr5g_fapi_wls_print_stats();