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 entry = rte_cfgfile_get_entry(cfg, "port", "frame overhead"); 33 if (entry) 34 port_params->frame_overhead = (uint32_t)atoi(entry); 35 36 entry = rte_cfgfile_get_entry(cfg, "port", "number of subports per port"); 37 if (entry) 38 port_params->n_subports_per_port = (uint32_t)atoi(entry); 39 40 entry = rte_cfgfile_get_entry(cfg, "port", "number of pipes per subport"); 41 if (entry) 42 port_params->n_pipes_per_subport = (uint32_t)atoi(entry); 43 44 entry = rte_cfgfile_get_entry(cfg, "port", "queue sizes"); 45 if (entry) { 46 char *next; 47 48 for(j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) { 49 port_params->qsize[j] = (uint16_t)strtol(entry, &next, 10); 50 if (next == NULL) 51 break; 52 entry = next; 53 } 54 } 55 56 #ifdef RTE_SCHED_RED 57 for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) { 58 char str[32]; 59 60 /* Parse WRED min thresholds */ 61 snprintf(str, sizeof(str), "tc %d wred min", j); 62 entry = rte_cfgfile_get_entry(cfg, "red", str); 63 if (entry) { 64 char *next; 65 int k; 66 /* for each packet colour (green, yellow, red) */ 67 for (k = 0; k < RTE_COLORS; k++) { 68 port_params->red_params[j][k].min_th 69 = (uint16_t)strtol(entry, &next, 10); 70 if (next == NULL) 71 break; 72 entry = next; 73 } 74 } 75 76 /* Parse WRED max thresholds */ 77 snprintf(str, sizeof(str), "tc %d wred max", 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].max_th 85 = (uint16_t)strtol(entry, &next, 10); 86 if (next == NULL) 87 break; 88 entry = next; 89 } 90 } 91 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); 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].maxp_inv 101 = (uint8_t)strtol(entry, &next, 10); 102 103 if (next == NULL) 104 break; 105 entry = next; 106 } 107 } 108 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); 112 if (entry) { 113 char *next; 114 int k; 115 /* for each packet colour (green, yellow, red) */ 116 for (k = 0; k < RTE_COLORS; k++) { 117 port_params->red_params[j][k].wq_log2 118 = (uint8_t)strtol(entry, &next, 10); 119 if (next == NULL) 120 break; 121 entry = next; 122 } 123 } 124 } 125 #endif /* RTE_SCHED_RED */ 126 127 return 0; 128 } 129 130 int 131 cfg_load_pipe(struct rte_cfgfile *cfg, struct rte_sched_pipe_params *pipe_params) 132 { 133 int i, j; 134 char *next; 135 const char *entry; 136 int profiles; 137 138 if (!cfg || !pipe_params) 139 return -1; 140 141 profiles = rte_cfgfile_num_sections(cfg, "pipe profile", sizeof("pipe profile") - 1); 142 port_params.n_pipe_profiles = profiles; 143 144 for (j = 0; j < profiles; j++) { 145 char pipe_name[32]; 146 snprintf(pipe_name, sizeof(pipe_name), "pipe profile %d", j); 147 148 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb rate"); 149 if (entry) 150 pipe_params[j].tb_rate = (uint32_t)atoi(entry); 151 152 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tb size"); 153 if (entry) 154 pipe_params[j].tb_size = (uint32_t)atoi(entry); 155 156 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc period"); 157 if (entry) 158 pipe_params[j].tc_period = (uint32_t)atoi(entry); 159 160 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 rate"); 161 if (entry) 162 pipe_params[j].tc_rate[0] = (uint32_t)atoi(entry); 163 164 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 rate"); 165 if (entry) 166 pipe_params[j].tc_rate[1] = (uint32_t)atoi(entry); 167 168 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 rate"); 169 if (entry) 170 pipe_params[j].tc_rate[2] = (uint32_t)atoi(entry); 171 172 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 rate"); 173 if (entry) 174 pipe_params[j].tc_rate[3] = (uint32_t)atoi(entry); 175 176 #ifdef RTE_SCHED_SUBPORT_TC_OV 177 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 oversubscription weight"); 178 if (entry) 179 pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry); 180 #endif 181 182 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 wrr weights"); 183 if (entry) { 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); 187 if (next == NULL) 188 break; 189 entry = next; 190 } 191 } 192 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 wrr weights"); 193 if (entry) { 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); 197 if (next == NULL) 198 break; 199 entry = next; 200 } 201 } 202 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 wrr weights"); 203 if (entry) { 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); 207 if (next == NULL) 208 break; 209 entry = next; 210 } 211 } 212 entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 wrr weights"); 213 if (entry) { 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); 217 if (next == NULL) 218 break; 219 entry = next; 220 } 221 } 222 } 223 return 0; 224 } 225 226 int 227 cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subport_params) 228 { 229 const char *entry; 230 int i, j, k; 231 232 if (!cfg || !subport_params) 233 return -1; 234 235 memset(app_pipe_to_profile, -1, sizeof(app_pipe_to_profile)); 236 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); 240 241 if (rte_cfgfile_has_section(cfg, sec_name)) { 242 entry = rte_cfgfile_get_entry(cfg, sec_name, "tb rate"); 243 if (entry) 244 subport_params[i].tb_rate = (uint32_t)atoi(entry); 245 246 entry = rte_cfgfile_get_entry(cfg, sec_name, "tb size"); 247 if (entry) 248 subport_params[i].tb_size = (uint32_t)atoi(entry); 249 250 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc period"); 251 if (entry) 252 subport_params[i].tc_period = (uint32_t)atoi(entry); 253 254 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 0 rate"); 255 if (entry) 256 subport_params[i].tc_rate[0] = (uint32_t)atoi(entry); 257 258 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 1 rate"); 259 if (entry) 260 subport_params[i].tc_rate[1] = (uint32_t)atoi(entry); 261 262 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 2 rate"); 263 if (entry) 264 subport_params[i].tc_rate[2] = (uint32_t)atoi(entry); 265 266 entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 3 rate"); 267 if (entry) 268 subport_params[i].tc_rate[3] = (uint32_t)atoi(entry); 269 270 int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name); 271 struct rte_cfgfile_entry entries[n_entries]; 272 273 rte_cfgfile_section_entries(cfg, sec_name, entries, n_entries); 274 275 for (j = 0; j < n_entries; j++) { 276 if (strncmp("pipe", entries[j].name, sizeof("pipe") - 1) == 0) { 277 int profile; 278 char *tokens[2] = {NULL, NULL}; 279 int n_tokens; 280 int begin, end; 281 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, '-'); 285 286 begin = atoi(tokens[0]); 287 if (n_tokens == 2) 288 end = atoi(tokens[1]); 289 else 290 end = begin; 291 292 if (end >= MAX_SCHED_PIPES || begin > end) 293 return -1; 294 295 for (k = begin; k <= end; k++) { 296 char profile_name[CFG_NAME_LEN]; 297 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; 302 else 303 rte_exit(EXIT_FAILURE, "Wrong pipe profile %s\n", 304 entries[j].value); 305 306 } 307 } 308 } 309 } 310 } 311 312 return 0; 313 } 314