* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fapi_5g / source / api / fapi2mac / nr5g_fapi_fapi2mac_api.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2021 Intel.
4 *
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
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 *******************************************************************************/
18
19 /**
20  * @file This file contains implementation of all the functions used 
21  * to send APIs from FAPI to MAC
22  *
23  **/
24
25 #include <stdio.h>
26 #include "nr5g_fapi_internal.h"
27 #include "nr5g_fapi_fapi2mac_api.h"
28 #include "nr5g_fapi_fapi2mac_wls.h"
29 #include "nr5g_fapi_log.h"
30
31 static nr5g_fapi_fapi2mac_queue_t fapi2mac_q[FAPI_MAX_PHY_INSTANCES];
32 static nr5g_fapi_fapi2mac_queue_t fapi2mac_urllc_q[FAPI_MAX_PHY_INSTANCES];
33
34
35 //------------------------------------------------------------------------------
36 /** @ingroup     group_source_api_fapi2phy
37  *
38  *  @param[in]   phy_id Value of phy_id.
39  *  @param[in]   is_urllc True for urllc, false otherwise.
40  *
41  *  @return      Pointer to fapi2mac api queue.
42  *
43  *  @description This function access proper instance of fapi2mac queue.
44  *
45 **/
46 //------------------------------------------------------------------------------
47 static inline p_nr5g_fapi_fapi2mac_queue_t nr5g_fapi_fapi2mac_queue(
48     uint8_t phy_id,
49     bool is_urllc)
50 {
51     return is_urllc ? &fapi2mac_urllc_q[phy_id] : &fapi2mac_q[phy_id];
52 }
53
54 //------------------------------------------------------------------------------
55 /** @ingroup     group_lte_source_phy_fapi
56  *
57  *  @param[in]   pListElem Pointer to the ListElement
58  *
59  *  @return      void
60  *
61  *  @description This function adds a ListElement API to a Linked list which will
62  *               be sent to L1 once all APIs for a TTI are added
63  *
64 **/
65 //------------------------------------------------------------------------------
66 void nr5g_fapi_fapi2mac_add_api_to_list(
67     uint8_t phy_id,
68     p_fapi_api_queue_elem_t p_list_elem,
69     bool is_urllc)
70 {
71     p_nr5g_fapi_fapi2mac_queue_t queue = NULL;
72     p_fapi_msg_header_t p_fapi_msg_hdr = NULL;
73
74     if (!p_list_elem) {
75         return;
76     }
77
78     queue = nr5g_fapi_fapi2mac_queue(phy_id, is_urllc);
79     if (pthread_mutex_lock((pthread_mutex_t *) & queue->lock)) {
80         NR5G_FAPI_LOG(ERROR_LOG, ("unable to lock fapi2mac aggregate list"
81                 "pthread mutex"));
82         return;
83     }
84     if (queue->p_send_list_head && queue->p_send_list_tail) {
85         p_fapi_msg_hdr = (p_fapi_msg_header_t) (queue->p_send_list_head + 1);
86         p_fapi_msg_hdr->num_msg += 1;
87         queue->p_send_list_tail->p_next = p_list_elem;
88         queue->p_send_list_tail = p_list_elem;
89     } else {
90         queue->p_send_list_head = queue->p_send_list_tail = p_list_elem;
91     }
92     if (pthread_mutex_unlock((pthread_mutex_t *) & queue->lock)) {
93         NR5G_FAPI_LOG(ERROR_LOG, ("unable to unlock fapi2mac aggregate list"
94                 "pthread mutex"));
95         return;
96     }
97 }
98
99 //------------------------------------------------------------------------------
100 /** @ingroup      group_lte_source_phy_fapi
101  *
102  *  @param        A pointer to phy Instance
103  *
104  *  @return       FAPI status
105  *
106  *  @description  This function send API list to L1
107  *
108 **/
109 //------------------------------------------------------------------------------
110 void nr5g_fapi_fapi2mac_send_api_list(
111     bool is_urllc)
112 {
113     uint8_t phy_id = 0;
114     p_fapi_msg_header_t p_fapi_msg_hdr = NULL;
115     p_fapi_api_queue_elem_t p_commit_list_head = NULL;
116     p_fapi_api_queue_elem_t p_commit_list_tail = NULL;
117     p_nr5g_fapi_fapi2mac_queue_t queue = NULL;
118
119     for (phy_id = 0; phy_id < FAPI_MAX_PHY_INSTANCES; phy_id++) {
120         queue = nr5g_fapi_fapi2mac_queue(phy_id, is_urllc);
121         if (pthread_mutex_lock((pthread_mutex_t *) & queue->lock)) {
122             NR5G_FAPI_LOG(ERROR_LOG, ("unable to lock fapi2mac aggregate list"
123                     "pthread mutex"));
124             return;
125         }
126         if (queue->p_send_list_head && queue->p_send_list_tail) {
127             p_fapi_msg_hdr =
128                 (p_fapi_msg_header_t) (queue->p_send_list_head + 1);
129             if (p_fapi_msg_hdr->num_msg) {
130                 if (p_commit_list_head && p_commit_list_tail) {
131                     p_commit_list_tail->p_next = queue->p_send_list_head;
132                     p_commit_list_tail = queue->p_send_list_tail;
133                 } else {
134                     p_commit_list_head = queue->p_send_list_head;
135                     p_commit_list_tail = queue->p_send_list_tail;
136                 }
137             } else {
138                 nr5g_fapi_fapi2mac_wls_free_buffer((void *)
139                     queue->p_send_list_head);
140             }
141             queue->p_send_list_head = queue->p_send_list_tail = NULL;
142         }
143         if (pthread_mutex_unlock((pthread_mutex_t *) & queue->lock)) {
144             NR5G_FAPI_LOG(ERROR_LOG, ("unable to unlock fapi2mac aggregate list"
145                     "pthread mutex"));
146             return;
147         }
148     }
149
150     if (p_commit_list_head)
151         nr5g_fapi_fapi2mac_wls_send(p_commit_list_head, is_urllc);
152 }
153
154 //------------------------------------------------------------------------------
155 /** @ingroup     group_lte_source_phy_fapi
156  *
157  *  @param[in]   phyInstance PhyInstance Id
158  *  @param[in]   NumMessageInBlock Number of Messages in Block
159  *  @param[in]   AlignOffset Align Offset
160  *  @param[in]   MsgType Message Type
161  *  @param[in]   FrameNum Frame Number
162  *  @param[in]   subFrameNum subframe Number
163  *
164  *  @return      Pointer to the List Element structure
165  *
166  *  @description This function allocates a buffer from shared memory WLS
167  *               interface and creates a List Element structures. It then fills
168  *               all the fields with data being passed in.
169  *
170 **/
171 //------------------------------------------------------------------------------
172 p_fapi_api_queue_elem_t nr5g_fapi_fapi2mac_create_api_list_elem(
173     uint32_t msg_type,
174     uint16_t num_message_in_block,
175     uint32_t align_offset)
176 {
177     p_fapi_api_queue_elem_t p_list_elem = NULL;
178
179     p_list_elem = (p_fapi_api_queue_elem_t)
180         nr5g_fapi_fapi2mac_wls_alloc_buffer();
181     //Fill header for link list of API messages
182     if (p_list_elem) {
183         p_list_elem->msg_type = (uint8_t) msg_type;
184         p_list_elem->num_message_in_block = num_message_in_block;
185         p_list_elem->align_offset = (uint16_t) align_offset;
186         p_list_elem->msg_len = num_message_in_block * align_offset;
187         p_list_elem->p_next = NULL;
188         p_list_elem->p_tx_data_elm_list = NULL;
189         p_list_elem->time_stamp = 0;
190     }
191
192     return p_list_elem;
193 }
194
195 //------------------------------------------------------------------------------
196 /** @ingroup     group_lte_source_phy_fapi
197  *
198  *  @return      void
199  *
200  *  @description This function initializes the pthead_mutext_lock.
201  */
202 void nr5g_fapi_fapi2mac_init_api_list(
203     )
204 {
205     uint8_t phy_id = 0;
206     p_nr5g_fapi_fapi2mac_queue_t queue = NULL;
207
208     for (phy_id = 0; phy_id < FAPI_MAX_PHY_INSTANCES; phy_id++) {
209         queue = nr5g_fapi_fapi2mac_queue(phy_id, false);
210         pthread_mutex_init((pthread_mutex_t *) & queue->lock, NULL);
211         queue = nr5g_fapi_fapi2mac_queue(phy_id, true);
212         pthread_mutex_init((pthread_mutex_t *) & queue->lock, NULL);
213     }
214 }