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_fapi2phy_group
24 #include "nr5g_fapi_std.h"
25 #include "nr5g_fapi_common_types.h"
26 #include "nr5g_fapi_internal.h"
27 #include "nr5g_fapi_wls.h"
28 #include "nr5g_fapi_fapi2phy_wls.h"
29 #include "nr5g_fapi_log.h"
30 #include "nr5g_fapi_urllc_thread.h"
32 static uint32_t g_to_free_send_list_cnt[TO_FREE_SIZE] = { 0 };
33 static uint64_t g_to_free_send_list[TO_FREE_SIZE][TOTAL_FREE_BLOCKS] = { {0L} };
34 static uint32_t g_to_free_recv_list_cnt[TO_FREE_SIZE] = { 0 };
35 static uint64_t g_to_free_recv_list[TO_FREE_SIZE][TOTAL_FREE_BLOCKS] = { {0L} };
37 static uint32_t g_to_free_send_list_cnt_urllc[TO_FREE_SIZE_URLLC] = { 0 };
38 static uint64_t g_to_free_send_list_urllc[TO_FREE_SIZE_URLLC][TOTAL_FREE_BLOCKS] = { {0L} };
40 //------------------------------------------------------------------------------
41 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
43 * @param data Pointer to validate
45 * @return TRUE If pointer is within valid shared WLS memory region
46 * FALSE If pointer is out of valid shared WLS memory region
49 * This function validates pointer's in WLS shared memory region
52 //------------------------------------------------------------------------------
53 uint8_t nr5g_fapi_fapi2phy_is_valid_wls_ptr(
56 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
57 if ((unsigned long)data >= (unsigned long)p_wls_ctx->pPartitionMemBase &&
58 (unsigned long)data < ((unsigned long)p_wls_ctx->pPartitionMemBase +
59 p_wls_ctx->nPartitionMemSize)) {
66 //------------------------------------------------------------------------------
67 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
71 * @return A pointer to WLS_HANDLE stucture
74 * This function returns the WLS instance
77 //------------------------------------------------------------------------------
78 static inline WLS_HANDLE nr5g_fapi_fapi2phy_wls_instance(
81 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
82 return p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST];
85 //----------------------------------------------------------------------------------
86 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
88 * @param[out] data Location where First API from L1 is stored
90 * @return Size of Message sent from L1
93 * This function queries the APIs sent from L1 to L2 and gets the first pointer
97 //----------------------------------------------------------------------------------
98 inline uint64_t *nr5g_fapi_fapi2phy_wls_get(
103 uint64_t *data = NULL;
106 uint16_t mt = 0, f = 0;
108 h_wls = nr5g_fapi_fapi2phy_wls_instance();
109 data = (uint64_t *) WLS_Get(h_wls, &ms, &mt, &f);
110 *msg_size = ms, *msg_type = mt, *flags = f;
111 NR5G_FAPI_LOG(TRACE_LOG, ("[FAPI2PHY WLS][GET] %p size: %d "
112 "type: %x flags: %x", data, *msg_size, *msg_type, *flags));
117 //----------------------------------------------------------------------------------
118 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
120 * @param[in] p_msg Pointer to API block that needs to be sent to L1
121 * @param[in] msg_size Size of Message
122 * @param[in] msg_id Message Id
123 * @param[in] flags Special flags needed for WLS
125 * @return 0 if SUCCESS
128 * This function adds a block of API from L2 to L1 which will be sent later
131 //----------------------------------------------------------------------------------
132 inline uint8_t nr5g_fapi_fapi2phy_wls_put(
139 WLS_HANDLE h_phy_wls = nr5g_fapi_fapi2phy_wls_instance();
140 uint64_t pa = nr5g_fapi_wls_va_to_pa(h_phy_wls, (void *)p_msg);
141 NR5G_FAPI_LOG(TRACE_LOG, ("[FAPI2PHY WLS][PUT] %ld size: %d "
142 "type: %x flags: %x", pa, msg_size, msg_type, flags));
143 ret = WLS_Put(h_phy_wls, pa, msg_size, msg_type, flags);
148 //----------------------------------------------------------------------------------
149 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
153 * @return Number of blocks of APIs received
156 * This functions waits in a infinite loop for L1 to send a list of APIs to MAC. This is called
157 * during runtime when L2 sends a API to L1 and then waits for response back.
160 //----------------------------------------------------------------------------------
161 inline uint32_t nr5g_fapi_fapi2phy_wls_wait(
165 // NR5G_FAPI_LOG(TRACE_LOG, ("Waiting for L1 to respond in WLS Wait"));
166 ret = WLS_Wait(nr5g_fapi_fapi2phy_wls_instance());
170 //------------------------------------------------------------------------------
171 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
173 * @param[out] data Location where First API from L1 is stored
175 * @return Size of Message sent from L1
178 * This function checks if this is the last message in this tti.
181 //------------------------------------------------------------------------------
182 static inline uint8_t is_msg_present(
185 return (!((flags & WLS_TF_FIN) || (flags == 0)));
188 //----------------------------------------------------------------------------------
189 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
191 * @param[out] data Location where First API from L1 is stored
193 * @return Size of Message sent from L1
196 * This function queries the APIs sent from L1 to L2 and gets the first pointer
200 //----------------------------------------------------------------------------------
201 PMAC2PHY_QUEUE_EL nr5g_fapi_fapi2phy_wls_recv(
204 uint16_t msg_type = 0;
206 uint32_t msg_size = 0;
207 uint32_t num_elms = 0;
208 uint64_t *p_msg = NULL;
209 static uint32_t g_free_recv_idx = 0;
210 PMAC2PHY_QUEUE_EL p_qelm_list = NULL, p_urllc_qelm_list = NULL;
211 PMAC2PHY_QUEUE_EL p_qelm = NULL;
212 PMAC2PHY_QUEUE_EL p_tail_qelm = NULL, p_urllc_tail_qelm = NULL;
213 uint64_t start_tick = 0;
215 num_elms = nr5g_fapi_fapi2phy_wls_wait();
219 start_tick = __rdtsc();
222 p_msg = nr5g_fapi_fapi2phy_wls_get(&msg_size, &msg_type, &flags);
224 WLS_HANDLE h_wls = nr5g_fapi_fapi2phy_wls_instance();
225 p_qelm = (PMAC2PHY_QUEUE_EL)
226 nr5g_fapi_wls_pa_to_va(h_wls, (uint64_t) p_msg);
227 if (nr5g_fapi_fapi2phy_is_valid_wls_ptr(p_qelm) == FALSE) {
228 printf("Error: Invalid Ptr\n");
231 p_qelm->pNext = NULL;
233 if (flags & WLS_TF_URLLC)
235 if (p_urllc_qelm_list) {
236 p_urllc_tail_qelm->pNext = p_qelm;
237 p_urllc_tail_qelm = p_qelm;
239 p_urllc_qelm_list = p_qelm;
240 p_urllc_tail_qelm = p_qelm;
244 p_tail_qelm->pNext = p_qelm;
245 p_tail_qelm = p_qelm;
247 p_qelm_list = p_qelm;
248 p_tail_qelm = p_qelm;
254 } while (num_elms && is_msg_present(flags));
256 if (p_urllc_qelm_list) {
257 wls_fapi_add_recv_apis_to_free(p_urllc_qelm_list, g_free_recv_idx);
259 if (g_free_recv_idx >= TO_FREE_SIZE) {
262 // Free 10 TTIs Later
263 wls_fapi_free_recv_free_list(g_free_recv_idx);
265 wls_fapi_add_blocks_to_ul();
266 nr5g_fapi_urllc_thread_callback(NR5G_FAPI_URLLC_MSG_DIR_PHY2MAC, (void *) p_urllc_qelm_list);
270 wls_fapi_add_recv_apis_to_free(p_qelm_list, g_free_recv_idx);
272 if (g_free_recv_idx >= TO_FREE_SIZE) {
275 // Free 10 TTIs Later
276 wls_fapi_free_recv_free_list(g_free_recv_idx);
278 wls_fapi_add_blocks_to_ul();
280 tick_total_wls_get_per_tti_ul += __rdtsc() - start_tick;
285 //------------------------------------------------------------------------------
286 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
288 * @param[in] p_msg_header Pointer to the TxSDuReq Message block
289 * @param[out] n_zbc_blocks Number of ZBC blocks
291 * @return 1 if this block is a TxSduReq message. 0 else.
294 * This function checks if a block is a TxSduReq messages and counts the number
295 * of ZBC blocks in this API
298 //------------------------------------------------------------------------------
299 int nr5g_fapi_fapi2phy_is_sdu_zbc_block(
303 PL1L2MessageHdr p_msg_header = (PL1L2MessageHdr) p_msg;
306 if (p_msg_header->nMessageType == MSG_TYPE_PHY_TX_REQ) {
307 PTXRequestStruct p_dl_sdu_req = (PTXRequestStruct) p_msg_header;
308 PDLPDUDataStruct p_dl_pdu_data = (PDLPDUDataStruct) (p_dl_sdu_req + 1);
310 for (i = 0; i < p_dl_sdu_req->nPDU; i++) {
311 *num_zbc_blocks += (p_dl_pdu_data->nPduLen1 ? 1 : 0);
312 *num_zbc_blocks += (p_dl_pdu_data->nPduLen2 ? 1 : 0);
316 if (*num_zbc_blocks) {
324 //----------------------------------------------------------------------------------
325 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
327 * @param[in] p_msg_header Pointer to the TxSduReq Message block
328 * @param[in] flags Special flags needed for WLS
329 * @param[in] n_zbc_blocks Number of ZBC blocks in list
331 * @return 0 if SUCCESS
334 * This function adds all the ZBC blocks in a TXSDU Message and prepares them to
338 //------------------------------------------------------------------------------
339 uint32_t nr5g_fapi_fapi2phy_send_zbc_blocks(
343 PL1L2MessageHdr p_msg_header = (PL1L2MessageHdr) p_msg;
344 PTXRequestStruct p_dl_sdu_req = (PTXRequestStruct) p_msg_header;
345 PDLPDUDataStruct p_dl_pdu_data = (PDLPDUDataStruct) (p_dl_sdu_req + 1);
346 uint32_t i, j, is_last, is_last1, msg_type;
347 uint16_t list_flags = flags;
348 uint16_t flags_urllc = (flags & WLS_TF_URLLC) ? WLS_TF_URLLC : 0;
350 for (i = 0; i < p_dl_sdu_req->nPDU; i++) {
351 is_last = (i == (p_dl_sdu_req->nPDU - 1));
352 for (j = 0; j < MAX_DL_PER_UE_CODEWORD_NUM; j++) {
358 pdu_len = p_dl_pdu_data->nPduLen1;
359 p_payload = p_dl_pdu_data->pPayload1;
360 msg_type = MSG_PHY_ZBC_BLOCK0_REQ;
362 pdu_len = p_dl_pdu_data->nPduLen2;
363 p_payload = p_dl_pdu_data->pPayload2;
364 msg_type = MSG_PHY_ZBC_BLOCK1_REQ;
368 is_last1 = (((j == 0) && (p_dl_pdu_data->pPayload2 == 0)) ||
369 (j == (MAX_DL_PER_UE_CODEWORD_NUM - 1)));
370 if ((list_flags & WLS_TF_FIN) && is_last && is_last1) {
371 flags = WLS_SG_LAST | flags_urllc;
373 flags = WLS_SG_NEXT | flags_urllc;
376 WLS_HANDLE h_phy_wls = nr5g_fapi_fapi2phy_wls_instance();
377 if (WLS_Put(h_phy_wls, (uint64_t) p_payload, pdu_len, msg_type,
379 printf("Error ZBC block 0x%016lx\n", (uint64_t) p_payload);
390 //------------------------------------------------------------------------------
391 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
393 * @param[in] A pointer to the phy instance
394 * @param[in] A data Pointer to the Linked list header
396 * @return 0 if SUCCESS
398 * @description This function sends a list of APIs to the L1 via WLS
401 //------------------------------------------------------------------------------
402 uint8_t nr5g_fapi_fapi2phy_wls_send(
406 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
407 PMAC2PHY_QUEUE_EL p_curr_msg = NULL;
408 PL1L2MessageHdr p_msg_header;
410 uint16_t flags_urllc = (is_urllc ? WLS_TF_URLLC : 0);
411 uint8_t ret = SUCCESS;
412 int n_zbc_blocks = 0, is_zbc = 0, count = 0;
413 static uint32_t g_free_send_idx = 0;
414 static uint32_t g_free_send_idx_urllc = 0;
416 p_curr_msg = (PMAC2PHY_QUEUE_EL) data;
417 is_urllc ? wls_fapi_add_send_apis_to_free_urllc(p_curr_msg, g_free_send_idx_urllc)
418 : wls_fapi_add_send_apis_to_free(p_curr_msg, g_free_send_idx);
420 if (pthread_mutex_lock((pthread_mutex_t *) & p_wls_ctx->fapi2phy_lock_send)) {
421 NR5G_FAPI_LOG(ERROR_LOG, ("unable to lock send pthread mutex"));
425 if (p_curr_msg->pNext) {
426 flags = WLS_SG_FIRST | flags_urllc;
430 p_msg_header = (PL1L2MessageHdr) (p_curr_msg + 1);
431 if (p_curr_msg->pNext) { // FIRST/NEXT list element
432 if (SUCCESS != nr5g_fapi_fapi2phy_wls_put((uint64_t) p_curr_msg,
433 p_curr_msg->nMessageLen + sizeof(MAC2PHY_QUEUE_EL),
434 p_msg_header->nMessageType, flags)) {
435 if (pthread_mutex_unlock((pthread_mutex_t *) &
436 p_wls_ctx->fapi2phy_lock_send)) {
437 NR5G_FAPI_LOG(ERROR_LOG,
438 ("unable to unlock send pthread mutex"));
443 if (nr5g_fapi_fapi2phy_is_sdu_zbc_block(p_msg_header, &n_zbc_blocks)) { // ZBC blocks
444 if (nr5g_fapi_fapi2phy_send_zbc_blocks(p_msg_header,
446 if (pthread_mutex_unlock((pthread_mutex_t *) &
447 p_wls_ctx->fapi2phy_lock_send)) {
448 NR5G_FAPI_LOG(ERROR_LOG,
449 ("unable to unlock send pthread mutex"));
454 p_curr_msg = p_curr_msg->pNext;
455 } else { /* p_curr_msg->Next */
457 flags = WLS_SG_LAST | flags_urllc;
459 if (nr5g_fapi_fapi2phy_is_sdu_zbc_block(p_msg_header,
461 flags = WLS_SG_NEXT | flags_urllc;
464 if (nr5g_fapi_fapi2phy_wls_put((uint64_t) p_curr_msg,
465 p_curr_msg->nMessageLen + sizeof(MAC2PHY_QUEUE_EL),
466 p_msg_header->nMessageType, flags) != SUCCESS) {
468 if (pthread_mutex_unlock((pthread_mutex_t *) &
469 p_wls_ctx->fapi2phy_lock_send)) {
470 NR5G_FAPI_LOG(ERROR_LOG,
471 ("unable to unlock send pthread mutex"));
476 if (is_zbc) { // ZBC blocks
477 if (nr5g_fapi_fapi2phy_send_zbc_blocks(p_msg_header,
478 WLS_SG_LAST | flags_urllc) != SUCCESS) {
480 if (pthread_mutex_unlock((pthread_mutex_t *) &
481 p_wls_ctx->fapi2phy_lock_send)) {
482 NR5G_FAPI_LOG(ERROR_LOG,
483 ("unable to unlock send pthread mutex"));
489 } /* p_curr_msg->Next */
490 flags = WLS_SG_NEXT | flags_urllc;
492 } else { // one block
494 if (nr5g_fapi_fapi2phy_is_sdu_zbc_block(p_curr_msg, &n_zbc_blocks)) {
495 printf("Error ZBC block cannot be only one in the list\n");
496 if (pthread_mutex_unlock((pthread_mutex_t *) &
497 p_wls_ctx->fapi2phy_lock_send)) {
498 NR5G_FAPI_LOG(ERROR_LOG,
499 ("unable to unlock send pthread mutex"));
504 if (SUCCESS != nr5g_fapi_fapi2phy_wls_put((uint64_t) p_curr_msg,
505 p_curr_msg->nMessageLen + sizeof(MAC2PHY_QUEUE_EL),
506 p_curr_msg->nMessageType, flags)) {
508 if (pthread_mutex_unlock((pthread_mutex_t *) &
509 p_wls_ctx->fapi2phy_lock_send)) {
510 NR5G_FAPI_LOG(ERROR_LOG,
511 ("unable to unlock send pthread mutex"));
519 g_free_send_idx_urllc++;
520 if (g_free_send_idx_urllc >= TO_FREE_SIZE_URLLC)
521 g_free_send_idx_urllc = 0;
524 if (g_free_send_idx >= TO_FREE_SIZE)
528 // Free some TTIs Later
529 is_urllc ? wls_fapi_free_send_free_list_urllc(g_free_send_idx_urllc)
530 : wls_fapi_free_send_free_list(g_free_send_idx);
533 if (pthread_mutex_unlock((pthread_mutex_t *) &
534 p_wls_ctx->fapi2phy_lock_send)) {
535 NR5G_FAPI_LOG(ERROR_LOG, ("unable to unlock send pthread mutex"));
541 //------------------------------------------------------------------------------
542 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
544 * @param[in] pListElem Pointer to List element header
545 * @param[in] idx Subframe Number
547 * @return Number of blocks freed
549 * @description This function Frees all the blocks in a List Element Linked
550 * List coming from L1 by storing them into an array to be
551 * freed at a later point in time.
553 //------------------------------------------------------------------------------
554 uint8_t get_stats_location(
559 case MSG_TYPE_PHY_CONFIG_REQ:
560 loc = MEM_STAT_CONFIG_REQ;
562 case MSG_TYPE_PHY_START_REQ:
563 loc = MEM_STAT_START_REQ;
565 case MSG_TYPE_PHY_STOP_REQ:
566 loc = MEM_STAT_STOP_REQ;
568 case MSG_TYPE_PHY_SHUTDOWN_REQ:
569 loc = MEM_STAT_SHUTDOWN_REQ;
571 case MSG_TYPE_PHY_DL_CONFIG_REQ:
572 loc = MEM_STAT_DL_CONFIG_REQ;
574 case MSG_TYPE_PHY_UL_CONFIG_REQ:
575 loc = MEM_STAT_UL_CONFIG_REQ;
577 case MSG_TYPE_PHY_UL_DCI_REQ:
578 loc = MEM_STAT_UL_DCI_REQ;
580 case MSG_TYPE_PHY_TX_REQ:
581 loc = MEM_STAT_TX_REQ;
583 case MSG_TYPE_PHY_DL_IQ_SAMPLES:
584 loc = MEM_STAT_DL_IQ_SAMPLES;
586 case MSG_TYPE_PHY_UL_IQ_SAMPLES:
587 loc = MEM_STAT_UL_IQ_SAMPLES;
590 loc = MEM_STAT_DEFAULT;
596 //------------------------------------------------------------------------------
597 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
599 * @param[in] pListElem Pointer to List element header
600 * @param[in] idx Subframe Number
602 * @return Number of blocks freed
604 * @description This function Frees all the blocks in a List Element Linked
605 * List coming from L1 by storing them into an array to be
606 * freed at a later point in time.
608 //------------------------------------------------------------------------------
609 void wls_fapi_add_recv_apis_to_free(
610 PMAC2PHY_QUEUE_EL pListElem,
613 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
614 L1L2MessageHdr *p_msg_header = NULL;
615 PRXULSCHIndicationStruct p_phy_rx_ulsch_ind = NULL;
616 PULSCHPDUDataStruct p_ulsch_pdu = NULL;
622 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
623 h_wls = p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST];
625 count = g_to_free_recv_list_cnt[idx];
626 pNextMsg = pListElem;
628 if (count >= TOTAL_FREE_BLOCKS) {
629 NR5G_FAPI_LOG(ERROR_LOG, ("%s: Reached max capacity of free list.\n"
630 "\t\t\t\tlist index: %d list count: %d max list count: %d",
631 __func__, idx, count, TOTAL_FREE_BLOCKS));
635 g_to_free_recv_list[idx][count++] = (uint64_t) pNextMsg;
636 p_msg_header = (PL1L2MessageHdr) (pNextMsg + 1);
637 if (p_msg_header->nMessageType == MSG_TYPE_PHY_RX_ULSCH_IND) {
638 p_phy_rx_ulsch_ind = (PRXULSCHIndicationStruct) p_msg_header;
639 for (i = 0u; i < p_phy_rx_ulsch_ind->nUlsch; i++) {
640 p_ulsch_pdu = &(p_phy_rx_ulsch_ind->sULSCHPDUDataStruct[i]);
641 if(p_ulsch_pdu->nPduLen > 0) {
642 ptr = (uint8_t *) nr5g_fapi_wls_pa_to_va(h_wls,
643 (uint64_t) p_ulsch_pdu->pPayload);
646 g_to_free_recv_list[idx][count++] = (uint64_t) ptr;
649 NR5G_FAPI_LOG(DEBUG_LOG, ("%s: Payload for"
650 "MSG_TYPE_PHY_RX_ULSCH_IND ulsch pdu (%u/%u) is NULL."
651 "Skip adding to free list.",
652 __func__, i, p_phy_rx_ulsch_ind->nUlsch));
656 pNextMsg = pNextMsg->pNext;
659 g_to_free_recv_list[idx][count] = 0L;
660 g_to_free_recv_list_cnt[idx] = count;
662 NR5G_FAPI_LOG(DEBUG_LOG, ("To Free %d\n", count));
665 //------------------------------------------------------------------------------
666 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
668 * @param[in] idx subframe Number
670 * @return Number of blocks freed
672 * @description This function frees all blocks that have been added to the
675 //------------------------------------------------------------------------------
676 void wls_fapi_free_recv_free_list(
679 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
682 if (idx >= TO_FREE_SIZE) {
683 NR5G_FAPI_LOG(ERROR_LOG, ("%s: list index: %d\n", __func__, idx));
687 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_recv_list[idx][count];
689 wls_fapi_free_buffer(pNextMsg, MIN_UL_BUF_LOCATIONS);
690 g_to_free_recv_list[idx][count++] = 0L;
691 if (g_to_free_recv_list[idx][count])
692 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_recv_list[idx][count];
697 NR5G_FAPI_LOG(DEBUG_LOG, ("Free %d\n", count));
698 g_to_free_recv_list_cnt[idx] = 0;
703 //------------------------------------------------------------------------------
704 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
706 * @param[in] pListElem Pointer to List element header
707 * @param[in] idx Subframe Number
709 * @return Number of blocks freed
711 * @description This function Frees all the blocks in a List Element Linked
712 * List coming from L1 by storing them into an array to be
713 * freed at a later point in time.
715 //------------------------------------------------------------------------------
716 void wls_fapi_add_send_apis_to_free(
717 PMAC2PHY_QUEUE_EL pListElem,
720 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
723 count = g_to_free_send_list_cnt[idx];
724 pNextMsg = pListElem;
726 if (count >= TOTAL_FREE_BLOCKS) {
727 NR5G_FAPI_LOG(ERROR_LOG, ("%s: Reached max capacity of free list.\n"
728 "\t\t\t\tlist index: %d list count: %d max list count: %d",
729 __func__, idx, count, TOTAL_FREE_BLOCKS));
733 g_to_free_send_list[idx][count++] = (uint64_t) pNextMsg;
734 pNextMsg = pNextMsg->pNext;
737 g_to_free_send_list[idx][count] = 0L;
738 g_to_free_send_list_cnt[idx] = count;
740 NR5G_FAPI_LOG(DEBUG_LOG, ("To Free %d\n", count));
743 //------------------------------------------------------------------------------
744 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
746 * @param[in] idx subframe Number
748 * @return Number of blocks freed
750 * @description This function frees all blocks that have been added to the
753 //------------------------------------------------------------------------------
754 void wls_fapi_free_send_free_list(
757 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
758 L1L2MessageHdr *p_msg_header = NULL;
759 int count = 0, loc = 0;
761 if (idx >= TO_FREE_SIZE) {
762 NR5G_FAPI_LOG(ERROR_LOG, ("%s: list index: %d\n", __func__, idx));
766 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list[idx][count];
768 p_msg_header = (PL1L2MessageHdr) (pNextMsg + 1);
769 loc = get_stats_location(p_msg_header->nMessageType);
770 wls_fapi_free_buffer(pNextMsg, loc);
771 g_to_free_send_list[idx][count++] = 0L;
772 if (g_to_free_send_list[idx][count])
773 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list[idx][count];
778 NR5G_FAPI_LOG(DEBUG_LOG, ("Free %d\n", count));
779 g_to_free_send_list_cnt[idx] = 0;
784 //------------------------------------------------------------------------------
785 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
787 * @param[in] pListElem Pointer to List element header
788 * @param[in] idx Subframe Number
790 * @return Number of blocks freed
792 * @description This function Frees all the blocks in a List Element Linked
793 * List coming from L1 by storing them into an array to be
794 * freed at a later point in time. Used by urllc thread.
796 //------------------------------------------------------------------------------
797 void wls_fapi_add_send_apis_to_free_urllc(
798 PMAC2PHY_QUEUE_EL pListElem,
801 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
804 count = g_to_free_send_list_cnt_urllc[idx];
805 pNextMsg = pListElem;
807 if (count >= TOTAL_FREE_BLOCKS) {
808 NR5G_FAPI_LOG(ERROR_LOG, ("%s: Reached max capacity of free list.\n"
809 "\t\t\t\tlist index: %d list count: %d max list count: %d",
810 __func__, idx, count, TOTAL_FREE_BLOCKS));
814 g_to_free_send_list_urllc[idx][count++] = (uint64_t) pNextMsg;
815 pNextMsg = pNextMsg->pNext;
818 g_to_free_send_list_urllc[idx][count] = 0L;
819 g_to_free_send_list_cnt_urllc[idx] = count;
821 NR5G_FAPI_LOG(DEBUG_LOG, ("To Free %d\n", count));
824 //------------------------------------------------------------------------------
825 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
827 * @param[in] idx subframe Number
829 * @return Number of blocks freed
831 * @description This function frees all blocks that have been added to the
832 * free array. Used by urllc thread.
834 //------------------------------------------------------------------------------
835 void wls_fapi_free_send_free_list_urllc(
838 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
839 L1L2MessageHdr *p_msg_header = NULL;
840 int count = 0, loc = 0;
842 if (idx >= TO_FREE_SIZE_URLLC) {
843 NR5G_FAPI_LOG(ERROR_LOG, ("%s: list index: %d\n", __func__, idx));
847 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list_urllc[idx][count];
849 p_msg_header = (PL1L2MessageHdr) (pNextMsg + 1);
850 loc = get_stats_location(p_msg_header->nMessageType);
851 wls_fapi_free_buffer(pNextMsg, loc);
852 g_to_free_send_list_urllc[idx][count++] = 0L;
853 if (g_to_free_send_list_urllc[idx][count])
854 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list_urllc[idx][count];
859 NR5G_FAPI_LOG(DEBUG_LOG, ("Free %d\n", count));
860 g_to_free_send_list_cnt_urllc[idx] = 0;