265279767726795dc28f20ced6063d97aa4c03dd
[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->wls.device_name);
39     char *const file_prefix = basename(p_cfg->wls.device_name);
40     printf("init basename: %s\n", file_prefix);
41     char whitelist[32];
42     uint8_t i;
43
44     char *argv[] = { p_cfg->prgname, "--proc-type=secondary",
45         "--file-prefix", file_prefix, whitelist
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, "-w %s", "0000:00:06.0");
59     printf("Calling rte_eal_init: ");
60     for (i = 0; i < RTE_DIM(argv); i++) {
61         printf("%s ", argv[i]);
62     }
63     printf("\n");
64
65     if (rte_eal_init(argc, argv) < 0)
66         rte_panic("Cannot init EAL\n");
67
68     return SUCCESS;
69 }
70
71 uint8_t nr5g_fapi_dpdk_wait(
72     p_nr5g_fapi_cfg_t p_cfg)
73 {
74 #if 0
75     uint32_t worker_core;
76     /* wait per-lcore */
77     RTE_LCORE_FOREACH_SLAVE(worker_core) {
78         if (rte_eal_wait_lcore(worker_core) < 0) {
79             return FAILURE;
80         }
81     }
82 #else
83     pthread_join(p_cfg->mac2phy_thread_info.thread_id, NULL);
84     pthread_join(p_cfg->phy2mac_thread_info.thread_id, NULL);
85 #endif
86     return SUCCESS;
87 }
88
89 void nr5g_fapi_set_ul_slot_info(
90     uint16_t frame_no,
91     uint8_t slot_no,
92     nr5g_fapi_ul_slot_info_t * p_ul_slot_info)
93 {
94     NR5G_FAPI_MEMSET(p_ul_slot_info, sizeof(nr5g_fapi_ul_slot_info_t), 0,
95         sizeof(nr5g_fapi_ul_slot_info_t));
96     p_ul_slot_info->cookie = frame_no;
97     p_ul_slot_info->slot_no = slot_no;
98 }
99
100 nr5g_fapi_ul_slot_info_t *nr5g_fapi_get_ul_slot_info(
101     uint16_t frame_no,
102     uint8_t slot_no,
103     p_nr5g_fapi_phy_instance_t p_phy_instance)
104 {
105     uint8_t i;
106     nr5g_fapi_ul_slot_info_t *p_ul_slot_info;
107
108     for (i = 0; i < MAX_UL_SLOT_INFO_COUNT; i++) {
109         p_ul_slot_info = &p_phy_instance->ul_slot_info[i];
110         if ((slot_no == p_ul_slot_info->slot_no) &&
111             (frame_no == p_ul_slot_info->cookie)) {
112             return p_ul_slot_info;
113         }
114     }
115     return NULL;
116 }
117
118 uint8_t nr5g_fapi_framework_init(
119     p_nr5g_fapi_cfg_t p_cfg)
120 {
121     uint8_t retval = FAILURE;
122     p_nr5g_fapi_phy_ctx_t p_phy_ctx = nr5g_fapi_get_nr5g_fapi_phy_ctx();
123     p_nr5g_fapi_wls_context_t pwls;
124     pthread_attr_t *p_mac2phy_attr, *p_phy2mac_attr;
125     struct sched_param param;
126
127     nr5g_fapi_set_log_level(p_cfg->logger.level);
128     // Set up WLS
129     if (FAILURE == nr5g_fapi_wls_init(p_cfg)) {
130         NR5G_FAPI_LOG(ERROR_LOG, ("[FAPI_INT] WLS init Failed"));
131         return FAILURE;
132     }
133     // First let's wait for the L1 and L2 to be present
134     while (retval) {
135         retval = nr5g_fapi_fapi2phy_wls_ready();
136     }
137     // Now the L2 is up so let's make sure that the L1 was started first
138     retval = FAILURE;
139     while (retval) {
140         retval = nr5g_fapi_fapi2mac_wls_ready();
141     }
142
143     usleep(1000000);
144     // Now that the L2 is up and has completed the Common Memory initialization
145     // the FT needs to initialize the FAPI2PHY buffers
146     pwls = nr5g_fapi_wls_context();
147     if (pwls) {
148         if (FAILURE == nr5g_fapi2Phy_wls_init(pwls)) {
149             return FAILURE;
150         }
151     } else {
152         return FAILURE;
153     }
154
155     p_phy_ctx->phy2mac_worker_core_id = p_cfg->phy2mac_worker.core_id;
156     p_phy_ctx->mac2phy_worker_core_id = p_cfg->mac2phy_worker.core_id;
157
158     p_phy2mac_attr = &p_cfg->phy2mac_thread_info.thread_attr;
159     pthread_attr_init(p_phy2mac_attr);
160     if (!pthread_attr_getschedparam(p_phy2mac_attr, &param)) {
161         param.sched_priority = p_cfg->phy2mac_worker.thread_priority;
162         pthread_attr_setschedparam(p_phy2mac_attr, &param);
163         pthread_attr_setschedpolicy(p_phy2mac_attr, SCHED_FIFO);
164     }
165
166     if (0 != pthread_create(&p_cfg->phy2mac_thread_info.thread_id,
167             p_phy2mac_attr, nr5g_fapi_phy2mac_thread_func, (void *)
168             p_phy_ctx)) {
169         printf("Error: Unable to create threads\n");
170         if (p_phy2mac_attr)
171             pthread_attr_destroy(p_phy2mac_attr);
172         return FAILURE;
173     }
174     pthread_setname_np(p_cfg->phy2mac_thread_info.thread_id,
175         "nr5g_fapi_phy2mac_thread");
176
177     p_mac2phy_attr = &p_cfg->mac2phy_thread_info.thread_attr;
178     pthread_attr_init(p_mac2phy_attr);
179     if (!pthread_attr_getschedparam(p_mac2phy_attr, &param)) {
180         param.sched_priority = p_cfg->mac2phy_worker.thread_priority;
181         pthread_attr_setschedparam(p_mac2phy_attr, &param);
182         pthread_attr_setschedpolicy(p_mac2phy_attr, SCHED_FIFO);
183     }
184
185     if (0 != pthread_create(&p_cfg->mac2phy_thread_info.thread_id,
186             p_mac2phy_attr, nr5g_fapi_mac2phy_thread_func, (void *)
187             p_phy_ctx)) {
188         printf("Error: Unable to create threads\n");
189         if (p_mac2phy_attr)
190             pthread_attr_destroy(p_mac2phy_attr);
191         return FAILURE;
192     }
193     pthread_setname_np(p_cfg->mac2phy_thread_info.thread_id,
194         "nr5g_fapi_mac2phy_thread");
195
196     return SUCCESS;
197 }