Update to odulow per maintenance bronze
[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 #include "nr5g_fapi_log.h"
25
26 //------------------------------------------------------------------------------
27 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
28  *
29  *  @param[in,out]   void
30  *
31  *  @return none
32  *
33  *  @description
34  *  DOXYGEN_TO_DO
35  *
36 **/
37 //------------------------------------------------------------------------------
38 void *nr5g_fapi_mac2phy_thread_func(
39     void *config)
40 {
41     cpu_set_t cpuset;
42     pthread_t thread;
43     p_fapi_api_queue_elem_t p_msg_list = NULL;
44     p_nr5g_fapi_phy_ctx_t p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
45
46     NR5G_FAPI_LOG(INFO_LOG, ("[MAC2PHY] Thread %s launched LWP:%ld on "
47             "Core: %d\n", __func__, pthread_self(),
48             p_phy_ctx->mac2phy_worker_core_id));
49
50     thread = p_phy_ctx->mac2phy_tid = pthread_self();
51     CPU_ZERO(&cpuset);
52     CPU_SET(p_phy_ctx->mac2phy_worker_core_id, &cpuset);
53     pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
54
55     usleep(1000);
56     while (!p_phy_ctx->process_exit) {
57         p_msg_list = nr5g_fapi_fapi2mac_wls_recv();
58         if (p_msg_list)
59             nr5g_fapi_mac2phy_api_recv_handler(config, p_msg_list);
60     }
61     pthread_exit(NULL);
62 }
63
64 //------------------------------------------------------------------------------
65 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
66  *
67  *  @param[in,out]   void
68  *
69  *  @return none
70  *
71  *  @description
72  *  DOXYGEN_TO_DO
73  *
74 **/
75 //------------------------------------------------------------------------------
76 void nr5g_fapi_mac2phy_api_recv_handler(
77     void *config,
78     p_fapi_api_queue_elem_t p_msg_list)
79 {
80     p_fapi_api_queue_elem_t p_per_carr_api_list = NULL;
81     p_fapi_api_queue_elem_t p_prev_elm = NULL;
82     fapi_msg_t *p_fapi_msg = NULL;
83     p_fapi_msg_header_t p_fapi_msg_header = NULL;
84
85     p_nr5g_fapi_phy_ctx_t p_phy_ctx = NULL;
86     p_nr5g_fapi_phy_instance_t p_phy_instance = NULL;
87     uint8_t num_apis = 0;
88     uint8_t phy_id = 0;
89     uint64_t start_tick = __rdtsc();
90
91     NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] %s:", __func__));
92     p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
93     while (p_msg_list) {
94         p_per_carr_api_list = p_msg_list;
95         p_fapi_msg_header = (fapi_msg_header_t *) (p_per_carr_api_list + 1);
96         num_apis = p_fapi_msg_header->num_msg;
97         phy_id = p_fapi_msg_header->handle;
98
99         if (num_apis > 0 && p_msg_list->p_next) {   // likely
100             p_per_carr_api_list = p_per_carr_api_list->p_next;
101             p_msg_list = p_per_carr_api_list;
102             NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
103                     phy_id, num_apis));
104         } else {                // unlikely
105             // skip to next carrier list. since current fapi message hearder
106             // has no apis
107             if (p_msg_list->p_next) {
108                 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] No APIs for PHY_ID: %d."
109                         " Skip...\n", phy_id));
110                 p_msg_list = p_msg_list->p_next;
111                 continue;
112             } else {
113                 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
114                         phy_id, num_apis));
115                 return;
116             }
117         }
118
119         // walk through the list and disconnet per carrier apis
120         if (p_msg_list->p_next) {
121             p_prev_elm = p_msg_list;
122             while (p_msg_list) {
123                 if (FAPI_VENDOR_MSG_HEADER_IND == p_msg_list->msg_type) {
124                     p_prev_elm->p_next = NULL;
125                     break;
126                 }
127                 p_prev_elm = p_msg_list;
128                 p_msg_list = p_msg_list->p_next;
129             }
130         } else {
131             p_msg_list = NULL;
132         }
133
134         if (phy_id > FAPI_MAX_PHY_INSTANCES) {
135             NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY]: Invalid Phy Id: %d\n",
136                     phy_id));
137             continue;
138         }
139
140         if (p_per_carr_api_list) {
141             p_fapi_msg = (fapi_msg_t *) (p_per_carr_api_list + 1);
142 #ifdef DEBUG_MODE
143             if ((p_fapi_msg->msg_id != FAPI_VENDOR_EXT_UL_IQ_SAMPLES)) {
144 #endif
145                 p_phy_instance = &p_phy_ctx->phy_instance[phy_id];
146                 if (FAPI_STATE_IDLE == p_phy_instance->state) {
147                     if (p_fapi_msg->msg_id != FAPI_CONFIG_REQUEST) {
148                         NR5G_FAPI_LOG(ERROR_LOG,
149                             ("CONFIG.request is not received "
150                                 "for %d PHY Instance\n", phy_id));
151                         continue;
152                     }
153                     p_phy_instance->phy_id = phy_id;
154                 }
155 #ifdef DEBUG_MODE
156             }
157 #endif
158             nr5g_fapi_mac2phy_api_processing_handler(p_phy_instance,
159                 p_per_carr_api_list);
160             p_per_carr_api_list = NULL;
161         }
162     }
163     tick_total_parse_per_tti_dl += __rdtsc() - start_tick;
164     start_tick = __rdtsc();
165
166     // Send to PHY
167     NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Send to PHY.."));
168     nr5g_fapi_fapi2phy_send_api_list();
169     tick_total_wls_send_per_tti_dl += __rdtsc() - start_tick;
170 }
171
172 //------------------------------------------------------------------------------
173 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
174  *
175  *  @param[in,out]   void
176  *
177  *  @return none
178  *
179  *  @description
180  *  DOXYGEN_TO_DO
181  *
182 **/
183 //------------------------------------------------------------------------------
184 void nr5g_fapi_mac2phy_api_processing_handler(
185     p_nr5g_fapi_phy_instance_t p_phy_instance,
186     p_fapi_api_queue_elem_t p_msg_list)
187 {
188     uint16_t msg_type;
189     p_fapi_api_queue_elem_t p_vendor_elm = NULL;
190     p_fapi_api_queue_elem_t p_prev_elm = NULL;
191     p_fapi_api_queue_elem_t p_curr_elm = NULL;
192     p_fapi_api_queue_elem_t p_tx_data_elm = NULL;
193     p_fapi_api_queue_elem_t p_tx_data_pdu_list = NULL;
194     p_fapi_api_queue_elem_t p_tx_data_pdu_list_tail = NULL;
195     fapi_msg_t *p_fapi_msg = NULL;
196     fapi_vendor_msg_t *p_vendor_msg = NULL;
197
198     // Get vendor body if present
199     p_prev_elm = p_vendor_elm = p_msg_list;
200     while (p_vendor_elm) {
201         p_fapi_msg = (fapi_msg_t *) (p_vendor_elm + 1);
202         if (p_fapi_msg->msg_id == FAPI_VENDOR_MESSAGE) {
203             if (p_prev_elm == p_vendor_elm) {
204                 NR5G_FAPI_LOG(ERROR_LOG,
205                     ("[MAC2PHY] Received only Vendor Message"));
206                 return;
207             }
208             p_vendor_msg = (fapi_vendor_msg_t *) p_fapi_msg;
209             NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Vendor Msg: %p\n",
210                     p_vendor_msg));
211             // disconnect the vendor element from the api list
212             p_prev_elm->p_next = NULL;
213             break;
214         }
215         p_prev_elm = p_vendor_elm;
216         p_vendor_elm = p_vendor_elm->p_next;
217     }
218
219     // split the tx_data_request pdus
220     p_curr_elm = p_msg_list;
221     while (p_curr_elm) {
222         msg_type = p_curr_elm->msg_type;
223         if (msg_type == FAPI_TX_DATA_REQUEST) {
224             p_tx_data_elm = p_curr_elm;
225         } else if (msg_type == FAPI_VENDOR_MSG_PHY_ZBC_BLOCK_REQ) {
226             if (p_tx_data_pdu_list) {
227                 p_tx_data_pdu_list_tail->p_next = p_curr_elm;
228                 p_tx_data_pdu_list_tail = p_tx_data_pdu_list_tail->p_next;
229             } else {
230                 p_tx_data_pdu_list_tail = p_tx_data_pdu_list = p_curr_elm;
231             }
232         } else {
233         }
234         p_curr_elm = p_curr_elm->p_next;
235     }
236
237     if (p_tx_data_pdu_list && p_tx_data_elm) {
238         p_tx_data_elm->p_tx_data_elm_list = p_tx_data_pdu_list;
239         p_tx_data_elm->p_next = NULL;
240     }
241
242     if (FAILURE == nr5g_fapi_check_api_ordering(p_phy_instance, p_msg_list)) {
243         NR5G_FAPI_LOG(ERROR_LOG, ("API Ordering is wrong."));
244         return;
245     }
246     // Walk through the API list
247     while (p_msg_list) {
248         p_fapi_msg = (fapi_msg_t *) (p_msg_list + 1);
249         switch (p_fapi_msg->msg_id) {
250                 /*  P5 Vendor Message Processing */
251 #ifdef DEBUG_MODE
252             case FAPI_VENDOR_EXT_UL_IQ_SAMPLES:
253                 nr5g_fapi_ul_iq_samples_request(
254                     (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
255                 break;
256
257             case FAPI_VENDOR_EXT_DL_IQ_SAMPLES:
258                 nr5g_fapi_dl_iq_samples_request(
259                     (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
260                 break;
261
262 #endif
263             case FAPI_VENDOR_EXT_SHUTDOWN_REQUEST:
264                 {
265                     nr5g_fapi_shutdown_request(p_phy_instance,
266                         (fapi_vendor_ext_shutdown_req_t *) p_fapi_msg);
267                     nr5g_fapi_statistic_info_print();
268                     if (g_statistic_start_flag == 1)
269                         g_statistic_start_flag = 0;
270                 }
271                 break;
272
273                 /*  P5 Message Processing */
274             case FAPI_CONFIG_REQUEST:
275                 {
276                     nr5g_fapi_config_request(p_phy_instance,
277                         (fapi_config_req_t *)
278                         p_fapi_msg, p_vendor_msg);
279                     nr5g_fapi_statistic_info_init();
280                 }
281
282                 break;
283
284             case FAPI_START_REQUEST:
285                 nr5g_fapi_start_request(p_phy_instance, (fapi_start_req_t *)
286                     p_fapi_msg, p_vendor_msg);
287                 break;
288
289             case FAPI_STOP_REQUEST:
290                 {
291                     nr5g_fapi_stop_request(p_phy_instance, (fapi_stop_req_t *)
292                         p_fapi_msg, p_vendor_msg);
293                     nr5g_fapi_statistic_info_print();
294                     if (g_statistic_start_flag == 1)
295                         g_statistic_start_flag = 0;
296                 }
297
298                 break;
299                 /*  P7 Message Processing */
300             case FAPI_DL_TTI_REQUEST:
301                 {
302                     nr5g_fapi_dl_tti_request(p_phy_instance,
303                         (fapi_dl_tti_req_t *)
304                         p_fapi_msg, p_vendor_msg);
305                     if (g_statistic_start_flag == 0)
306                         g_statistic_start_flag = 1;
307                 }
308                 break;
309
310             case FAPI_UL_TTI_REQUEST:
311                 nr5g_fapi_ul_tti_request(p_phy_instance, (fapi_ul_tti_req_t *)
312                     p_fapi_msg, p_vendor_msg);
313                 break;
314
315             case FAPI_UL_DCI_REQUEST:
316                 nr5g_fapi_ul_dci_request(p_phy_instance, (fapi_ul_dci_req_t *)
317                     p_fapi_msg, p_vendor_msg);
318                 break;
319
320             case FAPI_TX_DATA_REQUEST:
321                 nr5g_fapi_tx_data_request(p_phy_instance, (fapi_tx_data_req_t *)
322                     p_fapi_msg, p_vendor_msg);
323                 p_msg_list->p_tx_data_elm_list = NULL;
324                 break;
325
326             default:
327                 break;
328         }
329         p_msg_list = p_msg_list->p_next;
330     }
331 }
332
333 uint8_t nr5g_fapi_check_api_ordering(
334     p_nr5g_fapi_phy_instance_t p_phy_instance,
335     p_fapi_api_queue_elem_t p_msg_list)
336 {
337     uint16_t msg_id, api_order_check = FAPI_CONFIG_REQUEST;
338     p_fapi_api_queue_elem_t p_msg = p_msg_list;
339     fapi_msg_t *p_fapi_msg = NULL;
340
341     if (p_phy_instance && p_phy_instance->state == FAPI_STATE_RUNNING) {
342         p_fapi_msg = (fapi_msg_t *) (p_msg + 1);
343         msg_id = p_fapi_msg->msg_id;
344         // check if first msg is CONFIG.req
345         if (msg_id == FAPI_CONFIG_REQUEST) {
346             p_msg = p_msg->p_next;
347         }
348         api_order_check = FAPI_DL_TTI_REQUEST;
349         // Continue checking remaining APIs
350         while (p_msg) {
351             p_fapi_msg = (fapi_msg_t *) (p_msg + 1);
352             msg_id = p_fapi_msg->msg_id;
353             if ((msg_id == FAPI_DL_TTI_REQUEST) && (msg_id == api_order_check)) {
354                 api_order_check = FAPI_UL_TTI_REQUEST;
355             } else if ((msg_id == FAPI_UL_TTI_REQUEST) &&
356                 (msg_id == api_order_check)) {
357                 api_order_check = FAPI_UL_DCI_REQUEST;
358             } else {
359                 break;
360             }
361             p_msg = p_msg->p_next;
362         }
363         if (api_order_check != FAPI_UL_DCI_REQUEST) {
364             return FAILURE;
365         }
366     }
367
368     return SUCCESS;
369 }