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"
25 //------------------------------------------------------------------------------
26 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
36 //------------------------------------------------------------------------------
37 void *nr5g_fapi_mac2phy_thread_func(
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;
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 thread = p_phy_ctx->mac2phy_tid = pthread_self();
51 CPU_SET(p_phy_ctx->mac2phy_worker_core_id, &cpuset);
52 pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
55 while (!p_phy_ctx->process_exit) {
56 p_msg_list = nr5g_fapi_fapi2mac_wls_recv();
58 nr5g_fapi_mac2phy_api_recv_handler(config, p_msg_list);
63 //------------------------------------------------------------------------------
64 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
74 //------------------------------------------------------------------------------
75 void nr5g_fapi_mac2phy_api_recv_handler(
77 p_fapi_api_queue_elem_t p_msg_list)
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;
84 p_nr5g_fapi_phy_ctx_t p_phy_ctx = NULL;
85 p_nr5g_fapi_phy_instance_t p_phy_instance = NULL;
89 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] %s:", __func__));
90 p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
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;
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",
103 // skip to next carrier list. since current fapi message hearder
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;
111 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
117 // walk through the list and disconnet per carrier apis
118 if (p_msg_list->p_next) {
119 p_prev_elm = p_msg_list;
121 if (FAPI_MSG_HEADER_IND == p_msg_list->msg_type) {
122 p_prev_elm->p_next = NULL;
125 p_prev_elm = p_msg_list;
126 p_msg_list = p_msg_list->p_next;
132 if (phy_id > FAPI_MAX_PHY_INSTANCES) {
133 NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY]: Invalid Phy Id: %d\n",
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));
149 p_phy_instance->phy_id = phy_id;
152 nr5g_fapi_mac2phy_api_processing_handler(p_phy_instance,
153 p_per_carr_api_list);
154 p_per_carr_api_list = NULL;
158 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Send to PHY.."));
159 nr5g_fapi_fapi2phy_send_api_list();
162 //------------------------------------------------------------------------------
163 /** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
165 * @param[in,out] void
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)
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;
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"));
198 p_vendor_msg = (fapi_vendor_msg_t *) p_fapi_msg;
199 NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Vendor Msg: %p\n",
201 // disconnect the vendor element from the api list
202 p_prev_elm->p_next = NULL;
205 p_prev_elm = p_vendor_elm;
206 p_vendor_elm = p_vendor_elm->p_next;
209 // split the tx_data_request pdus
210 p_curr_elm = p_msg_list;
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;
220 p_tx_data_pdu_list_tail = p_tx_data_pdu_list = p_curr_elm;
224 p_curr_elm = p_curr_elm->p_next;
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;
231 // Walk through the API list
233 p_fapi_msg = (fapi_msg_t *) (p_msg_list + 1);
234 switch (p_fapi_msg->msg_id) {
235 /* P5 Vendor Message Processing */
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);
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);
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);
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);
259 case FAPI_START_REQUEST:
260 nr5g_fapi_start_request(p_phy_instance, (fapi_start_req_t *)
261 p_fapi_msg, p_vendor_msg);
264 case FAPI_STOP_REQUEST:
265 nr5g_fapi_stop_request(p_phy_instance, (fapi_stop_req_t *)
266 p_fapi_msg, p_vendor_msg);
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);
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);
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);
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;
294 p_msg_list = p_msg_list->p_next;