2c7de23dd75e1d19fdaa3dee4ea28cbf3e32945c
[o-du/phy.git] / fapi_5g / source / framework / workers / nr5g_fapi_mac2phy_thread.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2019 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 #include "nr5g_fapi_std.h"
19 #include "nr5g_fapi_mac2phy_thread.h"
20 #include "nr5g_fapi_fapi2mac_wls.h"
21 #include "nr5g_fapi_fapi2phy_api.h"
22 #include "nr5g_fapi_fapi2phy_p5_proc.h"
23 #include "nr5g_fapi_fapi2phy_p7_proc.h"
24
25 //------------------------------------------------------------------------------
26 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
27  *
28  *  @param[in,out]   void
29  *
30  *  @return none
31  *
32  *  @description
33  *  DOXYGEN_TO_DO
34  *
35 **/
36 //------------------------------------------------------------------------------
37 void *nr5g_fapi_mac2phy_thread_func(
38     void *config)
39 {
40     cpu_set_t cpuset;
41     pthread_t thread;
42     p_fapi_api_queue_elem_t p_msg_list = NULL;
43     p_nr5g_fapi_phy_ctx_t p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
44
45     NR5G_FAPI_LOG(INFO_LOG, ("[MAC2PHY] Thread %s launched LWP:%ld on "
46             "Core: %d\n", __func__, pthread_self(),
47             p_phy_ctx->mac2phy_worker_core_id));
48
49     thread = p_phy_ctx->mac2phy_tid = pthread_self();
50     CPU_ZERO(&cpuset);
51     CPU_SET(p_phy_ctx->mac2phy_worker_core_id, &cpuset);
52     pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
53
54     usleep(1000);
55     while (!p_phy_ctx->process_exit) {
56         p_msg_list = nr5g_fapi_fapi2mac_wls_recv();
57         if (p_msg_list)
58             nr5g_fapi_mac2phy_api_recv_handler(config, p_msg_list);
59     }
60     pthread_exit(NULL);
61 }
62
63 //------------------------------------------------------------------------------
64 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
65  *
66  *  @param[in,out]   void
67  *
68  *  @return none
69  *
70  *  @description
71  *  DOXYGEN_TO_DO
72  *
73 **/
74 //------------------------------------------------------------------------------
75 void nr5g_fapi_mac2phy_api_recv_handler(
76     void *config,
77     p_fapi_api_queue_elem_t p_msg_list)
78 {
79     p_fapi_api_queue_elem_t p_per_carr_api_list = NULL;
80     p_fapi_api_queue_elem_t p_prev_elm = NULL;
81     fapi_msg_t *p_fapi_msg = NULL;
82     p_fapi_msg_header_t p_fapi_msg_header = NULL;
83
84     p_nr5g_fapi_phy_ctx_t p_phy_ctx = NULL;
85     p_nr5g_fapi_phy_instance_t p_phy_instance = NULL;
86     uint8_t num_apis = 0;
87     uint8_t phy_id = 0;
88
89     NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] %s:", __func__));
90     p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
91     while (p_msg_list) {
92         p_per_carr_api_list = p_msg_list;
93         p_fapi_msg_header = (fapi_msg_header_t *) (p_per_carr_api_list + 1);
94         num_apis = p_fapi_msg_header->num_msg;
95         phy_id = p_fapi_msg_header->handle;
96
97         if (num_apis > 0 && p_msg_list->p_next) {   // likely
98             p_per_carr_api_list = p_per_carr_api_list->p_next;
99             p_msg_list = p_per_carr_api_list;
100             NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
101                     phy_id, num_apis));
102         } else {                // unlikely
103             // skip to next carrier list. since current fapi message hearder
104             // has no apis
105             if (p_msg_list->p_next) {
106                 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] No APIs for PHY_ID: %d."
107                         " Skip...\n", phy_id));
108                 p_msg_list = p_msg_list->p_next;
109                 continue;
110             } else {
111                 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
112                         phy_id, num_apis));
113                 return;
114             }
115         }
116
117         // walk through the list and disconnet per carrier apis
118         if (p_msg_list->p_next) {
119             p_prev_elm = p_msg_list;
120             while (p_msg_list) {
121                 if (FAPI_MSG_HEADER_IND == p_msg_list->msg_type) {
122                     p_prev_elm->p_next = NULL;
123                     break;
124                 }
125                 p_prev_elm = p_msg_list;
126                 p_msg_list = p_msg_list->p_next;
127             }
128         } else {
129             p_msg_list = NULL;
130         }
131
132         if (phy_id > FAPI_MAX_PHY_INSTANCES) {
133             NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY]: Invalid Phy Id: %d\n",
134                     phy_id));
135             continue;
136         }
137
138         if (p_per_carr_api_list) {
139             p_fapi_msg = (fapi_msg_t *) (p_per_carr_api_list + 1);
140             if ((p_fapi_msg->msg_id != FAPI_VENDOR_EXT_UL_IQ_SAMPLES)) {
141                 p_phy_instance = &p_phy_ctx->phy_instance[phy_id];
142                 if (FAPI_STATE_IDLE == p_phy_instance->state) {
143                     if (p_fapi_msg->msg_id != FAPI_CONFIG_REQUEST) {
144                         NR5G_FAPI_LOG(ERROR_LOG,
145                             ("CONFIG.request is not received "
146                                 "for %d PHY Instance\n", phy_id));
147                         continue;
148                     }
149                     p_phy_instance->phy_id = phy_id;
150                 }
151             }
152             nr5g_fapi_mac2phy_api_processing_handler(p_phy_instance,
153                 p_per_carr_api_list);
154             p_per_carr_api_list = NULL;
155         }
156     }
157     // Send to PHY
158     NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Send to PHY.."));
159     nr5g_fapi_fapi2phy_send_api_list();
160 }
161
162 //------------------------------------------------------------------------------
163 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
164  *
165  *  @param[in,out]   void
166  *
167  *  @return none
168  *
169  *  @description
170  *  DOXYGEN_TO_DO
171  *
172 **/
173 //------------------------------------------------------------------------------
174 void nr5g_fapi_mac2phy_api_processing_handler(
175     p_nr5g_fapi_phy_instance_t p_phy_instance,
176     p_fapi_api_queue_elem_t p_msg_list)
177 {
178     uint16_t msg_type;
179     p_fapi_api_queue_elem_t p_vendor_elm = NULL;
180     p_fapi_api_queue_elem_t p_prev_elm = NULL;
181     p_fapi_api_queue_elem_t p_curr_elm = NULL;
182     p_fapi_api_queue_elem_t p_tx_data_elm = NULL;
183     p_fapi_api_queue_elem_t p_tx_data_pdu_list = NULL;
184     p_fapi_api_queue_elem_t p_tx_data_pdu_list_tail = NULL;
185     fapi_msg_t *p_fapi_msg = NULL;
186     fapi_vendor_msg_t *p_vendor_msg = NULL;
187
188     // Get vendor body if present
189     p_prev_elm = p_vendor_elm = p_msg_list;
190     while (p_vendor_elm) {
191         p_fapi_msg = (fapi_msg_t *) (p_vendor_elm + 1);
192         if (p_fapi_msg->msg_id == FAPI_VENDOR_MESSAGE) {
193             if (p_prev_elm == p_vendor_elm) {
194                 NR5G_FAPI_LOG(ERROR_LOG,
195                     ("[MAC2PHY] Received only Vendor Message"));
196                 return;
197             }
198             p_vendor_msg = (fapi_vendor_msg_t *) p_fapi_msg;
199             NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Vendor Msg: %p\n",
200                     p_vendor_msg));
201             // disconnect the vendor element from the api list
202             p_prev_elm->p_next = NULL;
203             break;
204         }
205         p_prev_elm = p_vendor_elm;
206         p_vendor_elm = p_vendor_elm->p_next;
207     }
208
209     // split the tx_data_request pdus
210     p_curr_elm = p_msg_list;
211     while (p_curr_elm) {
212         msg_type = p_curr_elm->msg_type;
213         if (msg_type == FAPI_TX_DATA_REQUEST) {
214             p_tx_data_elm = p_curr_elm;
215         } else if (msg_type == FAPI_MSG_PHY_ZBC_BLOCK_REQ) {
216             if (p_tx_data_pdu_list) {
217                 p_tx_data_pdu_list_tail->p_next = p_curr_elm;
218                 p_tx_data_pdu_list_tail = p_tx_data_pdu_list_tail->p_next;
219             } else {
220                 p_tx_data_pdu_list_tail = p_tx_data_pdu_list = p_curr_elm;
221             }
222         } else {
223         }
224         p_curr_elm = p_curr_elm->p_next;
225     }
226
227     if (p_tx_data_pdu_list && p_tx_data_elm) {
228         p_tx_data_elm->p_tx_data_elm_list = p_tx_data_pdu_list;
229         p_tx_data_elm->p_next = NULL;
230     }
231     // Walk through the API list
232     while (p_msg_list) {
233         p_fapi_msg = (fapi_msg_t *) (p_msg_list + 1);
234         switch (p_fapi_msg->msg_id) {
235                 /*  P5 Vendor Message Processing */
236 #ifdef DEBUG_MODE
237             case FAPI_VENDOR_EXT_UL_IQ_SAMPLES:
238                 nr5g_fapi_ul_iq_samples_request(
239                     (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
240                 break;
241
242             case FAPI_VENDOR_EXT_DL_IQ_SAMPLES:
243                 nr5g_fapi_dl_iq_samples_request(
244                     (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
245                 break;
246
247 #endif
248             case FAPI_VENDOR_EXT_SHUTDOWN_REQUEST:
249                 nr5g_fapi_shutdown_request(p_phy_instance,
250                     (fapi_vendor_ext_shutdown_req_t *) p_fapi_msg);
251                 break;
252
253                 /*  P5 Message Processing */
254             case FAPI_CONFIG_REQUEST:
255                 nr5g_fapi_config_request(p_phy_instance, (fapi_config_req_t *)
256                     p_fapi_msg, p_vendor_msg);
257                 break;
258
259             case FAPI_START_REQUEST:
260                 nr5g_fapi_start_request(p_phy_instance, (fapi_start_req_t *)
261                     p_fapi_msg, p_vendor_msg);
262                 break;
263
264             case FAPI_STOP_REQUEST:
265                 nr5g_fapi_stop_request(p_phy_instance, (fapi_stop_req_t *)
266                     p_fapi_msg, p_vendor_msg);
267                 break;
268
269                 /*  P7 Message Processing */
270             case FAPI_DL_TTI_REQUEST:
271                 nr5g_fapi_dl_tti_request(p_phy_instance, (fapi_dl_tti_req_t *)
272                     p_fapi_msg, p_vendor_msg);
273                 break;
274
275             case FAPI_UL_TTI_REQUEST:
276                 nr5g_fapi_ul_tti_request(p_phy_instance, (fapi_ul_tti_req_t *)
277                     p_fapi_msg, p_vendor_msg);
278                 break;
279
280             case FAPI_UL_DCI_REQUEST:
281                 nr5g_fapi_ul_dci_request(p_phy_instance, (fapi_ul_dci_req_t *)
282                     p_fapi_msg, p_vendor_msg);
283                 break;
284
285             case FAPI_TX_DATA_REQUEST:
286                 nr5g_fapi_tx_data_request(p_phy_instance, (fapi_tx_data_req_t *)
287                     p_fapi_msg, p_vendor_msg);
288                 p_msg_list->p_tx_data_elm_list = NULL;
289                 break;
290
291             default:
292                 break;
293         }
294         p_msg_list = p_msg_list->p_next;
295     }
296 }