* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fapi_5g / source / utils / nr5g_fapi_config_loader.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_config_loader.h"
19 #include "nr5g_fapi_dpdk.h"
20 #include "sched.h"
21
22 #define NR5G_FAPI_MAX_SHMSIZE (2126512128)
23 char *fgets_s(
24     char *string,
25     size_t len,
26     FILE * fp);
27
28 void nr5g_fapi_get_worker_info(
29     struct rte_cfgfile *cfg_file,
30     unsigned int num_cpus,
31     nr5g_fapi_thread_params_t * thread_params,
32     const char* worker_name)
33 {
34     const char *entry;
35
36     entry = rte_cfgfile_get_entry(cfg_file, worker_name, "core_id");
37     if (entry) {
38         thread_params->thread_worker.core_id = (uint8_t) atoi(entry);
39         if (thread_params->thread_worker.core_id >= (uint8_t) num_cpus) {
40             printf("Core Id is not in the range 0 to %d: configured: %d\n",
41                 num_cpus, thread_params->thread_worker.core_id);
42             exit(-1);
43         }
44     }
45
46     entry =
47         rte_cfgfile_get_entry(cfg_file, worker_name,
48         "thread_sched_policy");
49     if (entry) {
50         thread_params->thread_worker.thread_sched_policy = (uint8_t) atoi(entry);
51         if (thread_params->thread_worker.thread_sched_policy != SCHED_FIFO &&
52             thread_params->thread_worker.thread_sched_policy != SCHED_RR) {
53             printf("Thread Policy valid range is Schedule Policy [1: SCHED_FIFO"
54                 " 2: SCHED_RR]: configured: %d\n",
55                 thread_params->thread_worker.thread_sched_policy);
56             exit(-1);
57         }
58     }
59
60     int min_prio =
61         sched_get_priority_min(thread_params->thread_worker.thread_sched_policy);
62     int max_prio =
63         sched_get_priority_max(thread_params->thread_worker.thread_sched_policy);
64     entry =
65         rte_cfgfile_get_entry(cfg_file, worker_name, "thread_priority");
66     if (entry) {
67         thread_params->thread_worker.thread_priority = (uint8_t) atoi(entry);
68         if (thread_params->thread_worker.thread_priority < min_prio &&
69             thread_params->thread_worker.thread_priority > max_prio) {
70             printf("Thread priority valid range is %d to %d: configured: %d\n",
71                 min_prio, max_prio, thread_params->thread_worker.thread_priority);
72             exit(-1);
73         }
74     }
75 }
76
77 p_nr5g_fapi_cfg_t nr5g_fapi_config_loader(
78     char *prgname,
79     const char *cfg_fname)
80 {
81     struct rte_cfgfile *cfg_file;
82     p_nr5g_fapi_cfg_t cfg;
83     const char *entry;
84     size_t dev_name_len, mem_zone_name_len;
85     unsigned int num_cpus = 0;
86     char check_core_count[255], *max_core;
87     FILE *fp = NULL;
88
89     if (cfg_fname == NULL) {
90         printf("Error: Configuration filename was not passed.");
91         return NULL;
92     }
93
94     cfg_file = rte_cfgfile_load(cfg_fname, 0);
95     if (cfg_file == NULL) {
96         printf("Error: Cofiguration file loading failed.");
97         return NULL;
98     }
99
100     cfg = (p_nr5g_fapi_cfg_t) calloc(1, sizeof(nr5g_fapi_cfg_t));
101     if (!cfg) {
102         printf("Error: not enough memory in the system");
103         return NULL;
104     }
105     cfg->prgname = prgname;
106     fp = popen("cat /proc/cpuinfo | grep processor | wc -l", "r");
107     if (NULL == fp) {
108         printf("Error: In getting maximum number of lcores in the system.");
109         free(cfg);
110         return NULL;
111     }
112     max_core = fgets_s(check_core_count, 255, fp);
113     if (NULL == max_core) {
114         printf("Error: In getting maximum number of lcores in the system.");
115         free(cfg);
116         pclose(fp);
117         return NULL;
118     }
119     pclose(fp);
120     num_cpus = atoi(max_core);
121
122     cfg->is_urllc_enabled = TRUE;
123     entry = rte_cfgfile_get_entry(cfg_file, "URLLC", "is_enabled");
124     if (entry)
125     {
126         cfg->is_urllc_enabled = (bool)atoi(entry);
127         if (!cfg->is_urllc_enabled)
128             printf("URLLC disabled\n");
129     }
130
131     nr5g_fapi_get_worker_info(cfg_file, num_cpus, &cfg->mac2phy_thread_params, "MAC2PHY_WORKER");
132     nr5g_fapi_get_worker_info(cfg_file, num_cpus, &cfg->phy2mac_thread_params, "PHY2MAC_WORKER");
133     nr5g_fapi_get_worker_info(cfg_file, num_cpus, &cfg->urllc_mac2phy_thread_params, "MAC2PHY_URLLC_WORKER");
134     nr5g_fapi_get_worker_info(cfg_file, num_cpus, &cfg->urllc_phy2mac_thread_params, "PHY2MAC_URLLC_WORKER");
135
136     entry = rte_cfgfile_get_entry(cfg_file, "WLS_CFG", "device_name");
137     if (entry) {
138         dev_name_len = (strlen(entry) > (NR5G_FAPI_DEVICE_NAME_LEN)) ?
139             (NR5G_FAPI_DEVICE_NAME_LEN) : strlen(entry);
140         rte_strlcpy(cfg->wls.device_name, entry, dev_name_len + 1);
141     }
142
143     entry = rte_cfgfile_get_entry(cfg_file, "WLS_CFG", "shmem_size");
144     if (entry) {
145         cfg->wls.shmem_size = (uint64_t) atoll(entry);
146         if (cfg->wls.shmem_size > NR5G_FAPI_MAX_SHMSIZE) {
147             printf("The memory range cannot exceed %d", NR5G_FAPI_MAX_SHMSIZE);
148             exit(-1);
149         }
150     }
151
152     entry = rte_cfgfile_get_entry(cfg_file, "LOGGER", "level");
153     if (entry) {
154         if (!strcmp(entry, "info"))
155             cfg->logger.level = INFO_LOG;
156         else if (!strcmp(entry, "debug"))
157             cfg->logger.level = DEBUG_LOG;
158         else if (!strcmp(entry, "error"))
159             cfg->logger.level = ERROR_LOG;
160         else if (!strcmp(entry, "trace"))
161             cfg->logger.level = TRACE_LOG;
162         else
163             cfg->logger.level = NONE_LOG;
164     }
165
166     entry = rte_cfgfile_get_entry(cfg_file, "DPDK", "dpdk_iova_mode");
167     if (entry) {
168         cfg->dpdk.iova_mode = (uint8_t) atoi(entry);
169         if (cfg->dpdk.iova_mode >= DPDK_IOVA_MAX_MODE) {
170             printf("The mode is out of range: %d", cfg->dpdk.iova_mode);
171             exit(-1);
172         }
173     }
174
175     entry = rte_cfgfile_get_entry(cfg_file, "DPDK", "dpdk_memory_zone");
176     if (entry) {
177         mem_zone_name_len = (strlen(entry) > (NR5G_FAPI_MEMORY_ZONE_NAME_LEN)) ?
178             (NR5G_FAPI_MEMORY_ZONE_NAME_LEN) : strlen(entry);
179         rte_strlcpy(cfg->dpdk.memory_zone, entry, mem_zone_name_len + 1);
180     }
181
182     return cfg;
183 }
184
185 char *fgets_s(
186     char *string,
187     size_t len,
188     FILE * fp)
189 {
190     if (fgets(string, len, fp) != 0) {
191         string[strcspn(string, "\n")] = '\0';
192         return string;
193     }
194     return 0;
195 }