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