xref: /dpdk/examples/ip_pipeline/tmgr.c (revision b53d106d34b5c638f5a2cbdfee0da5bd42d4383f)
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