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;
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));
50 thread = p_phy_ctx->mac2phy_tid = pthread_self();
52 CPU_SET(p_phy_ctx->mac2phy_worker_core_id, &cpuset);
53 pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
56 while (!p_phy_ctx->process_exit) {
57 p_msg_list = nr5g_fapi_fapi2mac_wls_recv();
59 nr5g_fapi_mac2phy_api_recv_handler(config, p_msg_list);
64 //------------------------------------------------------------------------------
65 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
75 //------------------------------------------------------------------------------
76 void nr5g_fapi_mac2phy_api_recv_handler(
78 p_fapi_api_queue_elem_t p_msg_list)
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;
85 p_nr5g_fapi_phy_ctx_t p_phy_ctx = NULL;
86 p_nr5g_fapi_phy_instance_t p_phy_instance = NULL;
89 uint64_t start_tick = __rdtsc();
91 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] %s:", __func__));
92 p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
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;
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",
105 // skip to next carrier list. since current fapi message hearder
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;
113 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
119 // walk through the list and disconnet per carrier apis
120 if (p_msg_list->p_next) {
121 p_prev_elm = p_msg_list;
123 if (FAPI_VENDOR_MSG_HEADER_IND == p_msg_list->msg_type) {
124 p_prev_elm->p_next = NULL;
127 p_prev_elm = p_msg_list;
128 p_msg_list = p_msg_list->p_next;
134 if (phy_id > FAPI_MAX_PHY_INSTANCES) {
135 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY]: Invalid Phy Id: %d\n",
140 if (p_per_carr_api_list) {
141 p_fapi_msg = (fapi_msg_t *) (p_per_carr_api_list + 1);
143 if ((p_fapi_msg->msg_id != FAPI_VENDOR_EXT_UL_IQ_SAMPLES)) {
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));
153 p_phy_instance->phy_id = phy_id;
158 nr5g_fapi_mac2phy_api_processing_handler(p_phy_instance,
159 p_per_carr_api_list);
160 p_per_carr_api_list = NULL;
163 tick_total_parse_per_tti_dl += __rdtsc() - start_tick;
164 start_tick = __rdtsc();
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;
172 //------------------------------------------------------------------------------
173 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
175 * @param[in,out] void
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)
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;
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"));
208 p_vendor_msg = (fapi_vendor_msg_t *) p_fapi_msg;
209 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Vendor Msg: %p\n",
211 // disconnect the vendor element from the api list
212 p_prev_elm->p_next = NULL;
215 p_prev_elm = p_vendor_elm;
216 p_vendor_elm = p_vendor_elm->p_next;
219 // split the tx_data_request pdus
220 p_curr_elm = p_msg_list;
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;
230 p_tx_data_pdu_list_tail = p_tx_data_pdu_list = p_curr_elm;
234 p_curr_elm = p_curr_elm->p_next;
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;
242 if (FAILURE == nr5g_fapi_check_api_ordering(p_phy_instance, p_msg_list)) {
243 NR5G_FAPI_LOG(ERROR_LOG, ("API Ordering is wrong."));
246 // Walk through the API list
248 p_fapi_msg = (fapi_msg_t *) (p_msg_list + 1);
249 switch (p_fapi_msg->msg_id) {
250 /* P5 Vendor Message Processing */
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);
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);
263 case FAPI_VENDOR_EXT_SHUTDOWN_REQUEST:
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;
273 /* P5 Message Processing */
274 case FAPI_CONFIG_REQUEST:
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();
284 case FAPI_START_REQUEST:
285 nr5g_fapi_start_request(p_phy_instance, (fapi_start_req_t *)
286 p_fapi_msg, p_vendor_msg);
289 case FAPI_STOP_REQUEST:
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;
299 /* P7 Message Processing */
300 case FAPI_DL_TTI_REQUEST:
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;
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);
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);
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;
329 p_msg_list = p_msg_list->p_next;
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)
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;
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;
348 api_order_check = FAPI_DL_TTI_REQUEST;
349 // Continue checking remaining APIs
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;
361 p_msg = p_msg->p_next;
363 if (api_order_check != FAPI_UL_DCI_REQUEST) {