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 *******************************************************************************/
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(
41 p_fapi_api_queue_elem_t p_msg_list = NULL;
42 p_nr5g_fapi_phy_ctx_t p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
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));
49 nr5g_fapi_init_thread(p_phy_ctx->mac2phy_worker_core_id);
51 while (!p_phy_ctx->process_exit) {
52 p_msg_list = nr5g_fapi_fapi2mac_wls_recv();
54 nr5g_fapi_mac2phy_api_recv_handler(false, config, p_msg_list);
56 start_tick = __rdtsc();
57 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Send to PHY.."));
58 nr5g_fapi_fapi2phy_send_api_list(0);
59 tick_total_wls_send_per_tti_dl += __rdtsc() - start_tick;
64 //------------------------------------------------------------------------------
65 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
75 //------------------------------------------------------------------------------
76 void nr5g_fapi_mac2phy_api_recv_handler(
79 p_fapi_api_queue_elem_t p_msg_list)
81 p_fapi_api_queue_elem_t p_per_carr_api_list = NULL;
82 p_fapi_api_queue_elem_t p_prev_elm = NULL;
83 fapi_msg_t *p_fapi_msg = NULL;
84 p_fapi_msg_header_t p_fapi_msg_header = NULL;
86 p_nr5g_fapi_phy_ctx_t p_phy_ctx = NULL;
87 p_nr5g_fapi_phy_instance_t p_phy_instance = NULL;
90 uint64_t start_tick = __rdtsc();
92 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] %s:", __func__));
93 p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
95 p_per_carr_api_list = p_msg_list;
96 p_fapi_msg_header = (fapi_msg_header_t *) (p_per_carr_api_list + 1);
97 num_apis = p_fapi_msg_header->num_msg;
98 phy_id = p_fapi_msg_header->handle;
100 if (num_apis > 0 && p_msg_list->p_next) { // likely
101 p_per_carr_api_list = p_per_carr_api_list->p_next;
102 p_msg_list = p_per_carr_api_list;
103 NR5G_FAPI_LOG(TRACE_LOG, ("\n[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
106 // skip to next carrier list. since current fapi message hearder
108 if (p_msg_list->p_next) {
109 NR5G_FAPI_LOG(TRACE_LOG, ("\n[MAC2PHY] No APIs for PHY_ID: %d."
110 " Skip...\n", phy_id));
111 p_msg_list = p_msg_list->p_next;
114 NR5G_FAPI_LOG(ERROR_LOG, ("\n[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
120 // walk through the list and disconnet per carrier apis
121 if (p_msg_list->p_next) {
122 p_prev_elm = p_msg_list;
124 if (FAPI_VENDOR_MSG_HEADER_IND == p_msg_list->msg_type) {
125 p_prev_elm->p_next = NULL;
128 p_prev_elm = p_msg_list;
129 p_msg_list = p_msg_list->p_next;
135 if (phy_id > FAPI_MAX_PHY_INSTANCES) {
136 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY]: Invalid Phy Id: %d\n",
141 if (p_per_carr_api_list) {
142 p_fapi_msg = (fapi_msg_t *) (p_per_carr_api_list + 1);
144 if ((p_fapi_msg->msg_id != FAPI_VENDOR_EXT_UL_IQ_SAMPLES) &&
145 (p_fapi_msg->msg_id != FAPI_VENDOR_EXT_ADD_REMOVE_CORE)) {
147 p_phy_instance = &p_phy_ctx->phy_instance[phy_id];
148 if (FAPI_STATE_IDLE == p_phy_instance->state) {
149 if (p_fapi_msg->msg_id != FAPI_CONFIG_REQUEST) {
150 NR5G_FAPI_LOG(ERROR_LOG,
151 ("CONFIG.request is not received "
152 "for %d PHY Instance\n", phy_id));
155 p_phy_instance->phy_id = phy_id;
161 nr5g_fapi_mac2phy_api_processing_handler(is_urllc, p_phy_instance,
162 p_per_carr_api_list);
163 p_per_carr_api_list = NULL;
166 tick_total_parse_per_tti_dl += __rdtsc() - start_tick;
169 //------------------------------------------------------------------------------
170 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
172 * @param[in,out] void
180 //------------------------------------------------------------------------------
181 void nr5g_fapi_mac2phy_api_processing_handler(
183 p_nr5g_fapi_phy_instance_t p_phy_instance,
184 p_fapi_api_queue_elem_t p_msg_list)
187 p_fapi_api_queue_elem_t p_vendor_elm = NULL;
188 p_fapi_api_queue_elem_t p_prev_elm = NULL;
189 p_fapi_api_queue_elem_t p_curr_elm = NULL;
190 p_fapi_api_queue_elem_t p_tx_data_elm = NULL;
191 p_fapi_api_queue_elem_t p_tx_data_pdu_list = NULL;
192 p_fapi_api_queue_elem_t p_tx_data_pdu_list_tail = NULL;
193 fapi_msg_t *p_fapi_msg = NULL;
194 fapi_vendor_msg_t *p_vendor_msg = NULL;
196 // Get vendor body if present
197 p_prev_elm = p_vendor_elm = p_msg_list;
198 while (p_vendor_elm) {
199 p_fapi_msg = (fapi_msg_t *) (p_vendor_elm + 1);
200 if (p_fapi_msg->msg_id == FAPI_VENDOR_MESSAGE) {
201 if (p_prev_elm == p_vendor_elm) {
202 NR5G_FAPI_LOG(ERROR_LOG,
203 ("[MAC2PHY] Received only Vendor Message"));
206 p_vendor_msg = (fapi_vendor_msg_t *) p_fapi_msg;
207 NR5G_FAPI_LOG(DEBUG_LOG, ("[MAC2PHY] P7 Vendor Msg: %p",
209 // disconnect the vendor element from the api list
210 p_prev_elm->p_next = NULL;
213 p_prev_elm = p_vendor_elm;
214 p_vendor_elm = p_vendor_elm->p_next;
217 // split the tx_data_request pdus
218 p_curr_elm = p_msg_list;
220 msg_type = p_curr_elm->msg_type;
221 if (msg_type == FAPI_TX_DATA_REQUEST) {
222 p_tx_data_elm = p_curr_elm;
223 } else if (msg_type == FAPI_VENDOR_MSG_PHY_ZBC_BLOCK_REQ) {
224 if (p_tx_data_pdu_list) {
225 p_tx_data_pdu_list_tail->p_next = p_curr_elm;
226 p_tx_data_pdu_list_tail = p_tx_data_pdu_list_tail->p_next;
228 p_tx_data_pdu_list_tail = p_tx_data_pdu_list = p_curr_elm;
232 p_curr_elm = p_curr_elm->p_next;
235 if (p_tx_data_pdu_list && p_tx_data_elm) {
236 p_tx_data_elm->p_tx_data_elm_list = p_tx_data_pdu_list;
237 p_tx_data_elm->p_next = NULL;
240 if (FAILURE == nr5g_fapi_check_api_ordering(p_phy_instance, p_msg_list)) {
241 NR5G_FAPI_LOG(ERROR_LOG, ("API Ordering is wrong."));
244 // Walk through the API list
246 p_fapi_msg = (fapi_msg_t *) (p_msg_list + 1);
247 switch (p_fapi_msg->msg_id) {
248 /* P5 Vendor Message Processing */
250 case FAPI_VENDOR_EXT_ADD_REMOVE_CORE:
251 nr5g_fapi_add_remove_core_message(is_urllc,
252 (fapi_vendor_ext_add_remove_core_msg_t *) p_fapi_msg);
254 case FAPI_VENDOR_EXT_UL_IQ_SAMPLES:
255 nr5g_fapi_ul_iq_samples_request(is_urllc,
256 (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
259 case FAPI_VENDOR_EXT_DL_IQ_SAMPLES:
260 nr5g_fapi_dl_iq_samples_request(is_urllc,
261 (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
265 case FAPI_VENDOR_EXT_SHUTDOWN_REQUEST:
267 nr5g_fapi_shutdown_request(is_urllc, p_phy_instance,
268 (fapi_vendor_ext_shutdown_req_t *) p_fapi_msg);
269 nr5g_fapi_statistic_info_print();
270 if (g_statistic_start_flag == 1)
271 g_statistic_start_flag = 0;
275 /* P5 Message Processing */
277 case FAPI_PARAM_REQUEST:
279 nr5g_fapi_param_response(p_phy_instance);
284 case FAPI_CONFIG_REQUEST:
286 nr5g_fapi_config_request(is_urllc, p_phy_instance,
287 (fapi_config_req_t *)
288 p_fapi_msg, p_vendor_msg);
289 nr5g_fapi_statistic_info_init();
294 case FAPI_START_REQUEST:
295 nr5g_fapi_start_request(is_urllc, p_phy_instance, (fapi_start_req_t *)
296 p_fapi_msg, p_vendor_msg);
299 case FAPI_STOP_REQUEST:
301 nr5g_fapi_stop_request(is_urllc, p_phy_instance, (fapi_stop_req_t *)
302 p_fapi_msg, p_vendor_msg);
303 nr5g_fapi_statistic_info_print();
304 if (g_statistic_start_flag == 1)
305 g_statistic_start_flag = 0;
309 /* P7 Message Processing */
310 case FAPI_DL_TTI_REQUEST:
312 nr5g_fapi_dl_tti_request(is_urllc, p_phy_instance,
313 (fapi_dl_tti_req_t *)
314 p_fapi_msg, p_vendor_msg);
315 if (g_statistic_start_flag == 0)
316 g_statistic_start_flag = 1;
320 case FAPI_UL_TTI_REQUEST:
321 nr5g_fapi_ul_tti_request(is_urllc, p_phy_instance, (fapi_ul_tti_req_t *)
322 p_fapi_msg, p_vendor_msg);
325 case FAPI_UL_DCI_REQUEST:
326 nr5g_fapi_ul_dci_request(is_urllc, p_phy_instance, (fapi_ul_dci_req_t *)
327 p_fapi_msg, p_vendor_msg);
330 case FAPI_TX_DATA_REQUEST:
331 nr5g_fapi_tx_data_request(is_urllc, p_phy_instance, (fapi_tx_data_req_t *)
332 p_fapi_msg, p_vendor_msg);
333 p_msg_list->p_tx_data_elm_list = NULL;
337 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY THREAD] Received Unknown Message: [msg_id = 0x%x]",
338 p_fapi_msg->msg_id));
341 p_msg_list = p_msg_list->p_next;
345 uint8_t nr5g_fapi_check_api_ordering(
346 p_nr5g_fapi_phy_instance_t p_phy_instance,
347 p_fapi_api_queue_elem_t p_msg_list)
349 uint16_t msg_id, api_order_check = FAPI_CONFIG_REQUEST;
350 p_fapi_api_queue_elem_t p_msg = p_msg_list;
351 fapi_msg_t *p_fapi_msg = NULL;
353 if (p_phy_instance && p_phy_instance->state == FAPI_STATE_RUNNING) {
354 p_fapi_msg = (fapi_msg_t *) (p_msg + 1);
355 msg_id = p_fapi_msg->msg_id;
356 // check if first msg is CONFIG.req
357 if (msg_id == FAPI_CONFIG_REQUEST) {
358 p_msg = p_msg->p_next;
360 api_order_check = FAPI_DL_TTI_REQUEST;
361 // Continue checking remaining APIs
363 p_fapi_msg = (fapi_msg_t *) (p_msg + 1);
364 msg_id = p_fapi_msg->msg_id;
365 if ((msg_id == FAPI_DL_TTI_REQUEST) && (msg_id == api_order_check)) {
366 api_order_check = FAPI_UL_TTI_REQUEST;
367 } else if ((msg_id == FAPI_UL_TTI_REQUEST) &&
368 (msg_id == api_order_check)) {
369 api_order_check = FAPI_UL_DCI_REQUEST;
373 p_msg = p_msg->p_next;
375 if (api_order_check != FAPI_UL_DCI_REQUEST) {