1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
9 #include <rte_string_fns.h>
10 #include <rte_sched.h>
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
24 cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params)
29 if (!cfg || !port_params)
32 entry = rte_cfgfile_get_entry(cfg, "port", "frame overhead");
34 port_params->frame_overhead = (uint32_t)atoi(entry);
36 entry = rte_cfgfile_get_entry(cfg, "port", "number of subports per port");
38 port_params->n_subports_per_port = (uint32_t)atoi(entry);
40 entry = rte_cfgfile_get_entry(cfg, "port", "number of pipes per subport");
42 port_params->n_pipes_per_subport = (uint32_t)atoi(entry);
44 entry = rte_cfgfile_get_entry(cfg, "port", "queue sizes");
48 for(j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
49 port_params->qsize[j] = (uint16_t)strtol(entry, &next, 10);
57 for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
60 /* Parse WRED min thresholds */
61 snprintf(str, sizeof(str), "tc %d wred min", j);
62 entry = rte_cfgfile_get_entry(cfg, "red", str);
66 /* for each packet colour (green, yellow, red) */
67 for (k = 0; k < e_RTE_METER_COLORS; k++) {
68 port_params->red_params[j][k].min_th
69 = (uint16_t)strtol(entry, &next, 10);
76 /* Parse WRED max thresholds */
77 snprintf(str, sizeof(str), "tc %d wred max", j);
78 entry = rte_cfgfile_get_entry(cfg, "red", str);
82 /* for each packet colour (green, yellow, red) */
83 for (k = 0; k < e_RTE_METER_COLORS; k++) {
84 port_params->red_params[j][k].max_th
85 = (uint16_t)strtol(entry, &next, 10);
92 /* Parse WRED inverse mark probabilities */
93 snprintf(str, sizeof(str), "tc %d wred inv prob", j);
94 entry = rte_cfgfile_get_entry(cfg, "red", str);
98 /* for each packet colour (green, yellow, red) */
99 for (k = 0; k < e_RTE_METER_COLORS; k++) {
100 port_params->red_params[j][k].maxp_inv
101 = (uint8_t)strtol(entry, &next, 10);
109 /* Parse WRED EWMA filter weights */
110 snprintf(str, sizeof(str), "tc %d wred weight", j);
111 entry = rte_cfgfile_get_entry(cfg, "red", str);
115 /* for each packet colour (green, yellow, red) */
116 for (k = 0; k < e_RTE_METER_COLORS; k++) {
117 port_params->red_params[j][k].wq_log2
118 = (uint8_t)strtol(entry, &next, 10);
125 #endif /* RTE_SCHED_RED */
131 cfg_load_pipe(struct rte_cfgfile *cfg, struct rte_sched_pipe_params *pipe_params)
138 if (!cfg || !pipe_params)
141 profiles = rte_cfgfile_num_sections(cfg, "pipe profile", sizeof("pipe profile") - 1);
142 port_params.n_pipe_profiles = profiles;
144 for (j = 0; j < profiles; j++) {
146 snprintf(pipe_name, sizeof(pipe_name), "pipe profile %d", j);
148 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb rate");
150 pipe_params[j].tb_rate = (uint32_t)atoi(entry);
152 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb size");
154 pipe_params[j].tb_size = (uint32_t)atoi(entry);
156 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc period");
158 pipe_params[j].tc_period = (uint32_t)atoi(entry);
160 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 rate");
162 pipe_params[j].tc_rate[0] = (uint32_t)atoi(entry);
164 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 rate");
166 pipe_params[j].tc_rate[1] = (uint32_t)atoi(entry);
168 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 rate");
170 pipe_params[j].tc_rate[2] = (uint32_t)atoi(entry);
172 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 rate");
174 pipe_params[j].tc_rate[3] = (uint32_t)atoi(entry);
176 #ifdef RTE_SCHED_SUBPORT_TC_OV
177 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 oversubscription weight");
179 pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry);
182 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 wrr weights");
184 for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
185 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*0 + i] =
186 (uint8_t)strtol(entry, &next, 10);
192 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 wrr weights");
194 for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
195 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*1 + i] =
196 (uint8_t)strtol(entry, &next, 10);
202 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 wrr weights");
204 for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
205 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*2 + i] =
206 (uint8_t)strtol(entry, &next, 10);
212 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 wrr weights");
214 for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
215 pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*3 + i] =
216 (uint8_t)strtol(entry, &next, 10);
227 cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subport_params)
232 if (!cfg || !subport_params)
235 memset(app_pipe_to_profile, -1, sizeof(app_pipe_to_profile));
237 for (i = 0; i < MAX_SCHED_SUBPORTS; i++) {
238 char sec_name[CFG_NAME_LEN];
239 snprintf(sec_name, sizeof(sec_name), "subport %d", i);
241 if (rte_cfgfile_has_section(cfg, sec_name)) {
242 entry = rte_cfgfile_get_entry(cfg, sec_name, "tb rate");
244 subport_params[i].tb_rate = (uint32_t)atoi(entry);
246 entry = rte_cfgfile_get_entry(cfg, sec_name, "tb size");
248 subport_params[i].tb_size = (uint32_t)atoi(entry);
250 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc period");
252 subport_params[i].tc_period = (uint32_t)atoi(entry);
254 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 0 rate");
256 subport_params[i].tc_rate[0] = (uint32_t)atoi(entry);
258 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 1 rate");
260 subport_params[i].tc_rate[1] = (uint32_t)atoi(entry);
262 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 2 rate");
264 subport_params[i].tc_rate[2] = (uint32_t)atoi(entry);
266 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 3 rate");
268 subport_params[i].tc_rate[3] = (uint32_t)atoi(entry);
270 int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name);
271 struct rte_cfgfile_entry entries[n_entries];
273 rte_cfgfile_section_entries(cfg, sec_name, entries, n_entries);
275 for (j = 0; j < n_entries; j++) {
276 if (strncmp("pipe", entries[j].name, sizeof("pipe") - 1) == 0) {
278 char *tokens[2] = {NULL, NULL};
282 profile = atoi(entries[j].value);
283 n_tokens = rte_strsplit(&entries[j].name[sizeof("pipe")],
284 strnlen(entries[j].name, CFG_NAME_LEN), tokens, 2, '-');
286 begin = atoi(tokens[0]);
288 end = atoi(tokens[1]);
292 if (end >= MAX_SCHED_PIPES || begin > end)
295 for (k = begin; k <= end; k++) {
296 char profile_name[CFG_NAME_LEN];
298 snprintf(profile_name, sizeof(profile_name),
299 "pipe profile %d", profile);
300 if (rte_cfgfile_has_section(cfg, profile_name))
301 app_pipe_to_profile[i][k] = profile;
303 rte_exit(EXIT_FAILURE, "Wrong pipe profile %s\n",