FAPI TM, WLS_LIB and ODULOW documentation
[o-du/phy.git] / fapi_5g / source / framework / workers / nr5g_fapi_mac2phy_thread.c
diff --git a/fapi_5g/source/framework/workers/nr5g_fapi_mac2phy_thread.c b/fapi_5g/source/framework/workers/nr5g_fapi_mac2phy_thread.c
new file mode 100644 (file)
index 0000000..2c7de23
--- /dev/null
@@ -0,0 +1,296 @@
+/******************************************************************************
+*
+*   Copyright (c) 2019 Intel.
+*
+*   Licensed under the Apache License, Version 2.0 (the "License");
+*   you may not use this file except in compliance with the License.
+*   You may obtain a copy of the License at
+*
+*       http://www.apache.org/licenses/LICENSE-2.0
+*
+*   Unless required by applicable law or agreed to in writing, software
+*   distributed under the License is distributed on an "AS IS" BASIS,
+*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*   See the License for the specific language governing permissions and
+*   limitations under the License.
+*
+*******************************************************************************/
+#include "nr5g_fapi_std.h"
+#include "nr5g_fapi_mac2phy_thread.h"
+#include "nr5g_fapi_fapi2mac_wls.h"
+#include "nr5g_fapi_fapi2phy_api.h"
+#include "nr5g_fapi_fapi2phy_p5_proc.h"
+#include "nr5g_fapi_fapi2phy_p7_proc.h"
+
+//------------------------------------------------------------------------------
+/** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
+ *
+ *  @param[in,out]   void
+ *
+ *  @return none
+ *
+ *  @description
+ *  DOXYGEN_TO_DO
+ *
+**/
+//------------------------------------------------------------------------------
+void *nr5g_fapi_mac2phy_thread_func(
+    void *config)
+{
+    cpu_set_t cpuset;
+    pthread_t thread;
+    p_fapi_api_queue_elem_t p_msg_list = NULL;
+    p_nr5g_fapi_phy_ctx_t p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
+
+    NR5G_FAPI_LOG(INFO_LOG, ("[MAC2PHY] Thread %s launched LWP:%ld on "
+            "Core: %d\n", __func__, pthread_self(),
+            p_phy_ctx->mac2phy_worker_core_id));
+
+    thread = p_phy_ctx->mac2phy_tid = pthread_self();
+    CPU_ZERO(&cpuset);
+    CPU_SET(p_phy_ctx->mac2phy_worker_core_id, &cpuset);
+    pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
+
+    usleep(1000);
+    while (!p_phy_ctx->process_exit) {
+        p_msg_list = nr5g_fapi_fapi2mac_wls_recv();
+        if (p_msg_list)
+            nr5g_fapi_mac2phy_api_recv_handler(config, p_msg_list);
+    }
+    pthread_exit(NULL);
+}
+
+//------------------------------------------------------------------------------
+/** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
+ *
+ *  @param[in,out]   void
+ *
+ *  @return none
+ *
+ *  @description
+ *  DOXYGEN_TO_DO
+ *
+**/
+//------------------------------------------------------------------------------
+void nr5g_fapi_mac2phy_api_recv_handler(
+    void *config,
+    p_fapi_api_queue_elem_t p_msg_list)
+{
+    p_fapi_api_queue_elem_t p_per_carr_api_list = NULL;
+    p_fapi_api_queue_elem_t p_prev_elm = NULL;
+    fapi_msg_t *p_fapi_msg = NULL;
+    p_fapi_msg_header_t p_fapi_msg_header = NULL;
+
+    p_nr5g_fapi_phy_ctx_t p_phy_ctx = NULL;
+    p_nr5g_fapi_phy_instance_t p_phy_instance = NULL;
+    uint8_t num_apis = 0;
+    uint8_t phy_id = 0;
+
+    NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] %s:", __func__));
+    p_phy_ctx = (p_nr5g_fapi_phy_ctx_t) config;
+    while (p_msg_list) {
+        p_per_carr_api_list = p_msg_list;
+        p_fapi_msg_header = (fapi_msg_header_t *) (p_per_carr_api_list + 1);
+        num_apis = p_fapi_msg_header->num_msg;
+        phy_id = p_fapi_msg_header->handle;
+
+        if (num_apis > 0 && p_msg_list->p_next) {   // likely
+            p_per_carr_api_list = p_per_carr_api_list->p_next;
+            p_msg_list = p_per_carr_api_list;
+            NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
+                    phy_id, num_apis));
+        } else {                // unlikely
+            // skip to next carrier list. since current fapi message hearder
+            // has no apis
+            if (p_msg_list->p_next) {
+                NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] No APIs for PHY_ID: %d."
+                        " Skip...\n", phy_id));
+                p_msg_list = p_msg_list->p_next;
+                continue;
+            } else {
+                NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY] PHY_ID: %d NUM APIs: %d\n",
+                        phy_id, num_apis));
+                return;
+            }
+        }
+
+        // walk through the list and disconnet per carrier apis
+        if (p_msg_list->p_next) {
+            p_prev_elm = p_msg_list;
+            while (p_msg_list) {
+                if (FAPI_MSG_HEADER_IND == p_msg_list->msg_type) {
+                    p_prev_elm->p_next = NULL;
+                    break;
+                }
+                p_prev_elm = p_msg_list;
+                p_msg_list = p_msg_list->p_next;
+            }
+        } else {
+            p_msg_list = NULL;
+        }
+
+        if (phy_id > FAPI_MAX_PHY_INSTANCES) {
+            NR5G_FAPI_LOG(ERROR_LOG, ("[MAC2PHY]: Invalid Phy Id: %d\n",
+                    phy_id));
+            continue;
+        }
+
+        if (p_per_carr_api_list) {
+            p_fapi_msg = (fapi_msg_t *) (p_per_carr_api_list + 1);
+            if ((p_fapi_msg->msg_id != FAPI_VENDOR_EXT_UL_IQ_SAMPLES)) {
+                p_phy_instance = &p_phy_ctx->phy_instance[phy_id];
+                if (FAPI_STATE_IDLE == p_phy_instance->state) {
+                    if (p_fapi_msg->msg_id != FAPI_CONFIG_REQUEST) {
+                        NR5G_FAPI_LOG(ERROR_LOG,
+                            ("CONFIG.request is not received "
+                                "for %d PHY Instance\n", phy_id));
+                        continue;
+                    }
+                    p_phy_instance->phy_id = phy_id;
+                }
+            }
+            nr5g_fapi_mac2phy_api_processing_handler(p_phy_instance,
+                p_per_carr_api_list);
+            p_per_carr_api_list = NULL;
+        }
+    }
+    // Send to PHY
+    NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Send to PHY.."));
+    nr5g_fapi_fapi2phy_send_api_list();
+}
+
+//------------------------------------------------------------------------------
+/** @ingroup nr5g_fapi_source_framework_workers_mac2phy_group
+ *
+ *  @param[in,out]   void
+ *
+ *  @return none
+ *
+ *  @description
+ *  DOXYGEN_TO_DO
+ *
+**/
+//------------------------------------------------------------------------------
+void nr5g_fapi_mac2phy_api_processing_handler(
+    p_nr5g_fapi_phy_instance_t p_phy_instance,
+    p_fapi_api_queue_elem_t p_msg_list)
+{
+    uint16_t msg_type;
+    p_fapi_api_queue_elem_t p_vendor_elm = NULL;
+    p_fapi_api_queue_elem_t p_prev_elm = NULL;
+    p_fapi_api_queue_elem_t p_curr_elm = NULL;
+    p_fapi_api_queue_elem_t p_tx_data_elm = NULL;
+    p_fapi_api_queue_elem_t p_tx_data_pdu_list = NULL;
+    p_fapi_api_queue_elem_t p_tx_data_pdu_list_tail = NULL;
+    fapi_msg_t *p_fapi_msg = NULL;
+    fapi_vendor_msg_t *p_vendor_msg = NULL;
+
+    // Get vendor body if present
+    p_prev_elm = p_vendor_elm = p_msg_list;
+    while (p_vendor_elm) {
+        p_fapi_msg = (fapi_msg_t *) (p_vendor_elm + 1);
+        if (p_fapi_msg->msg_id == FAPI_VENDOR_MESSAGE) {
+            if (p_prev_elm == p_vendor_elm) {
+                NR5G_FAPI_LOG(ERROR_LOG,
+                    ("[MAC2PHY] Received only Vendor Message"));
+                return;
+            }
+            p_vendor_msg = (fapi_vendor_msg_t *) p_fapi_msg;
+            NR5G_FAPI_LOG(TRACE_LOG, ("[MAC2PHY] Vendor Msg: %p\n",
+                    p_vendor_msg));
+            // disconnect the vendor element from the api list
+            p_prev_elm->p_next = NULL;
+            break;
+        }
+        p_prev_elm = p_vendor_elm;
+        p_vendor_elm = p_vendor_elm->p_next;
+    }
+
+    // split the tx_data_request pdus
+    p_curr_elm = p_msg_list;
+    while (p_curr_elm) {
+        msg_type = p_curr_elm->msg_type;
+        if (msg_type == FAPI_TX_DATA_REQUEST) {
+            p_tx_data_elm = p_curr_elm;
+        } else if (msg_type == FAPI_MSG_PHY_ZBC_BLOCK_REQ) {
+            if (p_tx_data_pdu_list) {
+                p_tx_data_pdu_list_tail->p_next = p_curr_elm;
+                p_tx_data_pdu_list_tail = p_tx_data_pdu_list_tail->p_next;
+            } else {
+                p_tx_data_pdu_list_tail = p_tx_data_pdu_list = p_curr_elm;
+            }
+        } else {
+        }
+        p_curr_elm = p_curr_elm->p_next;
+    }
+
+    if (p_tx_data_pdu_list && p_tx_data_elm) {
+        p_tx_data_elm->p_tx_data_elm_list = p_tx_data_pdu_list;
+        p_tx_data_elm->p_next = NULL;
+    }
+    // Walk through the API list
+    while (p_msg_list) {
+        p_fapi_msg = (fapi_msg_t *) (p_msg_list + 1);
+        switch (p_fapi_msg->msg_id) {
+                /*  P5 Vendor Message Processing */
+#ifdef DEBUG_MODE
+            case FAPI_VENDOR_EXT_UL_IQ_SAMPLES:
+                nr5g_fapi_ul_iq_samples_request(
+                    (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
+                break;
+
+            case FAPI_VENDOR_EXT_DL_IQ_SAMPLES:
+                nr5g_fapi_dl_iq_samples_request(
+                    (fapi_vendor_ext_iq_samples_req_t *) p_fapi_msg);
+                break;
+
+#endif
+            case FAPI_VENDOR_EXT_SHUTDOWN_REQUEST:
+                nr5g_fapi_shutdown_request(p_phy_instance,
+                    (fapi_vendor_ext_shutdown_req_t *) p_fapi_msg);
+                break;
+
+                /*  P5 Message Processing */
+            case FAPI_CONFIG_REQUEST:
+                nr5g_fapi_config_request(p_phy_instance, (fapi_config_req_t *)
+                    p_fapi_msg, p_vendor_msg);
+                break;
+
+            case FAPI_START_REQUEST:
+                nr5g_fapi_start_request(p_phy_instance, (fapi_start_req_t *)
+                    p_fapi_msg, p_vendor_msg);
+                break;
+
+            case FAPI_STOP_REQUEST:
+                nr5g_fapi_stop_request(p_phy_instance, (fapi_stop_req_t *)
+                    p_fapi_msg, p_vendor_msg);
+                break;
+
+                /*  P7 Message Processing */
+            case FAPI_DL_TTI_REQUEST:
+                nr5g_fapi_dl_tti_request(p_phy_instance, (fapi_dl_tti_req_t *)
+                    p_fapi_msg, p_vendor_msg);
+                break;
+
+            case FAPI_UL_TTI_REQUEST:
+                nr5g_fapi_ul_tti_request(p_phy_instance, (fapi_ul_tti_req_t *)
+                    p_fapi_msg, p_vendor_msg);
+                break;
+
+            case FAPI_UL_DCI_REQUEST:
+                nr5g_fapi_ul_dci_request(p_phy_instance, (fapi_ul_dci_req_t *)
+                    p_fapi_msg, p_vendor_msg);
+                break;
+
+            case FAPI_TX_DATA_REQUEST:
+                nr5g_fapi_tx_data_request(p_phy_instance, (fapi_tx_data_req_t *)
+                    p_fapi_msg, p_vendor_msg);
+                p_msg_list->p_tx_data_elm_list = NULL;
+                break;
+
+            default:
+                break;
+        }
+        p_msg_list = p_msg_list->p_next;
+    }
+}