O-RAN E Maintenance Release contribution for ODULOW
[o-du/phy.git] / fapi_5g / source / utils / nr5g_fapi_config_loader.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_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 p_nr5g_fapi_cfg_t nr5g_fapi_config_loader(
29     char *prgname,
30     const char *cfg_fname)
31 {
32     struct rte_cfgfile *cfg_file;
33     p_nr5g_fapi_cfg_t cfg;
34     const char *entry;
35     size_t dev_name_len, mem_zone_name_len;
36     unsigned int num_cpus = 0;
37     char check_core_count[255], *max_core;
38     FILE *fp = NULL;
39
40     if (cfg_fname == NULL) {
41         printf("Error: Configuration filename was not passed.");
42         return NULL;
43     }
44
45     cfg_file = rte_cfgfile_load(cfg_fname, 0);
46     if (cfg_file == NULL) {
47         printf("Error: Cofiguration file loading failed.");
48         return NULL;
49     }
50
51     cfg = (p_nr5g_fapi_cfg_t) calloc(1, sizeof(nr5g_fapi_cfg_t));
52     if (!cfg) {
53         printf("Error: not enough memory in the system");
54         return NULL;
55     }
56     cfg->prgname = prgname;
57     fp = popen("cat /proc/cpuinfo | grep processor | wc -l", "r");
58     if (NULL == fp) {
59         printf("Error: In getting maximum number of lcores in the system.");
60         free(cfg);
61         return NULL;
62     }
63     max_core = fgets_s(check_core_count, 255, fp);
64     if (NULL == max_core) {
65         printf("Error: In getting maximum number of lcores in the system.");
66         free(cfg);
67         pclose(fp);
68         return NULL;
69     }
70     pclose(fp);
71     num_cpus = atoi(max_core);
72     entry = rte_cfgfile_get_entry(cfg_file, "MAC2PHY_WORKER", "core_id");
73     if (entry) {
74         cfg->mac2phy_worker.core_id = (uint8_t) atoi(entry);
75         if (cfg->mac2phy_worker.core_id >= (uint8_t) num_cpus) {
76             printf("Core Id is not in the range 0 to %d: configured: %d\n",
77                 num_cpus, cfg->mac2phy_worker.core_id);
78             exit(-1);
79         }
80     }
81
82     entry =
83         rte_cfgfile_get_entry(cfg_file, "MAC2PHY_WORKER",
84         "thread_sched_policy");
85     if (entry) {
86         cfg->mac2phy_worker.thread_sched_policy = (uint8_t) atoi(entry);
87         if (cfg->mac2phy_worker.thread_sched_policy != SCHED_FIFO &&
88             cfg->mac2phy_worker.thread_sched_policy != SCHED_RR) {
89             printf("Thread Policy valid range is Schedule Policy [1: SCHED_FIFO"
90                 " 2: SCHED_RR]: configured: %d\n",
91                 cfg->mac2phy_worker.thread_sched_policy);
92             exit(-1);
93         }
94     }
95
96     int min_prio =
97         sched_get_priority_min(cfg->mac2phy_worker.thread_sched_policy);
98     int max_prio =
99         sched_get_priority_max(cfg->mac2phy_worker.thread_sched_policy);
100     entry =
101         rte_cfgfile_get_entry(cfg_file, "MAC2PHY_WORKER", "thread_priority");
102     if (entry) {
103         cfg->mac2phy_worker.thread_priority = (uint8_t) atoi(entry);
104         if (cfg->mac2phy_worker.thread_priority < min_prio &&
105             cfg->mac2phy_worker.thread_priority > max_prio) {
106             printf("Thread priority valid range is %d to %d: configured: %d\n",
107                 min_prio, max_prio, cfg->mac2phy_worker.thread_priority);
108             exit(-1);
109         }
110     }
111
112     entry = rte_cfgfile_get_entry(cfg_file, "PHY2MAC_WORKER", "core_id");
113     if (entry) {
114         cfg->phy2mac_worker.core_id = (uint8_t) atoi(entry);
115         if (cfg->phy2mac_worker.core_id >= (uint8_t) num_cpus) {
116             printf("Core Id is not in the range 0 to %d configured: %d\n",
117                 num_cpus, cfg->phy2mac_worker.core_id);
118             exit(-1);
119         }
120     }
121
122     entry =
123         rte_cfgfile_get_entry(cfg_file, "PHY2MAC_WORKER",
124         "thread_sched_policy");
125     if (entry) {
126         cfg->phy2mac_worker.thread_sched_policy = (uint8_t) atoi(entry);
127         if (cfg->phy2mac_worker.thread_sched_policy != SCHED_FIFO &&
128             cfg->phy2mac_worker.thread_sched_policy != SCHED_RR) {
129             printf("Thread Policy valid range is Schedule Policy [1: SCHED_FIFO"
130                 " 2: SCHED_RR] configured: %d\n",
131                 cfg->phy2mac_worker.thread_sched_policy);
132             exit(-1);
133         }
134     }
135
136     entry =
137         rte_cfgfile_get_entry(cfg_file, "PHY2MAC_WORKER", "thread_priority");
138     if (entry) {
139         cfg->phy2mac_worker.thread_priority = (uint8_t) atoi(entry);
140         if (cfg->phy2mac_worker.thread_priority < min_prio &&
141             cfg->phy2mac_worker.thread_priority > max_prio) {
142             printf("Thread priority valid range is %d to %d configured: %d\n",
143                 min_prio, max_prio, cfg->phy2mac_worker.thread_priority);
144             exit(-1);
145         }
146     }
147
148     entry = rte_cfgfile_get_entry(cfg_file, "URLLC_WORKER", "core_id");
149     if (entry) {
150         cfg->urllc_worker.core_id = (uint8_t) atoi(entry);
151         if (cfg->urllc_worker.core_id >= (uint8_t) num_cpus) {
152             printf("Core Id is not in the range 0 to %d configured: %d\n",
153                 num_cpus, cfg->urllc_worker.core_id);
154             exit(-1);
155         }
156     }
157
158     entry =
159         rte_cfgfile_get_entry(cfg_file, "URLLC_WORKER", "thread_sched_policy");
160     if (entry) {
161         cfg->urllc_worker.thread_sched_policy = (uint8_t) atoi(entry);
162         if (cfg->urllc_worker.thread_sched_policy != SCHED_FIFO &&
163             cfg->urllc_worker.thread_sched_policy != SCHED_RR) {
164             printf("Thread Policy valid range is Schedule Policy [1: SCHED_FIFO"
165                 " 2: SCHED_RR] configured: %d\n",
166                 cfg->urllc_worker.thread_sched_policy);
167             exit(-1);
168         }
169     }
170
171     entry =
172         rte_cfgfile_get_entry(cfg_file, "URLLC_WORKER", "thread_priority");
173     if (entry) {
174         cfg->urllc_worker.thread_priority = (uint8_t) atoi(entry);
175         if (cfg->urllc_worker.thread_priority < min_prio &&
176             cfg->urllc_worker.thread_priority > max_prio) {
177             printf("Thread priority valid range is %d to %d configured: %d\n",
178                 min_prio, max_prio, cfg->urllc_worker.thread_priority);
179             exit(-1);
180         }
181     }
182
183     entry = rte_cfgfile_get_entry(cfg_file, "WLS_CFG", "device_name");
184     if (entry) {
185         dev_name_len = (strlen(entry) > (NR5G_FAPI_DEVICE_NAME_LEN)) ?
186             (NR5G_FAPI_DEVICE_NAME_LEN) : strlen(entry);
187         rte_strlcpy(cfg->wls.device_name, entry, dev_name_len + 1);
188     }
189
190     entry = rte_cfgfile_get_entry(cfg_file, "WLS_CFG", "shmem_size");
191     if (entry) {
192         cfg->wls.shmem_size = (uint64_t) atoll(entry);
193         if (cfg->wls.shmem_size > NR5G_FAPI_MAX_SHMSIZE) {
194             printf("The memory range cannot exceed %d", NR5G_FAPI_MAX_SHMSIZE);
195             exit(-1);
196         }
197     }
198
199     entry = rte_cfgfile_get_entry(cfg_file, "LOGGER", "level");
200     if (entry) {
201         if (!strcmp(entry, "info"))
202             cfg->logger.level = INFO_LOG;
203         else if (!strcmp(entry, "debug"))
204             cfg->logger.level = DEBUG_LOG;
205         else if (!strcmp(entry, "error"))
206             cfg->logger.level = ERROR_LOG;
207         else if (!strcmp(entry, "trace"))
208             cfg->logger.level = TRACE_LOG;
209         else
210             cfg->logger.level = NONE_LOG;
211     }
212
213     entry = rte_cfgfile_get_entry(cfg_file, "DPDK", "dpdk_iova_mode");
214     if (entry) {
215         cfg->dpdk.iova_mode = (uint8_t) atoi(entry);
216         if (cfg->dpdk.iova_mode >= DPDK_IOVA_MAX_MODE) {
217             printf("The mode is out of range: %d", cfg->dpdk.iova_mode);
218             exit(-1);
219         }
220     }
221
222     entry = rte_cfgfile_get_entry(cfg_file, "DPDK", "dpdk_memory_zone");
223     if (entry) {
224         mem_zone_name_len = (strlen(entry) > (NR5G_FAPI_MEMORY_ZONE_NAME_LEN)) ?
225             (NR5G_FAPI_MEMORY_ZONE_NAME_LEN) : strlen(entry);
226         rte_strlcpy(cfg->dpdk.memory_zone, entry, mem_zone_name_len + 1);
227     }
228
229     return cfg;
230 }
231
232 char *fgets_s(
233     char *string,
234     size_t len,
235     FILE * fp)
236 {
237     if (fgets(string, len, fp) != 0) {
238         string[strcspn(string, "\n")] = '\0';
239         return string;
240     }
241     return 0;
242 }