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