1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2018 Intel Corporation 3 */ 4 5 #include <stdlib.h> 6 7 #include <rte_common.h> 8 #include <rte_string_fns.h> 9 10 #include "tmgr.h" 11 12 static struct rte_sched_subport_profile_params 13 subport_profile[TMGR_SUBPORT_PROFILE_MAX]; 14 15 static uint32_t n_subport_profiles; 16 17 static struct rte_sched_pipe_params 18 pipe_profile[TMGR_PIPE_PROFILE_MAX]; 19 20 #ifdef RTE_SCHED_CMAN 21 static struct rte_sched_cman_params cman_params = { 22 .red_params = { 23 /* Traffic Class 0 Colors Green / Yellow / Red */ 24 [0][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 25 [0][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 26 [0][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 27 28 /* Traffic Class 1 - Colors Green / Yellow / Red */ 29 [1][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 30 [1][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 31 [1][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 32 33 /* Traffic Class 2 - Colors Green / Yellow / Red */ 34 [2][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 35 [2][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 36 [2][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 37 38 /* Traffic Class 3 - Colors Green / Yellow / Red */ 39 [3][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 40 [3][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 41 [3][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 42 43 /* Traffic Class 4 - Colors Green / Yellow / Red */ 44 [4][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 45 [4][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 46 [4][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 47 48 /* Traffic Class 5 - Colors Green / Yellow / Red */ 49 [5][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 50 [5][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 51 [5][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 52 53 /* Traffic Class 6 - Colors Green / Yellow / Red */ 54 [6][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 55 [6][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 56 [6][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 57 58 /* Traffic Class 7 - Colors Green / Yellow / Red */ 59 [7][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 60 [7][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 61 [7][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 62 63 /* Traffic Class 8 - Colors Green / Yellow / Red */ 64 [8][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 65 [8][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 66 [8][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 67 68 /* Traffic Class 9 - Colors Green / Yellow / Red */ 69 [9][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 70 [9][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 71 [9][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 72 73 /* Traffic Class 10 - Colors Green / Yellow / Red */ 74 [10][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 75 [10][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 76 [10][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 77 78 /* Traffic Class 11 - Colors Green / Yellow / Red */ 79 [11][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 80 [11][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 81 [11][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 82 83 /* Traffic Class 12 - Colors Green / Yellow / Red */ 84 [12][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 85 [12][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 86 [12][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, 87 }, 88 }; 89 #endif /* RTE_SCHED_CMAN */ 90 91 static uint32_t n_pipe_profiles; 92 93 static const struct rte_sched_subport_params subport_params_default = { 94 .n_pipes_per_subport_enabled = 0, /* filled at runtime */ 95 .qsize = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, 96 .pipe_profiles = pipe_profile, 97 .n_pipe_profiles = 0, /* filled at run time */ 98 .n_max_pipe_profiles = RTE_DIM(pipe_profile), 99 #ifdef RTE_SCHED_CMAN 100 .cman_params = &cman_params, 101 #endif /* RTE_SCHED_CMAN */ 102 }; 103 104 static struct tmgr_port_list tmgr_port_list; 105 106 int 107 tmgr_init(void) 108 { 109 TAILQ_INIT(&tmgr_port_list); 110 111 return 0; 112 } 113 114 struct tmgr_port * 115 tmgr_port_find(const char *name) 116 { 117 struct tmgr_port *tmgr_port; 118 119 if (name == NULL) 120 return NULL; 121 122 TAILQ_FOREACH(tmgr_port, &tmgr_port_list, node) 123 if (strcmp(tmgr_port->name, name) == 0) 124 return tmgr_port; 125 126 return NULL; 127 } 128 129 int 130 tmgr_subport_profile_add(struct rte_sched_subport_profile_params *params) 131 { 132 /* Check input params */ 133 if (params == NULL) 134 return -1; 135 136 /* Save profile */ 137 memcpy(&subport_profile[n_subport_profiles], 138 params, 139 sizeof(*params)); 140 141 n_subport_profiles++; 142 143 return 0; 144 } 145 146 int 147 tmgr_pipe_profile_add(struct rte_sched_pipe_params *p) 148 { 149 /* Check input params */ 150 if (p == NULL) 151 return -1; 152 153 /* Save profile */ 154 memcpy(&pipe_profile[n_pipe_profiles], 155 p, 156 sizeof(*p)); 157 158 n_pipe_profiles++; 159 160 return 0; 161 } 162 163 struct tmgr_port * 164 tmgr_port_create(const char *name, struct tmgr_port_params *params) 165 { 166 struct rte_sched_subport_params subport_params; 167 struct rte_sched_port_params p; 168 struct tmgr_port *tmgr_port; 169 struct rte_sched_port *s; 170 uint32_t i, j; 171 172 /* Check input params */ 173 if ((name == NULL) || 174 tmgr_port_find(name) || 175 (params == NULL) || 176 (params->n_subports_per_port == 0) || 177 (params->n_pipes_per_subport == 0) || 178 (params->cpu_id >= RTE_MAX_NUMA_NODES) || 179 (n_subport_profiles == 0) || 180 (n_pipe_profiles == 0)) 181 return NULL; 182 183 /* Resource create */ 184 p.name = name; 185 p.socket = (int) params->cpu_id; 186 p.rate = params->rate; 187 p.mtu = params->mtu; 188 p.frame_overhead = params->frame_overhead; 189 p.n_subports_per_port = params->n_subports_per_port; 190 p.n_subport_profiles = n_subport_profiles; 191 p.subport_profiles = subport_profile; 192 p.n_max_subport_profiles = TMGR_SUBPORT_PROFILE_MAX; 193 p.n_pipes_per_subport = params->n_pipes_per_subport; 194 195 196 s = rte_sched_port_config(&p); 197 if (s == NULL) 198 return NULL; 199 200 memcpy(&subport_params, &subport_params_default, 201 sizeof(subport_params_default)); 202 203 subport_params.n_pipe_profiles = n_pipe_profiles; 204 subport_params.n_pipes_per_subport_enabled = 205 params->n_pipes_per_subport; 206 207 for (i = 0; i < params->n_subports_per_port; i++) { 208 int status; 209 210 status = rte_sched_subport_config( 211 s, 212 i, 213 &subport_params, 214 0); 215 216 if (status) { 217 rte_sched_port_free(s); 218 return NULL; 219 } 220 221 for (j = 0; j < params->n_pipes_per_subport; j++) { 222 223 status = rte_sched_pipe_config( 224 s, 225 i, 226 j, 227 0); 228 229 if (status) { 230 rte_sched_port_free(s); 231 return NULL; 232 } 233 } 234 } 235 236 /* Node allocation */ 237 tmgr_port = calloc(1, sizeof(struct tmgr_port)); 238 if (tmgr_port == NULL) { 239 rte_sched_port_free(s); 240 return NULL; 241 } 242 243 /* Node fill in */ 244 strlcpy(tmgr_port->name, name, sizeof(tmgr_port->name)); 245 tmgr_port->s = s; 246 tmgr_port->n_subports_per_port = params->n_subports_per_port; 247 tmgr_port->n_pipes_per_subport = params->n_pipes_per_subport; 248 249 /* Node add to list */ 250 TAILQ_INSERT_TAIL(&tmgr_port_list, tmgr_port, node); 251 252 return tmgr_port; 253 } 254 255 int 256 tmgr_subport_config(const char *port_name, 257 uint32_t subport_id, 258 uint32_t subport_profile_id) 259 { 260 struct tmgr_port *port; 261 int status; 262 263 /* Check input params */ 264 if (port_name == NULL) 265 return -1; 266 267 port = tmgr_port_find(port_name); 268 if ((port == NULL) || 269 (subport_id >= port->n_subports_per_port) || 270 (subport_profile_id >= n_subport_profiles)) 271 return -1; 272 273 /* Resource config */ 274 status = rte_sched_subport_config( 275 port->s, 276 subport_id, 277 NULL, 278 subport_profile_id); 279 280 return status; 281 } 282 283 int 284 tmgr_pipe_config(const char *port_name, 285 uint32_t subport_id, 286 uint32_t pipe_id_first, 287 uint32_t pipe_id_last, 288 uint32_t pipe_profile_id) 289 { 290 struct tmgr_port *port; 291 uint32_t i; 292 293 /* Check input params */ 294 if (port_name == NULL) 295 return -1; 296 297 port = tmgr_port_find(port_name); 298 if ((port == NULL) || 299 (subport_id >= port->n_subports_per_port) || 300 (pipe_id_first >= port->n_pipes_per_subport) || 301 (pipe_id_last >= port->n_pipes_per_subport) || 302 (pipe_id_first > pipe_id_last) || 303 (pipe_profile_id >= n_pipe_profiles)) 304 return -1; 305 306 /* Resource config */ 307 for (i = pipe_id_first; i <= pipe_id_last; i++) { 308 int status; 309 310 status = rte_sched_pipe_config( 311 port->s, 312 subport_id, 313 i, 314 (int) pipe_profile_id); 315 316 if (status) 317 return status; 318 } 319 320 return 0; 321 } 322