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 *******************************************************************************/
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"
26 //------------------------------------------------------------------------------
27 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
37 //------------------------------------------------------------------------------
38 void *nr5g_fapi_mac2phy_thread_func(
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;
47 NR5G_FAPI_LOG(INFO_LOG, ("[MAC2PHY] Thread %s launched LWP:%ld on "
48 "Core: %d\n", __func__, pthread_self(),
49 p_phy_ctx->mac2phy_worker_core_id));
51 thread = p_phy_ctx->mac2phy_tid = pthread_self();
53 CPU_SET(p_phy_ctx->mac2phy_worker_core_id, &cpuset);
54 pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
57 while (!p_phy_ctx->process_exit) {
58 p_msg_list = nr5g_fapi_fapi2mac_wls_recv();
60 nr5g_fapi_mac2phy_api_recv_handler(false, config, p_msg_list);
62 start_tick = __rdtsc();
63 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Send to PHY.."));
64 nr5g_fapi_fapi2phy_send_api_list(0);
65 tick_total_wls_send_per_tti_dl += __rdtsc() - start_tick;
70 //------------------------------------------------------------------------------
71 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
81 //------------------------------------------------------------------------------
82 void nr5g_fapi_mac2phy_api_recv_handler(
85 p_fapi_api_queue_elem_t p_msg_list)
87 p_fapi_api_queue_elem_t p_per_carr_api_list = NULL;
88 p_fapi_api_queue_elem_t p_prev_elm = NULL;
89 fapi_msg_t *p_fapi_msg = NULL;
90 p_fapi_msg_header_t p_fapi_msg_header = NULL;
92 p_nr5g_fapi_phy_ctx_t p_phy_ctx = NULL;
93 p_nr5g_fapi_phy_instance_t p_phy_instance = NULL;
96 uint64_t start_tick = __rdtsc();
98 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] %s:", __func__));
99 p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
101 p_per_carr_api_list = p_msg_list;
102 p_fapi_msg_header = (fapi_msg_header_t *) (p_per_carr_api_list + 1);
103 num_apis = p_fapi_msg_header->num_msg;
104 phy_id = p_fapi_msg_header->handle;
106 if (num_apis > 0 && p_msg_list->p_next) { // likely
107 p_per_carr_api_list = p_per_carr_api_list->p_next;
108 p_msg_list = p_per_carr_api_list;
109 NR5G_FAPI_LOG(TRACE_LOG, ("\n[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
112 // skip to next carrier list. since current fapi message hearder
114 if (p_msg_list->p_next) {
115 NR5G_FAPI_LOG(TRACE_LOG, ("\n[MAC2PHY] No APIs for PHY_ID: %d."
116 " Skip...\n", phy_id));
117 p_msg_list = p_msg_list->p_next;
120 NR5G_FAPI_LOG(ERROR_LOG, ("\n[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
126 // walk through the list and disconnet per carrier apis
127 if (p_msg_list->p_next) {
128 p_prev_elm = p_msg_list;
130 if (FAPI_VENDOR_MSG_HEADER_IND == p_msg_list->msg_type) {
131 p_prev_elm->p_next = NULL;
134 p_prev_elm = p_msg_list;
135 p_msg_list = p_msg_list->p_next;
141 if (phy_id > FAPI_MAX_PHY_INSTANCES) {
142 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY]: Invalid Phy Id: %d\n",
147 if (p_per_carr_api_list) {
148 p_fapi_msg = (fapi_msg_t *) (p_per_carr_api_list + 1);
150 if ((p_fapi_msg->msg_id != FAPI_VENDOR_EXT_UL_IQ_SAMPLES) &&
151 (p_fapi_msg->msg_id != FAPI_VENDOR_EXT_ADD_REMOVE_CORE)) {
153 p_phy_instance = &p_phy_ctx->phy_instance[phy_id];
154 if (FAPI_STATE_IDLE == p_phy_instance->state) {
155 if (p_fapi_msg->msg_id != FAPI_CONFIG_REQUEST) {
156 NR5G_FAPI_LOG(ERROR_LOG,
157 ("CONFIG.request is not received "
158 "for %d PHY Instance\n", phy_id));
161 p_phy_instance->phy_id = phy_id;
167 nr5g_fapi_mac2phy_api_processing_handler(is_urllc, p_phy_instance,
168 p_per_carr_api_list);
169 p_per_carr_api_list = NULL;
172 tick_total_parse_per_tti_dl += __rdtsc() - start_tick;
175 //------------------------------------------------------------------------------
176 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
178 * @param[in,out] void
186 //------------------------------------------------------------------------------
187 void nr5g_fapi_mac2phy_api_processing_handler(
189 p_nr5g_fapi_phy_instance_t p_phy_instance,
190 p_fapi_api_queue_elem_t p_msg_list)
193 p_fapi_api_queue_elem_t p_vendor_elm = NULL;
194 p_fapi_api_queue_elem_t p_prev_elm = NULL;
195 p_fapi_api_queue_elem_t p_curr_elm = NULL;
196 p_fapi_api_queue_elem_t p_tx_data_elm = NULL;
197 p_fapi_api_queue_elem_t p_tx_data_pdu_list = NULL;
198 p_fapi_api_queue_elem_t p_tx_data_pdu_list_tail = NULL;
199 fapi_msg_t *p_fapi_msg = NULL;
200 fapi_vendor_msg_t *p_vendor_msg = NULL;
202 // Get vendor body if present
203 p_prev_elm = p_vendor_elm = p_msg_list;
204 while (p_vendor_elm) {
205 p_fapi_msg = (fapi_msg_t *) (p_vendor_elm + 1);
206 if (p_fapi_msg->msg_id == FAPI_VENDOR_MESSAGE) {
207 if (p_prev_elm == p_vendor_elm) {
208 NR5G_FAPI_LOG(ERROR_LOG,
209 ("[MAC2PHY] Received only Vendor Message"));
212 p_vendor_msg = (fapi_vendor_msg_t *) p_fapi_msg;
213 NR5G_FAPI_LOG(DEBUG_LOG, ("[MAC2PHY] P7 Vendor Msg: %p",
215 // disconnect the vendor element from the api list
216 p_prev_elm->p_next = NULL;
219 p_prev_elm = p_vendor_elm;
220 p_vendor_elm = p_vendor_elm->p_next;
223 // split the tx_data_request pdus
224 p_curr_elm = p_msg_list;
226 msg_type = p_curr_elm->msg_type;
227 if (msg_type == FAPI_TX_DATA_REQUEST) {
228 p_tx_data_elm = p_curr_elm;
229 } else if (msg_type == FAPI_VENDOR_MSG_PHY_ZBC_BLOCK_REQ) {
230 if (p_tx_data_pdu_list) {
231 p_tx_data_pdu_list_tail->p_next = p_curr_elm;
232 p_tx_data_pdu_list_tail = p_tx_data_pdu_list_tail->p_next;
234 p_tx_data_pdu_list_tail = p_tx_data_pdu_list = p_curr_elm;
238 p_curr_elm = p_curr_elm->p_next;
241 if (p_tx_data_pdu_list && p_tx_data_elm) {
242 p_tx_data_elm->p_tx_data_elm_list = p_tx_data_pdu_list;
243 p_tx_data_elm->p_next = NULL;
246 if (FAILURE == nr5g_fapi_check_api_ordering(p_phy_instance, p_msg_list)) {
247 NR5G_FAPI_LOG(ERROR_LOG, ("API Ordering is wrong."));
250 // Walk through the API list
252 p_fapi_msg = (fapi_msg_t *) (p_msg_list + 1);
253 switch (p_fapi_msg->msg_id) {
254 /* P5 Vendor Message Processing */
256 case FAPI_VENDOR_EXT_ADD_REMOVE_CORE:
257 nr5g_fapi_add_remove_core_message(is_urllc,
258 (fapi_vendor_ext_add_remove_core_msg_t *) p_fapi_msg);
260 case FAPI_VENDOR_EXT_UL_IQ_SAMPLES:
261 nr5g_fapi_ul_iq_samples_request(is_urllc,
262 (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
265 case FAPI_VENDOR_EXT_DL_IQ_SAMPLES:
266 nr5g_fapi_dl_iq_samples_request(is_urllc,
267 (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
271 case FAPI_VENDOR_EXT_SHUTDOWN_REQUEST:
273 nr5g_fapi_shutdown_request(is_urllc, p_phy_instance,
274 (fapi_vendor_ext_shutdown_req_t *) p_fapi_msg);
275 nr5g_fapi_statistic_info_print();
276 if (g_statistic_start_flag == 1)
277 g_statistic_start_flag = 0;
281 /* P5 Message Processing */
282 case FAPI_CONFIG_REQUEST:
284 nr5g_fapi_config_request(is_urllc, p_phy_instance,
285 (fapi_config_req_t *)
286 p_fapi_msg, p_vendor_msg);
287 nr5g_fapi_statistic_info_init();
292 case FAPI_START_REQUEST:
293 nr5g_fapi_start_request(is_urllc, p_phy_instance, (fapi_start_req_t *)
294 p_fapi_msg, p_vendor_msg);
297 case FAPI_STOP_REQUEST:
299 nr5g_fapi_stop_request(is_urllc, p_phy_instance, (fapi_stop_req_t *)
300 p_fapi_msg, p_vendor_msg);
301 nr5g_fapi_statistic_info_print();
302 if (g_statistic_start_flag == 1)
303 g_statistic_start_flag = 0;
307 /* P7 Message Processing */
308 case FAPI_DL_TTI_REQUEST:
310 nr5g_fapi_dl_tti_request(is_urllc, p_phy_instance,
311 (fapi_dl_tti_req_t *)
312 p_fapi_msg, p_vendor_msg);
313 if (g_statistic_start_flag == 0)
314 g_statistic_start_flag = 1;
318 case FAPI_UL_TTI_REQUEST:
319 nr5g_fapi_ul_tti_request(is_urllc, p_phy_instance, (fapi_ul_tti_req_t *)
320 p_fapi_msg, p_vendor_msg);
323 case FAPI_UL_DCI_REQUEST:
324 nr5g_fapi_ul_dci_request(is_urllc, p_phy_instance, (fapi_ul_dci_req_t *)
325 p_fapi_msg, p_vendor_msg);
328 case FAPI_TX_DATA_REQUEST:
329 nr5g_fapi_tx_data_request(is_urllc, p_phy_instance, (fapi_tx_data_req_t *)
330 p_fapi_msg, p_vendor_msg);
331 p_msg_list->p_tx_data_elm_list = NULL;
335 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY THREAD] Received Unknown Message: [msg_id = 0x%x]",
336 p_fapi_msg->msg_id));
339 p_msg_list = p_msg_list->p_next;
343 uint8_t nr5g_fapi_check_api_ordering(
344 p_nr5g_fapi_phy_instance_t p_phy_instance,
345 p_fapi_api_queue_elem_t p_msg_list)
347 uint16_t msg_id, api_order_check = FAPI_CONFIG_REQUEST;
348 p_fapi_api_queue_elem_t p_msg = p_msg_list;
349 fapi_msg_t *p_fapi_msg = NULL;
351 if (p_phy_instance && p_phy_instance->state == FAPI_STATE_RUNNING) {
352 p_fapi_msg = (fapi_msg_t *) (p_msg + 1);
353 msg_id = p_fapi_msg->msg_id;
354 // check if first msg is CONFIG.req
355 if (msg_id == FAPI_CONFIG_REQUEST) {
356 p_msg = p_msg->p_next;
358 api_order_check = FAPI_DL_TTI_REQUEST;
359 // Continue checking remaining APIs
361 p_fapi_msg = (fapi_msg_t *) (p_msg + 1);
362 msg_id = p_fapi_msg->msg_id;
363 if ((msg_id == FAPI_DL_TTI_REQUEST) && (msg_id == api_order_check)) {
364 api_order_check = FAPI_UL_TTI_REQUEST;
365 } else if ((msg_id == FAPI_UL_TTI_REQUEST) &&
366 (msg_id == api_order_check)) {
367 api_order_check = FAPI_UL_DCI_REQUEST;
371 p_msg = p_msg->p_next;
373 if (api_order_check != FAPI_UL_DCI_REQUEST) {