* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fapi_5g / source / framework / nr5g_fapi_framework.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2021 Intel.
4 *
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
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 *******************************************************************************/
18 #include "nr5g_fapi_framework.h"
19 #include "nr5g_fapi_wls.h"
20 #include "nr5g_fapi_fapi2mac_wls.h"
21 #include "nr5g_fapi_fapi2phy_wls.h"
22 #include "nr5g_fapi_fapi2phy_api.h"
23 #include "rte_memzone.h"
24 #include "nr5g_fapi_memory.h"
25
26 static nr5g_fapi_phy_ctx_t nr5g_fapi_phy_ctx;
27
28 inline p_nr5g_fapi_phy_ctx_t nr5g_fapi_get_nr5g_fapi_phy_ctx(
29     )
30 {
31     return &nr5g_fapi_phy_ctx;
32 }
33
34 uint8_t nr5g_fapi_dpdk_init(
35     p_nr5g_fapi_cfg_t p_cfg)
36 {
37     printf("init dev name: %s\n", p_cfg->dpdk.memory_zone);
38     char *const file_prefix = basename(p_cfg->dpdk.memory_zone);
39     printf("init basename: %s\n", file_prefix);
40     char whitelist[32], iova_mode[64];
41     uint8_t i;
42
43     char *argv[] = { p_cfg->prgname, "--proc-type=secondary",
44         "--file-prefix", file_prefix, whitelist, iova_mode
45     };
46 #if 0
47     char coremask[32];
48     char *argv[] = { p_cfg->prgname, coremask, "--proc-type=secondary",
49         "--file-prefix", file_prefix, whitelist
50     };
51     snprintf(coremask, 32, "-l %d,%d", p_cfg->mac2phy_worker.core_id,
52         p_cfg->phy2mac_worker.core_id);
53 #endif
54     int argc = RTE_DIM(argv);
55
56     /* initialize EAL first */
57     snprintf(whitelist, 32, "-a%s", "0000:00:06.0");
58
59     if (p_cfg->dpdk.iova_mode == 0)
60         snprintf(iova_mode, 64, "%s", "--iova-mode=pa");
61     else
62         snprintf(iova_mode, 64, "%s", "--iova-mode=va");
63
64     printf("Calling rte_eal_init: ");
65     for (i = 0; i < RTE_DIM(argv); i++) {
66         printf("%s ", argv[i]);
67     }
68     printf("\n");
69
70     if (rte_eal_init(argc, argv) < 0)
71         rte_panic("Cannot init EAL\n");
72
73     return SUCCESS;
74 }
75
76 uint8_t nr5g_fapi_dpdk_wait(
77     p_nr5g_fapi_cfg_t p_cfg)
78 {
79 #if 0
80     uint32_t worker_core;
81     /* wait per-lcore */
82     RTE_LCORE_FOREACH_SLAVE(worker_core) {
83         if (rte_eal_wait_lcore(worker_core) < 0) {
84             return FAILURE;
85         }
86     }
87 #else
88     pthread_join(p_cfg->mac2phy_thread_params.thread_info.thread_id, NULL);
89     pthread_join(p_cfg->phy2mac_thread_params.thread_info.thread_id, NULL);
90     pthread_join(p_cfg->urllc_phy2mac_thread_params.thread_info.thread_id, NULL);
91     pthread_join(p_cfg->urllc_mac2phy_thread_params.thread_info.thread_id, NULL);
92 #endif
93     return SUCCESS;
94 }
95
96 void nr5g_fapi_set_ul_slot_info(
97     uint16_t frame_no,
98     uint16_t slot_no,
99     uint8_t symbol_no,
100     nr5g_fapi_ul_slot_info_t * p_ul_slot_info)
101 {
102     NR5G_FAPI_MEMSET(p_ul_slot_info, sizeof(nr5g_fapi_ul_slot_info_t), 0, sizeof(nr5g_fapi_ul_slot_info_t));
103
104     p_ul_slot_info->cookie = frame_no;
105     p_ul_slot_info->slot_no = slot_no;
106     p_ul_slot_info->symbol_no = symbol_no;
107 }
108
109 nr5g_fapi_ul_slot_info_t *nr5g_fapi_get_ul_slot_info(
110     bool is_urllc,
111     uint16_t frame_no,
112     uint16_t slot_no,
113     uint8_t symbol_no,
114     p_nr5g_fapi_phy_instance_t p_phy_instance)
115 {
116     uint8_t i, j;
117     nr5g_fapi_ul_slot_info_t *p_ul_slot_info;
118
119     for (i = 0; i < MAX_UL_SLOT_INFO_COUNT; i++) {
120         for(j = 0; j < MAX_UL_SYMBOL_INFO_COUNT; j++) {
121             p_ul_slot_info = &p_phy_instance->ul_slot_info[is_urllc][i][j];
122         if ((slot_no == p_ul_slot_info->slot_no) &&
123                 (frame_no == p_ul_slot_info->cookie) &&
124                 (symbol_no == p_ul_slot_info->symbol_no)) {
125             return p_ul_slot_info;
126         }
127     }
128     }
129     return NULL;
130 }
131
132 uint8_t nr5g_fapi_prepare_thread(
133     nr5g_fapi_thread_params_t* thread_params,
134     char* thread_name,
135     void* thread_fun(void*))
136 {
137     struct sched_param param;
138     pthread_attr_t* p_thread_attr = &thread_params->thread_info.thread_attr;
139     pthread_attr_init(p_thread_attr);
140     if (!pthread_attr_getschedparam(p_thread_attr, &param)) {
141         param.sched_priority = thread_params->thread_worker.thread_priority;
142         pthread_attr_setschedparam(p_thread_attr, &param);
143         pthread_attr_setschedpolicy(p_thread_attr, SCHED_FIFO);
144     }
145
146     if (0 != pthread_create(&thread_params->thread_info.thread_id,
147             p_thread_attr, thread_fun, (void *)
148             nr5g_fapi_get_nr5g_fapi_phy_ctx())) {
149         printf("Error: Unable to create threads\n");
150         if (p_thread_attr)
151             pthread_attr_destroy(p_thread_attr);
152         return FAILURE;
153     }
154     pthread_setname_np(thread_params->thread_info.thread_id,
155                        thread_name);
156
157     return SUCCESS;
158 }
159
160 uint8_t nr5g_fapi_initialise_sempahore(
161     nr5g_fapi_urllc_thread_params_t* urllc_thread_params)
162 {
163     memset(&urllc_thread_params->urllc_sem_process, 0, sizeof(sem_t));
164     memset(&urllc_thread_params->urllc_sem_done, 0, sizeof(sem_t));
165      
166     pthread_mutex_init(&urllc_thread_params->lock, NULL);
167     urllc_thread_params->p_urllc_list_elem = NULL;
168     if (0 != sem_init(&urllc_thread_params->urllc_sem_process, 0, 0)) {
169         printf("Error: Unable to init urllc_sem_process semaphore\n");
170         return FAILURE;
171     }
172     if (0 != sem_init(&urllc_thread_params->urllc_sem_done, 0, 1)) {
173         printf("Error: Unable to init urllc_sem_done semaphore\n");
174         return FAILURE;
175     }
176
177     return SUCCESS;
178 }
179
180 void nr5g_fapi_init_thread(uint8_t worker_core_id)
181 {
182     cpu_set_t cpuset;
183     pthread_t thread = pthread_self();
184
185     CPU_ZERO(&cpuset);
186     CPU_SET(worker_core_id, &cpuset);
187     pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
188
189     usleep(1000);  
190 }
191
192 void nr5g_fapi_urllc_thread_callback(
193     void *p_list_elem,
194     nr5g_fapi_urllc_thread_params_t* urllc_params)
195 {
196     if (nr5g_fapi_get_nr5g_fapi_phy_ctx()->is_urllc_enabled){
197         sem_wait(&urllc_params->urllc_sem_done);
198         pthread_mutex_lock(&urllc_params->lock);
199         urllc_params->p_urllc_list_elem = p_list_elem;
200         pthread_mutex_unlock(&urllc_params->lock);
201         sem_post(&urllc_params->urllc_sem_process);
202     }
203     else {
204         NR5G_FAPI_LOG(ERROR_LOG, ("[URLLC] Threads are not running"));
205     }
206 }
207
208 uint8_t nr5g_fapi_framework_init(
209     p_nr5g_fapi_cfg_t p_cfg)
210 {
211     p_nr5g_fapi_phy_ctx_t p_phy_ctx = nr5g_fapi_get_nr5g_fapi_phy_ctx();
212
213     nr5g_fapi_set_log_level(p_cfg->logger.level);
214     // Set up WLS
215     if (FAILURE == nr5g_fapi_wls_init(p_cfg)) {
216         NR5G_FAPI_LOG(ERROR_LOG, ("[FAPI_INT] WLS init Failed"));
217         return FAILURE;
218     }
219     NR5G_FAPI_LOG(INFO_LOG, ("[FAPI_INT] WLS init Successful"));
220
221     p_phy_ctx->phy2mac_worker_core_id = p_cfg->phy2mac_thread_params.thread_worker.core_id;
222     p_phy_ctx->mac2phy_worker_core_id = p_cfg->mac2phy_thread_params.thread_worker.core_id;
223     p_phy_ctx->urllc_phy2mac_worker_core_id = p_cfg->urllc_phy2mac_thread_params.thread_worker.core_id;
224     p_phy_ctx->urllc_mac2phy_worker_core_id = p_cfg->urllc_mac2phy_thread_params.thread_worker.core_id;
225     p_phy_ctx->is_urllc_enabled = p_cfg->is_urllc_enabled;
226
227     if (nr5g_fapi_prepare_thread(&p_cfg->phy2mac_thread_params,
228                                  "nr5g_fapi_phy2mac_thread",
229                                  nr5g_fapi_phy2mac_thread_func) == FAILURE) {
230         return FAILURE;
231     }
232
233
234     if (nr5g_fapi_prepare_thread(&p_cfg->mac2phy_thread_params,
235                                  "nr5g_fapi_mac2phy_thread",
236                                  nr5g_fapi_mac2phy_thread_func) == FAILURE) {
237         return FAILURE;
238     }
239
240     if (p_cfg->is_urllc_enabled)
241     {
242         if (nr5g_fapi_initialise_sempahore(&p_phy_ctx->urllc_phy2mac_params) == FAILURE) {
243             return FAILURE;
244     }
245
246         if (nr5g_fapi_initialise_sempahore(&p_phy_ctx->urllc_mac2phy_params) == FAILURE) {
247         return FAILURE;
248     }
249
250         if (nr5g_fapi_prepare_thread(&p_cfg->urllc_mac2phy_thread_params,
251                                      "nr5g_fapi_urllc_mac2phy_thread",
252                                      nr5g_fapi_urllc_mac2phy_thread_func) == FAILURE) {
253             return FAILURE;
254     }
255
256
257         if (nr5g_fapi_prepare_thread(&p_cfg->urllc_phy2mac_thread_params,
258                                      "nr5g_fapi_urllc_phy2mac_thread",
259                                      nr5g_fapi_urllc_phy2mac_thread_func) == FAILURE) {
260         return FAILURE;
261     }
262
263     }
264     return SUCCESS;
265 }
266
267 void nr5g_fapi_clean(
268     p_nr5g_fapi_phy_instance_t p_phy_instance)
269 {
270     p_phy_instance->phy_config.n_nr_of_rx_ant = 0;
271     p_phy_instance->phy_config.phy_cell_id = 0;
272     p_phy_instance->phy_config.sub_c_common = 0;
273     p_phy_instance->phy_config.use_vendor_EpreXSSB = 0;
274     p_phy_instance->shutdown_test_type = 0; 
275     p_phy_instance->phy_id = 0;
276     p_phy_instance->state = FAPI_STATE_IDLE ;
277     
278     memset(p_phy_instance->ul_slot_info, 0, sizeof(nr5g_fapi_ul_slot_info_t));
279     wls_fapi_free_send_free_list_urllc();
280 }