O-RAN E Maintenance Release contribution for ODULOW
[o-du/phy.git] / fapi_5g / source / framework / nr5g_fapi_framework.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2019 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 "gnb_l1_l2_api.h"
24 #include "rte_memzone.h"
25 #include "nr5g_fapi_memory.h"
26
27 static nr5g_fapi_phy_ctx_t nr5g_fapi_phy_ctx;
28
29 inline p_nr5g_fapi_phy_ctx_t nr5g_fapi_get_nr5g_fapi_phy_ctx(
30     )
31 {
32     return &nr5g_fapi_phy_ctx;
33 }
34
35 uint8_t nr5g_fapi_dpdk_init(
36     p_nr5g_fapi_cfg_t p_cfg)
37 {
38     printf("init dev name: %s\n", p_cfg->dpdk.memory_zone);
39     char *const file_prefix = basename(p_cfg->dpdk.memory_zone);
40     printf("init basename: %s\n", file_prefix);
41     char whitelist[32], iova_mode[64];
42     uint8_t i;
43
44     char *argv[] = { p_cfg->prgname, "--proc-type=secondary",
45         "--file-prefix", file_prefix, whitelist, iova_mode
46     };
47 #if 0
48     char coremask[32];
49     char *argv[] = { p_cfg->prgname, coremask, "--proc-type=secondary",
50         "--file-prefix", file_prefix, whitelist
51     };
52     snprintf(coremask, 32, "-l %d,%d", p_cfg->mac2phy_worker.core_id,
53         p_cfg->phy2mac_worker.core_id);
54 #endif
55     int argc = RTE_DIM(argv);
56
57     /* initialize EAL first */
58     snprintf(whitelist, 32, "-a%s", "0000:00:06.0");
59
60     if (p_cfg->dpdk.iova_mode == 0)
61         snprintf(iova_mode, 64, "%s", "--iova-mode=pa");
62     else
63         snprintf(iova_mode, 64, "%s", "--iova-mode=va");
64
65     printf("Calling rte_eal_init: ");
66     for (i = 0; i < RTE_DIM(argv); i++) {
67         printf("%s ", argv[i]);
68     }
69     printf("\n");
70
71     if (rte_eal_init(argc, argv) < 0)
72         rte_panic("Cannot init EAL\n");
73
74     return SUCCESS;
75 }
76
77 uint8_t nr5g_fapi_dpdk_wait(
78     p_nr5g_fapi_cfg_t p_cfg)
79 {
80 #if 0
81     uint32_t worker_core;
82     /* wait per-lcore */
83     RTE_LCORE_FOREACH_SLAVE(worker_core) {
84         if (rte_eal_wait_lcore(worker_core) < 0) {
85             return FAILURE;
86         }
87     }
88 #else
89     pthread_join(p_cfg->mac2phy_thread_info.thread_id, NULL);
90     pthread_join(p_cfg->phy2mac_thread_info.thread_id, NULL);
91     pthread_join(p_cfg->urllc_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_framework_init(
133     p_nr5g_fapi_cfg_t p_cfg)
134 {
135     p_nr5g_fapi_phy_ctx_t p_phy_ctx = nr5g_fapi_get_nr5g_fapi_phy_ctx();
136     pthread_attr_t *p_mac2phy_attr, *p_phy2mac_attr, *p_urllc_attr;
137     struct sched_param param;
138
139     nr5g_fapi_set_log_level(p_cfg->logger.level);
140     // Set up WLS
141     if (FAILURE == nr5g_fapi_wls_init(p_cfg)) {
142         NR5G_FAPI_LOG(ERROR_LOG, ("[FAPI_INT] WLS init Failed"));
143         return FAILURE;
144     }
145     NR5G_FAPI_LOG(INFO_LOG, ("[FAPI_INT] WLS init Successful"));
146
147     p_phy_ctx->phy2mac_worker_core_id = p_cfg->phy2mac_worker.core_id;
148     p_phy_ctx->mac2phy_worker_core_id = p_cfg->mac2phy_worker.core_id;
149     p_phy_ctx->urllc_worker_core_id = p_cfg->urllc_worker.core_id;
150
151     memset(&p_phy_ctx->urllc_sem_process, 0, sizeof(sem_t));
152     memset(&p_phy_ctx->urllc_sem_done, 0, sizeof(sem_t));
153     if (0 != sem_init(&p_phy_ctx->urllc_sem_process, 0, 0)) {
154         printf("Error: Unable to init urllc semaphore\n");
155         return FAILURE;
156     }
157     if (0 != sem_init(&p_phy_ctx->urllc_sem_done, 0, 1)) {
158         printf("Error: Unable to init urllc_sem_done semaphore\n");
159         return FAILURE;
160     }
161
162     p_phy2mac_attr = &p_cfg->phy2mac_thread_info.thread_attr;
163     pthread_attr_init(p_phy2mac_attr);
164     if (!pthread_attr_getschedparam(p_phy2mac_attr, &param)) {
165         param.sched_priority = p_cfg->phy2mac_worker.thread_priority;
166         pthread_attr_setschedparam(p_phy2mac_attr, &param);
167         pthread_attr_setschedpolicy(p_phy2mac_attr, SCHED_FIFO);
168     }
169
170     if (0 != pthread_create(&p_cfg->phy2mac_thread_info.thread_id,
171             p_phy2mac_attr, nr5g_fapi_phy2mac_thread_func, (void *)
172             p_phy_ctx)) {
173         printf("Error: Unable to create threads\n");
174         if (p_phy2mac_attr)
175             pthread_attr_destroy(p_phy2mac_attr);
176         return FAILURE;
177     }
178     pthread_setname_np(p_cfg->phy2mac_thread_info.thread_id,
179         "nr5g_fapi_phy2mac_thread");
180
181     p_mac2phy_attr = &p_cfg->mac2phy_thread_info.thread_attr;
182     pthread_attr_init(p_mac2phy_attr);
183     if (!pthread_attr_getschedparam(p_mac2phy_attr, &param)) {
184         param.sched_priority = p_cfg->mac2phy_worker.thread_priority;
185         pthread_attr_setschedparam(p_mac2phy_attr, &param);
186         pthread_attr_setschedpolicy(p_mac2phy_attr, SCHED_FIFO);
187     }
188
189     if (0 != pthread_create(&p_cfg->mac2phy_thread_info.thread_id,
190             p_mac2phy_attr, nr5g_fapi_mac2phy_thread_func, (void *)
191             p_phy_ctx)) {
192         printf("Error: Unable to create threads\n");
193         if (p_mac2phy_attr)
194             pthread_attr_destroy(p_mac2phy_attr);
195         return FAILURE;
196     }
197     pthread_setname_np(p_cfg->mac2phy_thread_info.thread_id,
198         "nr5g_fapi_mac2phy_thread");
199
200     p_urllc_attr = &p_cfg->urllc_thread_info.thread_attr;
201     pthread_attr_init(p_urllc_attr);
202     if (!pthread_attr_getschedparam(p_urllc_attr, &param)) {
203         param.sched_priority = p_cfg->urllc_worker.thread_sched_policy;
204         pthread_attr_setschedparam(p_urllc_attr, &param);
205         pthread_attr_setschedpolicy(p_urllc_attr, SCHED_FIFO);
206     }
207
208     if (0 != pthread_create(&p_cfg->urllc_thread_info.thread_id,
209             p_urllc_attr, nr5g_fapi_urllc_thread_func, (void *)
210             p_phy_ctx)) {
211         printf("Error: Unable to create threads\n");
212         if (p_urllc_attr)
213             pthread_attr_destroy(p_urllc_attr);
214         sem_destroy(&p_phy_ctx->urllc_sem_process);
215         sem_destroy(&p_phy_ctx->urllc_sem_done);
216         return FAILURE;
217     }
218     pthread_setname_np(p_cfg->urllc_thread_info.thread_id,
219         "nr5g_fapi_urllc_thread");
220
221     return SUCCESS;
222 }