1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2015 Intel Corporation
15 #include <rte_errno.h>
16 #include <rte_cfgfile.h>
17 #include <rte_string_fns.h>
22 tm_cfgfile_load_sched_port(
23 struct rte_cfgfile *file,
24 struct rte_sched_port_params *port_params)
29 entry = rte_cfgfile_get_entry(file, "port", "frame overhead");
31 port_params->frame_overhead = (uint32_t)atoi(entry);
33 entry = rte_cfgfile_get_entry(file, "port", "mtu");
35 port_params->mtu = (uint32_t)atoi(entry);
37 entry = rte_cfgfile_get_entry(file,
39 "number of subports per port");
41 port_params->n_subports_per_port = (uint32_t) atoi(entry);
43 entry = rte_cfgfile_get_entry(file,
45 "number of pipes per subport");
47 port_params->n_pipes_per_subport = (uint32_t) atoi(entry);
49 entry = rte_cfgfile_get_entry(file, "port", "queue sizes");
53 for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
54 port_params->qsize[j] = (uint16_t)
55 strtol(entry, &next, 10);
63 for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
66 /* Parse WRED min thresholds */
67 snprintf(str, sizeof(str), "tc %" PRId32 " wred min", j);
68 entry = rte_cfgfile_get_entry(file, "red", str);
73 /* for each packet colour (green, yellow, red) */
74 for (k = 0; k < e_RTE_METER_COLORS; k++) {
75 port_params->red_params[j][k].min_th
76 = (uint16_t)strtol(entry, &next, 10);
83 /* Parse WRED max thresholds */
84 snprintf(str, sizeof(str), "tc %" PRId32 " wred max", j);
85 entry = rte_cfgfile_get_entry(file, "red", str);
90 /* for each packet colour (green, yellow, red) */
91 for (k = 0; k < e_RTE_METER_COLORS; k++) {
92 port_params->red_params[j][k].max_th
93 = (uint16_t)strtol(entry, &next, 10);
100 /* Parse WRED inverse mark probabilities */
101 snprintf(str, sizeof(str), "tc %" PRId32 " wred inv prob", j);
102 entry = rte_cfgfile_get_entry(file, "red", str);
107 /* for each packet colour (green, yellow, red) */
108 for (k = 0; k < e_RTE_METER_COLORS; k++) {
109 port_params->red_params[j][k].maxp_inv
110 = (uint8_t)strtol(entry, &next, 10);
118 /* Parse WRED EWMA filter weights */
119 snprintf(str, sizeof(str), "tc %" PRId32 " wred weight", j);
120 entry = rte_cfgfile_get_entry(file, "red", str);
125 /* for each packet colour (green, yellow, red) */
126 for (k = 0; k < e_RTE_METER_COLORS; k++) {
127 port_params->red_params[j][k].wq_log2
128 = (uint8_t)strtol(entry, &next, 10);
135 #endif /* RTE_SCHED_RED */
141 tm_cfgfile_load_sched_pipe(
142 struct rte_cfgfile *file,
143 struct rte_sched_port_params *port_params,
144 struct rte_sched_pipe_params *pipe_params)
151 profiles = rte_cfgfile_num_sections(file,
152 "pipe profile", sizeof("pipe profile") - 1);
153 port_params->n_pipe_profiles = profiles;
155 for (j = 0; j < profiles; j++) {
158 snprintf(pipe_name, sizeof(pipe_name),
159 "pipe profile %" PRId32, j);
161 entry = rte_cfgfile_get_entry(file, pipe_name, "tb rate");
163 pipe_params[j].tb_rate = (uint32_t) atoi(entry);
165 entry = rte_cfgfile_get_entry(file, pipe_name, "tb size");
167 pipe_params[j].tb_size = (uint32_t) atoi(entry);
169 entry = rte_cfgfile_get_entry(file, pipe_name, "tc period");
171 pipe_params[j].tc_period = (uint32_t) atoi(entry);
173 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 0 rate");
175 pipe_params[j].tc_rate[0] = (uint32_t) atoi(entry);
177 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 1 rate");
179 pipe_params[j].tc_rate[1] = (uint32_t) atoi(entry);
181 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 2 rate");
183 pipe_params[j].tc_rate[2] = (uint32_t) atoi(entry);
185 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 3 rate");
187 pipe_params[j].tc_rate[3] = (uint32_t) atoi(entry);
189 #ifdef RTE_SCHED_SUBPORT_TC_OV
190 entry = rte_cfgfile_get_entry(file, pipe_name,
191 "tc 3 oversubscription weight");
193 pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry);
196 entry = rte_cfgfile_get_entry(file,
200 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
201 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*0 + i] =
202 (uint8_t) strtol(entry, &next, 10);
208 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 1 wrr weights");
210 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
211 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*1 + i] =
212 (uint8_t) strtol(entry, &next, 10);
218 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 2 wrr weights");
220 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
221 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*2 + i] =
222 (uint8_t) strtol(entry, &next, 10);
228 entry = rte_cfgfile_get_entry(file, pipe_name, "tc 3 wrr weights");
230 for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
231 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*3 + i] =
232 (uint8_t) strtol(entry, &next, 10);
242 tm_cfgfile_load_sched_subport(
243 struct rte_cfgfile *file,
244 struct rte_sched_subport_params *subport_params,
245 int *pipe_to_profile)
250 for (i = 0; i < APP_MAX_SCHED_SUBPORTS; i++) {
251 char sec_name[CFG_NAME_LEN];
253 snprintf(sec_name, sizeof(sec_name),
254 "subport %" PRId32, i);
256 if (rte_cfgfile_has_section(file, sec_name)) {
257 entry = rte_cfgfile_get_entry(file,
261 subport_params[i].tb_rate =
262 (uint32_t) atoi(entry);
264 entry = rte_cfgfile_get_entry(file,
268 subport_params[i].tb_size =
269 (uint32_t) atoi(entry);
271 entry = rte_cfgfile_get_entry(file,
275 subport_params[i].tc_period =
276 (uint32_t) atoi(entry);
278 entry = rte_cfgfile_get_entry(file,
282 subport_params[i].tc_rate[0] =
283 (uint32_t) atoi(entry);
285 entry = rte_cfgfile_get_entry(file,
289 subport_params[i].tc_rate[1] =
290 (uint32_t) atoi(entry);
292 entry = rte_cfgfile_get_entry(file,
296 subport_params[i].tc_rate[2] =
297 (uint32_t) atoi(entry);
299 entry = rte_cfgfile_get_entry(file,
303 subport_params[i].tc_rate[3] =
304 (uint32_t) atoi(entry);
306 int n_entries = rte_cfgfile_section_num_entries(file,
308 struct rte_cfgfile_entry entries[n_entries];
310 rte_cfgfile_section_entries(file,
315 for (j = 0; j < n_entries; j++)
318 sizeof("pipe") - 1) == 0) {
320 char *tokens[2] = {NULL, NULL};
323 char name[CFG_NAME_LEN + 1];
325 profile = atoi(entries[j].value);
329 n_tokens = rte_strsplit(
330 &name[sizeof("pipe")],
331 strnlen(name, CFG_NAME_LEN),
334 begin = atoi(tokens[0]);
336 end = atoi(tokens[1]);
340 if ((end >= APP_MAX_SCHED_PIPES) ||
344 for (k = begin; k <= end; k++) {
345 char profile_name[CFG_NAME_LEN];
347 snprintf(profile_name,
348 sizeof(profile_name),
349 "pipe profile %" PRId32,
351 if (rte_cfgfile_has_section(file, profile_name))
352 pipe_to_profile[i * APP_MAX_SCHED_PIPES + k] = profile;
354 rte_exit(EXIT_FAILURE,
355 "Wrong pipe profile %s\n",
366 tm_cfgfile_load(struct app_pktq_tm_params *tm)
368 struct rte_cfgfile *file;
371 memset(tm->sched_subport_params, 0, sizeof(tm->sched_subport_params));
372 memset(tm->sched_pipe_profiles, 0, sizeof(tm->sched_pipe_profiles));
373 memset(&tm->sched_port_params, 0, sizeof(tm->sched_port_params));
374 for (i = 0; i < APP_MAX_SCHED_SUBPORTS * APP_MAX_SCHED_PIPES; i++)
375 tm->sched_pipe_to_profile[i] = -1;
377 tm->sched_port_params.pipe_profiles = &tm->sched_pipe_profiles[0];
379 if (tm->file_name[0] == '\0')
382 file = rte_cfgfile_load(tm->file_name, 0);
386 tm_cfgfile_load_sched_port(file,
387 &tm->sched_port_params);
388 tm_cfgfile_load_sched_subport(file,
389 tm->sched_subport_params,
390 tm->sched_pipe_to_profile);
391 tm_cfgfile_load_sched_pipe(file,
392 &tm->sched_port_params,
393 tm->sched_pipe_profiles);
395 rte_cfgfile_close(file);
400 app_config_parse_tm(struct app_params *app)
404 for (i = 0; i < RTE_DIM(app->tm_params); i++) {
405 struct app_pktq_tm_params *p = &app->tm_params[i];
408 if (!APP_PARAM_VALID(p))
411 status = tm_cfgfile_load(p);
412 APP_CHECK(status == 0,
413 "Parse error for %s configuration file \"%s\"\n",