1 /******************************************************************************
3 * Copyright (c) 2021 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_mac_phy_api.h"
25 #include "nr5g_fapi_std.h"
26 #include "nr5g_fapi_common_types.h"
27 #include "nr5g_fapi_internal.h"
28 #include "nr5g_fapi_wls.h"
29 #include "nr5g_fapi_fapi2phy_wls.h"
30 #include "nr5g_fapi_log.h"
31 #include "nr5g_fapi_framework.h"
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 uint32_t g_to_free_send_list_cnt_urllc[TO_FREE_SIZE_URLLC] = { 0 };
39 static uint64_t g_to_free_send_list_urllc[TO_FREE_SIZE_URLLC][TOTAL_FREE_BLOCKS] = { {0L} };
41 static uint32_t g_free_recv_idx = 0;
42 static uint32_t g_free_send_idx = 0;
43 static uint32_t g_free_send_idx_urllc = 0;
45 uint64_t *nr5g_fapi_fapi2phy_wls_get(
46 uint32_t * const msg_size,
47 uint16_t * const msg_type,
48 uint16_t * const flags);
50 uint8_t nr5g_fapi_fapi2phy_wls_put(
56 //------------------------------------------------------------------------------
57 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
59 * @param data Pointer to validate
61 * @return TRUE If pointer is within valid shared WLS memory region
62 * FALSE If pointer is out of valid shared WLS memory region
65 * This function validates pointer's in WLS shared memory region
68 //------------------------------------------------------------------------------
69 uint8_t nr5g_fapi_fapi2phy_is_valid_wls_ptr(
72 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
73 if ((unsigned long)data >= (unsigned long)p_wls_ctx->pPartitionMemBase &&
74 (unsigned long)data < ((unsigned long)p_wls_ctx->pPartitionMemBase +
75 p_wls_ctx->nPartitionMemSize)) {
82 //------------------------------------------------------------------------------
83 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
87 * @return A pointer to WLS_HANDLE stucture
90 * This function returns the WLS instance
93 //------------------------------------------------------------------------------
94 static inline WLS_HANDLE nr5g_fapi_fapi2phy_wls_instance(
97 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
98 return p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST];
101 //----------------------------------------------------------------------------------
102 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
104 * @param[out] data Location where First API from L1 is stored
106 * @return Size of Message sent from L1
109 * This function queries the APIs sent from L1 to L2 and gets the first pointer
113 //----------------------------------------------------------------------------------
114 inline uint64_t *nr5g_fapi_fapi2phy_wls_get(
115 uint32_t * const msg_size,
116 uint16_t * const msg_type,
117 uint16_t * const flags)
119 uint64_t *data = NULL;
122 uint16_t mt = 0, f = 0;
124 h_wls = nr5g_fapi_fapi2phy_wls_instance();
125 data = (uint64_t *) WLS_Get(h_wls, &ms, &mt, &f);
126 *msg_size = ms, *msg_type = mt, *flags = f;
127 NR5G_FAPI_LOG(TRACE_LOG, ("[FAPI2PHY WLS][GET] %p size: %d "
128 "type: %x flags: %x", data, *msg_size, *msg_type, *flags));
133 //----------------------------------------------------------------------------------
134 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
136 * @param[in] p_msg Pointer to API block that needs to be sent to L1
137 * @param[in] msg_size Size of Message
138 * @param[in] msg_id Message Id
139 * @param[in] flags Special flags needed for WLS
141 * @return 0 if SUCCESS
144 * This function adds a block of API from L2 to L1 which will be sent later
147 //----------------------------------------------------------------------------------
148 inline uint8_t nr5g_fapi_fapi2phy_wls_put(
155 WLS_HANDLE h_phy_wls = nr5g_fapi_fapi2phy_wls_instance();
156 uint64_t pa = nr5g_fapi_wls_va_to_pa(h_phy_wls, (void *)p_msg);
157 NR5G_FAPI_LOG(TRACE_LOG, ("[FAPI2PHY WLS][PUT] %ld size: %d "
158 "type: %x flags: %x", pa, msg_size, msg_type, flags));
159 ret = WLS_Put(h_phy_wls, pa, msg_size, msg_type, flags);
164 //----------------------------------------------------------------------------------
165 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
169 * @return Number of blocks of APIs received
172 * This functions waits in a infinite loop for L1 to send a list of APIs to MAC. This is called
173 * during runtime when L2 sends a API to L1 and then waits for response back.
176 //----------------------------------------------------------------------------------
177 inline uint32_t nr5g_fapi_fapi2phy_wls_wait(
181 // NR5G_FAPI_LOG(TRACE_LOG, ("Waiting for L1 to respond in WLS Wait"));
182 ret = WLS_Wait(nr5g_fapi_fapi2phy_wls_instance());
186 //------------------------------------------------------------------------------
187 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
189 * @param[out] data Location where First API from L1 is stored
191 * @return Size of Message sent from L1
194 * This function checks if this is the last message in this tti.
197 //------------------------------------------------------------------------------
198 static inline uint8_t is_msg_present(
201 return (!((flags & WLS_TF_FIN) || (flags == 0)));
204 void nr5g_fapi_transfer_to_free_recv_list (
205 PMAC2PHY_QUEUE_EL p_qelm_list
206 /*uint32_t* free_recv_idx*/)
208 wls_fapi_add_recv_apis_to_free(p_qelm_list, g_free_recv_idx);
210 if ((g_free_recv_idx) >= TO_FREE_SIZE) {
211 (g_free_recv_idx) = 0;
213 // Free few TTIs Later
214 wls_fapi_free_recv_free_list(g_free_recv_idx);
216 wls_fapi_add_blocks_to_ul();
219 //----------------------------------------------------------------------------------
220 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
222 * @param[out] data Location where First API from L1 is stored
224 * @return Size of Message sent from L1
227 * This function queries the APIs sent from L1 to L2 and gets the first pointer
231 //----------------------------------------------------------------------------------
232 PMAC2PHY_QUEUE_EL nr5g_fapi_fapi2phy_wls_recv(
235 uint16_t msg_type = 0;
237 uint32_t msg_size = 0;
238 uint32_t num_elms = 0;
239 uint64_t *p_msg = NULL;
240 PMAC2PHY_QUEUE_EL p_qelm_list = NULL, p_urllc_qelm_list = NULL;
241 PMAC2PHY_QUEUE_EL p_qelm = NULL;
242 PMAC2PHY_QUEUE_EL p_tail_qelm = NULL, p_urllc_tail_qelm = NULL;
243 uint64_t start_tick = 0;
245 num_elms = nr5g_fapi_fapi2phy_wls_wait();
249 start_tick = __rdtsc();
252 p_msg = nr5g_fapi_fapi2phy_wls_get(&msg_size, &msg_type, &flags);
254 WLS_HANDLE h_wls = nr5g_fapi_fapi2phy_wls_instance();
255 p_qelm = (PMAC2PHY_QUEUE_EL)
256 nr5g_fapi_wls_pa_to_va(h_wls, (uint64_t) p_msg);
257 if (nr5g_fapi_fapi2phy_is_valid_wls_ptr(p_qelm) == FALSE) {
258 printf("Error: Invalid Ptr\n");
261 p_qelm->pNext = NULL;
263 if (flags & WLS_TF_URLLC)
265 if (p_urllc_qelm_list) {
266 p_urllc_tail_qelm->pNext = p_qelm;
267 p_urllc_tail_qelm = p_qelm;
269 p_urllc_qelm_list = p_qelm;
270 p_urllc_tail_qelm = p_qelm;
274 p_tail_qelm->pNext = p_qelm;
275 p_tail_qelm = p_qelm;
277 p_qelm_list = p_qelm;
278 p_tail_qelm = p_qelm;
284 } while (num_elms && is_msg_present(flags));
286 if (p_urllc_qelm_list) {
287 nr5g_fapi_transfer_to_free_recv_list (p_urllc_qelm_list);
288 nr5g_fapi_urllc_thread_callback((void *) p_urllc_qelm_list,
289 &nr5g_fapi_get_nr5g_fapi_phy_ctx()->urllc_phy2mac_params);
293 nr5g_fapi_transfer_to_free_recv_list (p_qelm_list);
295 tick_total_wls_get_per_tti_ul += __rdtsc() - start_tick;
300 //------------------------------------------------------------------------------
301 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
303 * @param[in] p_msg_header Pointer to the TxSDuReq Message block
304 * @param[out] n_zbc_blocks Number of ZBC blocks
306 * @return 1 if this block is a TxSduReq message. 0 else.
309 * This function checks if a block is a TxSduReq messages and counts the number
310 * of ZBC blocks in this API
313 //------------------------------------------------------------------------------
314 int nr5g_fapi_fapi2phy_is_sdu_zbc_block(
318 PL1L2MessageHdr p_msg_header = (PL1L2MessageHdr) p_msg;
321 if (p_msg_header->nMessageType == MSG_TYPE_PHY_TX_REQ) {
322 PTXRequestStruct p_dl_sdu_req = (PTXRequestStruct) p_msg_header;
323 PDLPDUDataStruct p_dl_pdu_data = (PDLPDUDataStruct) (p_dl_sdu_req + 1);
325 for (i = 0; i < p_dl_sdu_req->nPDU; i++) {
326 *num_zbc_blocks += (p_dl_pdu_data->nPduLen1 ? 1 : 0);
327 *num_zbc_blocks += (p_dl_pdu_data->nPduLen2 ? 1 : 0);
331 if (*num_zbc_blocks) {
339 //----------------------------------------------------------------------------------
340 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
342 * @param[in] p_msg_header Pointer to the TxSduReq Message block
343 * @param[in] flags Special flags needed for WLS
344 * @param[in] n_zbc_blocks Number of ZBC blocks in list
346 * @return 0 if SUCCESS
349 * This function adds all the ZBC blocks in a TXSDU Message and prepares them to
353 //------------------------------------------------------------------------------
354 uint32_t nr5g_fapi_fapi2phy_send_zbc_blocks(
358 PL1L2MessageHdr p_msg_header = (PL1L2MessageHdr) p_msg;
359 PTXRequestStruct p_dl_sdu_req = (PTXRequestStruct) p_msg_header;
360 PDLPDUDataStruct p_dl_pdu_data = (PDLPDUDataStruct) (p_dl_sdu_req + 1);
361 uint32_t i, j, is_last, is_last1, msg_type;
362 uint16_t list_flags = flags;
363 uint16_t flags_urllc = (flags & WLS_TF_URLLC) ? WLS_TF_URLLC : 0;
365 for (i = 0; i < p_dl_sdu_req->nPDU; i++) {
366 is_last = (i == (p_dl_sdu_req->nPDU - 1));
367 for (j = 0; j < MAX_DL_PER_UE_CODEWORD_NUM; j++) {
373 pdu_len = p_dl_pdu_data->nPduLen1;
374 p_payload = p_dl_pdu_data->pPayload1;
375 msg_type = MSG_PHY_ZBC_BLOCK0_REQ;
377 pdu_len = p_dl_pdu_data->nPduLen2;
378 p_payload = p_dl_pdu_data->pPayload2;
379 msg_type = MSG_PHY_ZBC_BLOCK1_REQ;
383 is_last1 = (((j == 0) && (p_dl_pdu_data->pPayload2 == 0)) ||
384 (j == (MAX_DL_PER_UE_CODEWORD_NUM - 1)));
385 if ((list_flags & WLS_TF_FIN) && is_last && is_last1) {
386 flags = WLS_SG_LAST | flags_urllc;
388 flags = WLS_SG_NEXT | flags_urllc;
391 WLS_HANDLE h_phy_wls = nr5g_fapi_fapi2phy_wls_instance();
392 if (WLS_Put(h_phy_wls, (uint64_t) p_payload, pdu_len, msg_type,
394 printf("Error ZBC block 0x%016lx\n", (uint64_t) p_payload);
405 //------------------------------------------------------------------------------
406 /** @ingroup nr5g_fapi_source_framework_wls_fapi2phy_group
408 * @param[in] A pointer to the phy instance
409 * @param[in] A data Pointer to the Linked list header
411 * @return 0 if SUCCESS
413 * @description This function sends a list of APIs to the L1 via WLS
416 //------------------------------------------------------------------------------
417 uint8_t nr5g_fapi_fapi2phy_wls_send(
421 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
422 PMAC2PHY_QUEUE_EL p_curr_msg = NULL;
423 PL1L2MessageHdr p_msg_header;
425 uint16_t flags_urllc = (is_urllc ? WLS_TF_URLLC : 0);
426 uint8_t ret = SUCCESS;
427 int n_zbc_blocks = 0, is_zbc = 0, count = 0;
429 p_curr_msg = (PMAC2PHY_QUEUE_EL) data;
430 is_urllc ? wls_fapi_add_send_apis_to_free_urllc(p_curr_msg, g_free_send_idx_urllc)
431 : wls_fapi_add_send_apis_to_free(p_curr_msg, g_free_send_idx);
433 if (pthread_mutex_lock((pthread_mutex_t *) & p_wls_ctx->fapi2phy_lock_send)) {
434 NR5G_FAPI_LOG(ERROR_LOG, ("unable to lock send pthread mutex"));
438 if (p_curr_msg->pNext) {
439 flags = WLS_SG_FIRST | flags_urllc;
443 p_msg_header = (PL1L2MessageHdr) (p_curr_msg + 1);
444 if (p_curr_msg->pNext) { // FIRST/NEXT list element
445 if (SUCCESS != nr5g_fapi_fapi2phy_wls_put((uint64_t) p_curr_msg,
446 p_curr_msg->nMessageLen + sizeof(MAC2PHY_QUEUE_EL),
447 p_msg_header->nMessageType, flags)) {
448 if (pthread_mutex_unlock((pthread_mutex_t *) &
449 p_wls_ctx->fapi2phy_lock_send)) {
450 NR5G_FAPI_LOG(ERROR_LOG,
451 ("unable to unlock send pthread mutex"));
456 if (nr5g_fapi_fapi2phy_is_sdu_zbc_block(p_msg_header, &n_zbc_blocks)) { // ZBC blocks
457 if (nr5g_fapi_fapi2phy_send_zbc_blocks(p_msg_header,
459 if (pthread_mutex_unlock((pthread_mutex_t *) &
460 p_wls_ctx->fapi2phy_lock_send)) {
461 NR5G_FAPI_LOG(ERROR_LOG,
462 ("unable to unlock send pthread mutex"));
467 p_curr_msg = p_curr_msg->pNext;
468 } else { /* p_curr_msg->Next */
470 flags = WLS_SG_LAST | flags_urllc;
472 if (nr5g_fapi_fapi2phy_is_sdu_zbc_block(p_msg_header,
474 flags = WLS_SG_NEXT | flags_urllc;
477 if (nr5g_fapi_fapi2phy_wls_put((uint64_t) p_curr_msg,
478 p_curr_msg->nMessageLen + sizeof(MAC2PHY_QUEUE_EL),
479 p_msg_header->nMessageType, flags) != SUCCESS) {
481 if (pthread_mutex_unlock((pthread_mutex_t *) &
482 p_wls_ctx->fapi2phy_lock_send)) {
483 NR5G_FAPI_LOG(ERROR_LOG,
484 ("unable to unlock send pthread mutex"));
489 if (is_zbc) { // ZBC blocks
490 if (nr5g_fapi_fapi2phy_send_zbc_blocks(p_msg_header,
491 WLS_SG_LAST | flags_urllc) != SUCCESS) {
493 if (pthread_mutex_unlock((pthread_mutex_t *) &
494 p_wls_ctx->fapi2phy_lock_send)) {
495 NR5G_FAPI_LOG(ERROR_LOG,
496 ("unable to unlock send pthread mutex"));
502 } /* p_curr_msg->Next */
503 flags = WLS_SG_NEXT | flags_urllc;
505 } else { // one block
507 if (nr5g_fapi_fapi2phy_is_sdu_zbc_block(p_curr_msg, &n_zbc_blocks)) {
508 printf("Error ZBC block cannot be only one in the list\n");
509 if (pthread_mutex_unlock((pthread_mutex_t *) &
510 p_wls_ctx->fapi2phy_lock_send)) {
511 NR5G_FAPI_LOG(ERROR_LOG,
512 ("unable to unlock send pthread mutex"));
517 if (SUCCESS != nr5g_fapi_fapi2phy_wls_put((uint64_t) p_curr_msg,
518 p_curr_msg->nMessageLen + sizeof(MAC2PHY_QUEUE_EL),
519 p_curr_msg->nMessageType, flags)) {
521 if (pthread_mutex_unlock((pthread_mutex_t *) &
522 p_wls_ctx->fapi2phy_lock_send)) {
523 NR5G_FAPI_LOG(ERROR_LOG,
524 ("unable to unlock send pthread mutex"));
532 g_free_send_idx_urllc++;
533 if (g_free_send_idx_urllc >= TO_FREE_SIZE_URLLC)
534 g_free_send_idx_urllc = 0;
537 if (g_free_send_idx >= TO_FREE_SIZE)
541 // Free some TTIs Later
542 is_urllc ? wls_fapi_free_send_free_list_urllc()
543 : wls_fapi_free_send_free_list();
546 if (pthread_mutex_unlock((pthread_mutex_t *) &
547 p_wls_ctx->fapi2phy_lock_send)) {
548 NR5G_FAPI_LOG(ERROR_LOG, ("unable to unlock send pthread mutex"));
554 //------------------------------------------------------------------------------
555 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
557 * @param[in] pListElem Pointer to List element header
558 * @param[in] idx Subframe Number
560 * @return Number of blocks freed
562 * @description This function Frees all the blocks in a List Element Linked
563 * List coming from L1 by storing them into an array to be
564 * freed at a later point in time.
566 //------------------------------------------------------------------------------
567 uint8_t get_stats_location(
572 case MSG_TYPE_PHY_CONFIG_REQ:
573 loc = MEM_STAT_CONFIG_REQ;
575 case MSG_TYPE_PHY_START_REQ:
576 loc = MEM_STAT_START_REQ;
578 case MSG_TYPE_PHY_STOP_REQ:
579 loc = MEM_STAT_STOP_REQ;
581 case MSG_TYPE_PHY_SHUTDOWN_REQ:
582 loc = MEM_STAT_SHUTDOWN_REQ;
584 case MSG_TYPE_PHY_DL_CONFIG_REQ:
585 loc = MEM_STAT_DL_CONFIG_REQ;
587 case MSG_TYPE_PHY_UL_CONFIG_REQ:
588 loc = MEM_STAT_UL_CONFIG_REQ;
590 case MSG_TYPE_PHY_UL_DCI_REQ:
591 loc = MEM_STAT_UL_DCI_REQ;
593 case MSG_TYPE_PHY_TX_REQ:
594 loc = MEM_STAT_TX_REQ;
596 case MSG_TYPE_PHY_DL_IQ_SAMPLES:
597 loc = MEM_STAT_DL_IQ_SAMPLES;
599 case MSG_TYPE_PHY_UL_IQ_SAMPLES:
600 loc = MEM_STAT_UL_IQ_SAMPLES;
603 loc = MEM_STAT_DEFAULT;
609 //------------------------------------------------------------------------------
610 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
612 * @param[in] pListElem Pointer to List element header
613 * @param[in] idx Subframe Number
615 * @return Number of blocks freed
617 * @description This function Frees all the blocks in a List Element Linked
618 * List coming from L1 by storing them into an array to be
619 * freed at a later point in time.
621 //------------------------------------------------------------------------------
622 void wls_fapi_add_recv_apis_to_free(
623 PMAC2PHY_QUEUE_EL pListElem,
626 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
627 L1L2MessageHdr *p_msg_header = NULL;
628 PRXULSCHIndicationStruct p_phy_rx_ulsch_ind = NULL;
629 PULSCHPDUDataStruct p_ulsch_pdu = NULL;
635 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
636 h_wls = p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST];
638 count = g_to_free_recv_list_cnt[idx];
639 pNextMsg = pListElem;
641 if (count >= TOTAL_FREE_BLOCKS) {
642 NR5G_FAPI_LOG(ERROR_LOG, ("%s: Reached max capacity of free list.\n"
643 "\t\t\t\tlist index: %d list count: %d max list count: %d",
644 __func__, idx, count, TOTAL_FREE_BLOCKS));
648 g_to_free_recv_list[idx][count++] = (uint64_t) pNextMsg;
649 p_msg_header = (PL1L2MessageHdr) (pNextMsg + 1);
650 if (p_msg_header->nMessageType == MSG_TYPE_PHY_RX_ULSCH_IND) {
651 p_phy_rx_ulsch_ind = (PRXULSCHIndicationStruct) p_msg_header;
652 for (i = 0u; i < p_phy_rx_ulsch_ind->nUlsch; i++) {
653 p_ulsch_pdu = &(p_phy_rx_ulsch_ind->sULSCHPDUDataStruct[i]);
654 if(p_ulsch_pdu->nPduLen > 0) {
655 ptr = (uint8_t *) nr5g_fapi_wls_pa_to_va(h_wls,
656 (uint64_t) p_ulsch_pdu->pPayload);
659 g_to_free_recv_list[idx][count++] = (uint64_t) ptr;
662 NR5G_FAPI_LOG(DEBUG_LOG, ("%s: Payload for"
663 "MSG_TYPE_PHY_RX_ULSCH_IND ulsch pdu (%u/%u) is NULL."
664 "Skip adding to free list.",
665 __func__, i, p_phy_rx_ulsch_ind->nUlsch));
669 pNextMsg = pNextMsg->pNext;
672 g_to_free_recv_list[idx][count] = 0L;
673 g_to_free_recv_list_cnt[idx] = count;
675 NR5G_FAPI_LOG(DEBUG_LOG, ("To Free %d\n", count));
678 //------------------------------------------------------------------------------
679 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
681 * @param[in] idx subframe Number
683 * @return Number of blocks freed
685 * @description This function frees all blocks that have been added to the
688 //------------------------------------------------------------------------------
689 void wls_fapi_free_recv_free_list(
692 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
695 if (idx >= TO_FREE_SIZE) {
696 NR5G_FAPI_LOG(ERROR_LOG, ("%s: list index: %d\n", __func__, idx));
700 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_recv_list[idx][count];
702 wls_fapi_free_buffer(pNextMsg, MIN_UL_BUF_LOCATIONS);
703 g_to_free_recv_list[idx][count++] = 0L;
704 if (g_to_free_recv_list[idx][count])
705 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_recv_list[idx][count];
710 NR5G_FAPI_LOG(DEBUG_LOG, ("Free %d\n", count));
711 g_to_free_recv_list_cnt[idx] = 0;
716 //------------------------------------------------------------------------------
717 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
719 * @param[in] pListElem Pointer to List element header
720 * @param[in] idx Subframe Number
722 * @return Number of blocks freed
724 * @description This function Frees all the blocks in a List Element Linked
725 * List coming from L1 by storing them into an array to be
726 * freed at a later point in time.
728 //------------------------------------------------------------------------------
729 void wls_fapi_add_send_apis_to_free(
730 PMAC2PHY_QUEUE_EL pListElem,
733 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
736 count = g_to_free_send_list_cnt[idx];
737 pNextMsg = pListElem;
739 if (count >= TOTAL_FREE_BLOCKS) {
740 NR5G_FAPI_LOG(ERROR_LOG, ("%s: Reached max capacity of free list.\n"
741 "\t\t\t\tlist index: %d list count: %d max list count: %d",
742 __func__, idx, count, TOTAL_FREE_BLOCKS));
746 g_to_free_send_list[idx][count++] = (uint64_t) pNextMsg;
747 pNextMsg = pNextMsg->pNext;
750 g_to_free_send_list[idx][count] = 0L;
751 g_to_free_send_list_cnt[idx] = count;
753 NR5G_FAPI_LOG(DEBUG_LOG, ("To Free %d\n", count));
756 //------------------------------------------------------------------------------
757 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
759 * @param[in] idx subframe Number
761 * @return Number of blocks freed
763 * @description This function frees all blocks that have been added to the
766 //------------------------------------------------------------------------------
767 void wls_fapi_free_send_free_list()
769 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
770 L1L2MessageHdr *p_msg_header = NULL;
771 int count = 0, loc = 0;
773 if (g_free_send_idx >= TO_FREE_SIZE) {
774 NR5G_FAPI_LOG(ERROR_LOG, ("%s: list index: %d\n", __func__, g_free_send_idx));
778 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list[g_free_send_idx][count];
780 p_msg_header = (PL1L2MessageHdr) (pNextMsg + 1);
781 loc = get_stats_location(p_msg_header->nMessageType);
782 wls_fapi_free_buffer(pNextMsg, loc);
783 g_to_free_send_list[g_free_send_idx][count++] = 0L;
784 if (g_to_free_send_list[g_free_send_idx][count])
785 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list[g_free_send_idx][count];
790 NR5G_FAPI_LOG(DEBUG_LOG, ("Free %d\n", count));
791 g_to_free_send_list_cnt[g_free_send_idx] = 0;
796 //------------------------------------------------------------------------------
797 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
799 * @param[in] pListElem Pointer to List element header
800 * @param[in] idx Subframe Number
802 * @return Number of blocks freed
804 * @description This function Frees all the blocks in a List Element Linked
805 * List coming from L1 by storing them into an array to be
806 * freed at a later point in time. Used by urllc thread.
808 //------------------------------------------------------------------------------
809 void wls_fapi_add_send_apis_to_free_urllc(
810 PMAC2PHY_QUEUE_EL pListElem,
813 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
816 count = g_to_free_send_list_cnt_urllc[idx];
817 pNextMsg = pListElem;
819 if (count >= TOTAL_FREE_BLOCKS) {
820 NR5G_FAPI_LOG(ERROR_LOG, ("%s: Reached max capacity of free list.\n"
821 "\t\t\t\tlist index: %d list count: %d max list count: %d",
822 __func__, idx, count, TOTAL_FREE_BLOCKS));
826 g_to_free_send_list_urllc[idx][count++] = (uint64_t) pNextMsg;
827 pNextMsg = pNextMsg->pNext;
830 g_to_free_send_list_urllc[idx][count] = 0L;
831 g_to_free_send_list_cnt_urllc[idx] = count;
833 NR5G_FAPI_LOG(DEBUG_LOG, ("To Free %d\n", count));
836 //------------------------------------------------------------------------------
837 /** @ingroup nr5g_fapi_source_framework_wls_lib_group
839 * @param[in] idx subframe Number
841 * @return Number of blocks freed
843 * @description This function frees all blocks that have been added to the
844 * free array. Used by urllc thread.
846 //------------------------------------------------------------------------------
847 void wls_fapi_free_send_free_list_urllc()
849 PMAC2PHY_QUEUE_EL pNextMsg = NULL;
850 L1L2MessageHdr *p_msg_header = NULL;
851 int count = 0, loc = 0;
853 if (g_free_send_idx_urllc >= TO_FREE_SIZE_URLLC) {
854 NR5G_FAPI_LOG(ERROR_LOG, ("%s: list index: %d\n", __func__, g_free_send_idx_urllc));
858 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list_urllc[g_free_send_idx_urllc][count];
860 p_msg_header = (PL1L2MessageHdr) (pNextMsg + 1);
861 loc = get_stats_location(p_msg_header->nMessageType);
862 wls_fapi_free_buffer(pNextMsg, loc);
863 g_to_free_send_list_urllc[g_free_send_idx_urllc][count++] = 0L;
864 if (g_to_free_send_list_urllc[g_free_send_idx_urllc][count])
865 pNextMsg = (PMAC2PHY_QUEUE_EL) g_to_free_send_list_urllc[g_free_send_idx_urllc][count];
870 NR5G_FAPI_LOG(DEBUG_LOG, ("Free %d\n", count));
871 g_to_free_send_list_cnt_urllc[g_free_send_idx_urllc] = 0;