mbuf: extend meaning of QinQ stripped bit
[dpdk.git] / examples / qos_sched / cfg_file.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <ctype.h>
9 #include <rte_string_fns.h>
10 #include <rte_sched.h>
11
12 #include "cfg_file.h"
13 #include "main.h"
14
15
16 /** when we resize a file structure, how many extra entries
17  * for new sections do we add in */
18 #define CFG_ALLOC_SECTION_BATCH 8
19 /** when we resize a section structure, how many extra entries
20  * for new entries do we add in */
21 #define CFG_ALLOC_ENTRY_BATCH 16
22
23 uint32_t active_queues[RTE_SCHED_QUEUES_PER_PIPE];
24 uint32_t n_active_queues;
25
26 int
27 cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params)
28 {
29         const char *entry;
30
31         if (!cfg || !port_params)
32                 return -1;
33
34         entry = rte_cfgfile_get_entry(cfg, "port", "frame overhead");
35         if (entry)
36                 port_params->frame_overhead = (uint32_t)atoi(entry);
37
38         entry = rte_cfgfile_get_entry(cfg, "port", "number of subports per port");
39         if (entry)
40                 port_params->n_subports_per_port = (uint32_t)atoi(entry);
41
42         return 0;
43 }
44
45 int
46 cfg_load_pipe(struct rte_cfgfile *cfg, struct rte_sched_pipe_params *pipe_params)
47 {
48         int i, j;
49         char *next;
50         const char *entry;
51         int profiles;
52
53         if (!cfg || !pipe_params)
54                 return -1;
55
56         profiles = rte_cfgfile_num_sections(cfg, "pipe profile", sizeof("pipe profile") - 1);
57         subport_params[0].n_pipe_profiles = profiles;
58
59         for (j = 0; j < profiles; j++) {
60                 char pipe_name[32];
61                 snprintf(pipe_name, sizeof(pipe_name), "pipe profile %d", j);
62
63                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb rate");
64                 if (entry)
65                         pipe_params[j].tb_rate = (uint64_t)atoi(entry);
66
67                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb size");
68                 if (entry)
69                         pipe_params[j].tb_size = (uint64_t)atoi(entry);
70
71                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc period");
72                 if (entry)
73                         pipe_params[j].tc_period = (uint64_t)atoi(entry);
74
75                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 rate");
76                 if (entry)
77                         pipe_params[j].tc_rate[0] = (uint64_t)atoi(entry);
78
79                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 rate");
80                 if (entry)
81                         pipe_params[j].tc_rate[1] = (uint64_t)atoi(entry);
82
83                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 rate");
84                 if (entry)
85                         pipe_params[j].tc_rate[2] = (uint64_t)atoi(entry);
86
87                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 rate");
88                 if (entry)
89                         pipe_params[j].tc_rate[3] = (uint64_t)atoi(entry);
90
91                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 4 rate");
92                 if (entry)
93                         pipe_params[j].tc_rate[4] = (uint64_t)atoi(entry);
94
95                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 5 rate");
96                 if (entry)
97                         pipe_params[j].tc_rate[5] = (uint64_t)atoi(entry);
98
99                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 6 rate");
100                 if (entry)
101                         pipe_params[j].tc_rate[6] = (uint64_t)atoi(entry);
102
103                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 7 rate");
104                 if (entry)
105                         pipe_params[j].tc_rate[7] = (uint64_t)atoi(entry);
106
107                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 8 rate");
108                 if (entry)
109                         pipe_params[j].tc_rate[8] = (uint64_t)atoi(entry);
110
111                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 9 rate");
112                 if (entry)
113                         pipe_params[j].tc_rate[9] = (uint64_t)atoi(entry);
114
115                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 10 rate");
116                 if (entry)
117                         pipe_params[j].tc_rate[10] = (uint64_t)atoi(entry);
118
119                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 11 rate");
120                 if (entry)
121                         pipe_params[j].tc_rate[11] = (uint64_t)atoi(entry);
122
123                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 rate");
124                 if (entry)
125                         pipe_params[j].tc_rate[12] = (uint64_t)atoi(entry);
126
127                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 oversubscription weight");
128                 if (entry)
129                         pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry);
130
131                 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 wrr weights");
132                 if (entry) {
133                         for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) {
134                                 pipe_params[j].wrr_weights[i] =
135                                         (uint8_t)strtol(entry, &next, 10);
136                                 if (next == NULL)
137                                         break;
138                                 entry = next;
139                         }
140                 }
141         }
142         return 0;
143 }
144
145 int
146 cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subport_params)
147 {
148         const char *entry;
149         int i, j, k;
150
151         if (!cfg || !subport_params)
152                 return -1;
153
154         memset(app_pipe_to_profile, -1, sizeof(app_pipe_to_profile));
155         memset(active_queues, 0, sizeof(active_queues));
156         n_active_queues = 0;
157
158 #ifdef RTE_SCHED_RED
159         char sec_name[CFG_NAME_LEN];
160         struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
161
162         snprintf(sec_name, sizeof(sec_name), "red");
163
164         if (rte_cfgfile_has_section(cfg, sec_name)) {
165
166                 for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
167                         char str[32];
168
169                         /* Parse WRED min thresholds */
170                         snprintf(str, sizeof(str), "tc %d wred min", i);
171                         entry = rte_cfgfile_get_entry(cfg, sec_name, str);
172                         if (entry) {
173                                 char *next;
174                                 /* for each packet colour (green, yellow, red) */
175                                 for (j = 0; j < RTE_COLORS; j++) {
176                                         red_params[i][j].min_th
177                                                 = (uint16_t)strtol(entry, &next, 10);
178                                         if (next == NULL)
179                                                 break;
180                                         entry = next;
181                                 }
182                         }
183
184                         /* Parse WRED max thresholds */
185                         snprintf(str, sizeof(str), "tc %d wred max", i);
186                         entry = rte_cfgfile_get_entry(cfg, "red", str);
187                         if (entry) {
188                                 char *next;
189                                 /* for each packet colour (green, yellow, red) */
190                                 for (j = 0; j < RTE_COLORS; j++) {
191                                         red_params[i][j].max_th
192                                                 = (uint16_t)strtol(entry, &next, 10);
193                                         if (next == NULL)
194                                                 break;
195                                         entry = next;
196                                 }
197                         }
198
199                         /* Parse WRED inverse mark probabilities */
200                         snprintf(str, sizeof(str), "tc %d wred inv prob", i);
201                         entry = rte_cfgfile_get_entry(cfg, "red", str);
202                         if (entry) {
203                                 char *next;
204                                 /* for each packet colour (green, yellow, red) */
205                                 for (j = 0; j < RTE_COLORS; j++) {
206                                         red_params[i][j].maxp_inv
207                                                 = (uint8_t)strtol(entry, &next, 10);
208
209                                         if (next == NULL)
210                                                 break;
211                                         entry = next;
212                                 }
213                         }
214
215                         /* Parse WRED EWMA filter weights */
216                         snprintf(str, sizeof(str), "tc %d wred weight", i);
217                         entry = rte_cfgfile_get_entry(cfg, "red", str);
218                         if (entry) {
219                                 char *next;
220                                 /* for each packet colour (green, yellow, red) */
221                                 for (j = 0; j < RTE_COLORS; j++) {
222                                         red_params[i][j].wq_log2
223                                                 = (uint8_t)strtol(entry, &next, 10);
224                                         if (next == NULL)
225                                                 break;
226                                         entry = next;
227                                 }
228                         }
229                 }
230         }
231 #endif /* RTE_SCHED_RED */
232
233         for (i = 0; i < MAX_SCHED_SUBPORTS; i++) {
234                 char sec_name[CFG_NAME_LEN];
235                 snprintf(sec_name, sizeof(sec_name), "subport %d", i);
236
237                 if (rte_cfgfile_has_section(cfg, sec_name)) {
238                         entry = rte_cfgfile_get_entry(cfg, sec_name,
239                                 "number of pipes per subport");
240                         if (entry)
241                                 subport_params[i].n_pipes_per_subport_enabled =
242                                         (uint32_t)atoi(entry);
243
244                         entry = rte_cfgfile_get_entry(cfg, sec_name, "queue sizes");
245                         if (entry) {
246                                 char *next;
247
248                                 for (j = 0; j < RTE_SCHED_TRAFFIC_CLASS_BE; j++) {
249                                         subport_params[i].qsize[j] =
250                                                 (uint16_t)strtol(entry, &next, 10);
251                                         if (subport_params[i].qsize[j] != 0) {
252                                                 active_queues[n_active_queues] = j;
253                                                 n_active_queues++;
254                                         }
255                                         if (next == NULL)
256                                                 break;
257                                         entry = next;
258                                 }
259
260                                 subport_params[i].qsize[RTE_SCHED_TRAFFIC_CLASS_BE] =
261                                         (uint16_t)strtol(entry, &next, 10);
262
263                                 for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) {
264                                         active_queues[n_active_queues] =
265                                                 RTE_SCHED_TRAFFIC_CLASS_BE + j;
266                                         n_active_queues++;
267                                 }
268                         }
269
270                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tb rate");
271                         if (entry)
272                                 subport_params[i].tb_rate = (uint64_t)atoi(entry);
273
274                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tb size");
275                         if (entry)
276                                 subport_params[i].tb_size = (uint64_t)atoi(entry);
277
278                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc period");
279                         if (entry)
280                                 subport_params[i].tc_period = (uint64_t)atoi(entry);
281
282                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 0 rate");
283                         if (entry)
284                                 subport_params[i].tc_rate[0] = (uint64_t)atoi(entry);
285
286                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 1 rate");
287                         if (entry)
288                                 subport_params[i].tc_rate[1] = (uint64_t)atoi(entry);
289
290                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 2 rate");
291                         if (entry)
292                                 subport_params[i].tc_rate[2] = (uint64_t)atoi(entry);
293
294                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 3 rate");
295                         if (entry)
296                                 subport_params[i].tc_rate[3] = (uint64_t)atoi(entry);
297
298                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 4 rate");
299                         if (entry)
300                                 subport_params[i].tc_rate[4] = (uint64_t)atoi(entry);
301
302                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 5 rate");
303                         if (entry)
304                                 subport_params[i].tc_rate[5] = (uint64_t)atoi(entry);
305
306                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 6 rate");
307                         if (entry)
308                                 subport_params[i].tc_rate[6] = (uint64_t)atoi(entry);
309
310                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 7 rate");
311                         if (entry)
312                                 subport_params[i].tc_rate[7] = (uint64_t)atoi(entry);
313
314                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 8 rate");
315                         if (entry)
316                                 subport_params[i].tc_rate[8] = (uint64_t)atoi(entry);
317
318                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 9 rate");
319                         if (entry)
320                                 subport_params[i].tc_rate[9] = (uint64_t)atoi(entry);
321
322                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 10 rate");
323                         if (entry)
324                                 subport_params[i].tc_rate[10] = (uint64_t)atoi(entry);
325
326                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 11 rate");
327                         if (entry)
328                                 subport_params[i].tc_rate[11] = (uint64_t)atoi(entry);
329
330                         entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 12 rate");
331                         if (entry)
332                                 subport_params[i].tc_rate[12] = (uint64_t)atoi(entry);
333
334                         int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name);
335                         struct rte_cfgfile_entry entries[n_entries];
336
337                         rte_cfgfile_section_entries(cfg, sec_name, entries, n_entries);
338
339                         for (j = 0; j < n_entries; j++) {
340                                 if (strncmp("pipe", entries[j].name, sizeof("pipe") - 1) == 0) {
341                                         int profile;
342                                         char *tokens[2] = {NULL, NULL};
343                                         int n_tokens;
344                                         int begin, end;
345
346                                         profile = atoi(entries[j].value);
347                                         n_tokens = rte_strsplit(&entries[j].name[sizeof("pipe")],
348                                                         strnlen(entries[j].name, CFG_NAME_LEN), tokens, 2, '-');
349
350                                         begin =  atoi(tokens[0]);
351                                         if (n_tokens == 2)
352                                                 end = atoi(tokens[1]);
353                                         else
354                                                 end = begin;
355
356                                         if (end >= MAX_SCHED_PIPES || begin > end)
357                                                 return -1;
358
359                                         for (k = begin; k <= end; k++) {
360                                                 char profile_name[CFG_NAME_LEN];
361
362                                                 snprintf(profile_name, sizeof(profile_name),
363                                                                 "pipe profile %d", profile);
364                                                 if (rte_cfgfile_has_section(cfg, profile_name))
365                                                         app_pipe_to_profile[i][k] = profile;
366                                                 else
367                                                         rte_exit(EXIT_FAILURE, "Wrong pipe profile %s\n",
368                                                                         entries[j].value);
369
370                                         }
371                                 }
372                         }
373 #ifdef RTE_SCHED_RED
374                         for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
375                                 for (k = 0; k < RTE_COLORS; k++) {
376                                         subport_params[i].red_params[j][k].min_th =
377                                                 red_params[j][k].min_th;
378                                         subport_params[i].red_params[j][k].max_th =
379                                                 red_params[j][k].max_th;
380                                         subport_params[i].red_params[j][k].maxp_inv =
381                                                 red_params[j][k].maxp_inv;
382                                         subport_params[i].red_params[j][k].wq_log2 =
383                                                 red_params[j][k].wq_log2;
384                                 }
385                         }
386 #endif
387                 }
388         }
389
390         return 0;
391 }