xref: /dpdk/examples/pipeline/obj.c (revision b77f660028127061b05a8a14cc6c93becb9e73bb)
1*b77f6600SCristian Dumitrescu /* SPDX-License-Identifier: BSD-3-Clause
2*b77f6600SCristian Dumitrescu  * Copyright(c) 2020 Intel Corporation
3*b77f6600SCristian Dumitrescu  */
4*b77f6600SCristian Dumitrescu 
5*b77f6600SCristian Dumitrescu #include <stdlib.h>
6*b77f6600SCristian Dumitrescu #include <string.h>
7*b77f6600SCristian Dumitrescu 
8*b77f6600SCristian Dumitrescu #include <rte_mempool.h>
9*b77f6600SCristian Dumitrescu #include <rte_mbuf.h>
10*b77f6600SCristian Dumitrescu #include <rte_ethdev.h>
11*b77f6600SCristian Dumitrescu #include <rte_swx_port_ethdev.h>
12*b77f6600SCristian Dumitrescu #include <rte_swx_port_source_sink.h>
13*b77f6600SCristian Dumitrescu #include <rte_swx_table_em.h>
14*b77f6600SCristian Dumitrescu #include <rte_swx_pipeline.h>
15*b77f6600SCristian Dumitrescu #include <rte_swx_ctl.h>
16*b77f6600SCristian Dumitrescu 
17*b77f6600SCristian Dumitrescu #include "obj.h"
18*b77f6600SCristian Dumitrescu 
19*b77f6600SCristian Dumitrescu /*
20*b77f6600SCristian Dumitrescu  * mempool
21*b77f6600SCristian Dumitrescu  */
22*b77f6600SCristian Dumitrescu TAILQ_HEAD(mempool_list, mempool);
23*b77f6600SCristian Dumitrescu 
24*b77f6600SCristian Dumitrescu /*
25*b77f6600SCristian Dumitrescu  * link
26*b77f6600SCristian Dumitrescu  */
27*b77f6600SCristian Dumitrescu TAILQ_HEAD(link_list, link);
28*b77f6600SCristian Dumitrescu 
29*b77f6600SCristian Dumitrescu /*
30*b77f6600SCristian Dumitrescu  * pipeline
31*b77f6600SCristian Dumitrescu  */
32*b77f6600SCristian Dumitrescu TAILQ_HEAD(pipeline_list, pipeline);
33*b77f6600SCristian Dumitrescu 
34*b77f6600SCristian Dumitrescu /*
35*b77f6600SCristian Dumitrescu  * obj
36*b77f6600SCristian Dumitrescu  */
37*b77f6600SCristian Dumitrescu struct obj {
38*b77f6600SCristian Dumitrescu 	struct mempool_list mempool_list;
39*b77f6600SCristian Dumitrescu 	struct link_list link_list;
40*b77f6600SCristian Dumitrescu 	struct pipeline_list pipeline_list;
41*b77f6600SCristian Dumitrescu };
42*b77f6600SCristian Dumitrescu 
43*b77f6600SCristian Dumitrescu /*
44*b77f6600SCristian Dumitrescu  * mempool
45*b77f6600SCristian Dumitrescu  */
46*b77f6600SCristian Dumitrescu #define BUFFER_SIZE_MIN (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
47*b77f6600SCristian Dumitrescu 
48*b77f6600SCristian Dumitrescu struct mempool *
49*b77f6600SCristian Dumitrescu mempool_create(struct obj *obj, const char *name, struct mempool_params *params)
50*b77f6600SCristian Dumitrescu {
51*b77f6600SCristian Dumitrescu 	struct mempool *mempool;
52*b77f6600SCristian Dumitrescu 	struct rte_mempool *m;
53*b77f6600SCristian Dumitrescu 
54*b77f6600SCristian Dumitrescu 	/* Check input params */
55*b77f6600SCristian Dumitrescu 	if ((name == NULL) ||
56*b77f6600SCristian Dumitrescu 		mempool_find(obj, name) ||
57*b77f6600SCristian Dumitrescu 		(params == NULL) ||
58*b77f6600SCristian Dumitrescu 		(params->buffer_size < BUFFER_SIZE_MIN) ||
59*b77f6600SCristian Dumitrescu 		(params->pool_size == 0))
60*b77f6600SCristian Dumitrescu 		return NULL;
61*b77f6600SCristian Dumitrescu 
62*b77f6600SCristian Dumitrescu 	/* Resource create */
63*b77f6600SCristian Dumitrescu 	m = rte_pktmbuf_pool_create(
64*b77f6600SCristian Dumitrescu 		name,
65*b77f6600SCristian Dumitrescu 		params->pool_size,
66*b77f6600SCristian Dumitrescu 		params->cache_size,
67*b77f6600SCristian Dumitrescu 		0,
68*b77f6600SCristian Dumitrescu 		params->buffer_size - sizeof(struct rte_mbuf),
69*b77f6600SCristian Dumitrescu 		params->cpu_id);
70*b77f6600SCristian Dumitrescu 
71*b77f6600SCristian Dumitrescu 	if (m == NULL)
72*b77f6600SCristian Dumitrescu 		return NULL;
73*b77f6600SCristian Dumitrescu 
74*b77f6600SCristian Dumitrescu 	/* Node allocation */
75*b77f6600SCristian Dumitrescu 	mempool = calloc(1, sizeof(struct mempool));
76*b77f6600SCristian Dumitrescu 	if (mempool == NULL) {
77*b77f6600SCristian Dumitrescu 		rte_mempool_free(m);
78*b77f6600SCristian Dumitrescu 		return NULL;
79*b77f6600SCristian Dumitrescu 	}
80*b77f6600SCristian Dumitrescu 
81*b77f6600SCristian Dumitrescu 	/* Node fill in */
82*b77f6600SCristian Dumitrescu 	strlcpy(mempool->name, name, sizeof(mempool->name));
83*b77f6600SCristian Dumitrescu 	mempool->m = m;
84*b77f6600SCristian Dumitrescu 	mempool->buffer_size = params->buffer_size;
85*b77f6600SCristian Dumitrescu 
86*b77f6600SCristian Dumitrescu 	/* Node add to list */
87*b77f6600SCristian Dumitrescu 	TAILQ_INSERT_TAIL(&obj->mempool_list, mempool, node);
88*b77f6600SCristian Dumitrescu 
89*b77f6600SCristian Dumitrescu 	return mempool;
90*b77f6600SCristian Dumitrescu }
91*b77f6600SCristian Dumitrescu 
92*b77f6600SCristian Dumitrescu struct mempool *
93*b77f6600SCristian Dumitrescu mempool_find(struct obj *obj, const char *name)
94*b77f6600SCristian Dumitrescu {
95*b77f6600SCristian Dumitrescu 	struct mempool *mempool;
96*b77f6600SCristian Dumitrescu 
97*b77f6600SCristian Dumitrescu 	if (!obj || !name)
98*b77f6600SCristian Dumitrescu 		return NULL;
99*b77f6600SCristian Dumitrescu 
100*b77f6600SCristian Dumitrescu 	TAILQ_FOREACH(mempool, &obj->mempool_list, node)
101*b77f6600SCristian Dumitrescu 		if (strcmp(mempool->name, name) == 0)
102*b77f6600SCristian Dumitrescu 			return mempool;
103*b77f6600SCristian Dumitrescu 
104*b77f6600SCristian Dumitrescu 	return NULL;
105*b77f6600SCristian Dumitrescu }
106*b77f6600SCristian Dumitrescu 
107*b77f6600SCristian Dumitrescu /*
108*b77f6600SCristian Dumitrescu  * link
109*b77f6600SCristian Dumitrescu  */
110*b77f6600SCristian Dumitrescu static struct rte_eth_conf port_conf_default = {
111*b77f6600SCristian Dumitrescu 	.link_speeds = 0,
112*b77f6600SCristian Dumitrescu 	.rxmode = {
113*b77f6600SCristian Dumitrescu 		.mq_mode = ETH_MQ_RX_NONE,
114*b77f6600SCristian Dumitrescu 		.max_rx_pkt_len = 9000, /* Jumbo frame max packet len */
115*b77f6600SCristian Dumitrescu 		.split_hdr_size = 0, /* Header split buffer size */
116*b77f6600SCristian Dumitrescu 	},
117*b77f6600SCristian Dumitrescu 	.rx_adv_conf = {
118*b77f6600SCristian Dumitrescu 		.rss_conf = {
119*b77f6600SCristian Dumitrescu 			.rss_key = NULL,
120*b77f6600SCristian Dumitrescu 			.rss_key_len = 40,
121*b77f6600SCristian Dumitrescu 			.rss_hf = 0,
122*b77f6600SCristian Dumitrescu 		},
123*b77f6600SCristian Dumitrescu 	},
124*b77f6600SCristian Dumitrescu 	.txmode = {
125*b77f6600SCristian Dumitrescu 		.mq_mode = ETH_MQ_TX_NONE,
126*b77f6600SCristian Dumitrescu 	},
127*b77f6600SCristian Dumitrescu 	.lpbk_mode = 0,
128*b77f6600SCristian Dumitrescu };
129*b77f6600SCristian Dumitrescu 
130*b77f6600SCristian Dumitrescu #define RETA_CONF_SIZE     (ETH_RSS_RETA_SIZE_512 / RTE_RETA_GROUP_SIZE)
131*b77f6600SCristian Dumitrescu 
132*b77f6600SCristian Dumitrescu static int
133*b77f6600SCristian Dumitrescu rss_setup(uint16_t port_id,
134*b77f6600SCristian Dumitrescu 	uint16_t reta_size,
135*b77f6600SCristian Dumitrescu 	struct link_params_rss *rss)
136*b77f6600SCristian Dumitrescu {
137*b77f6600SCristian Dumitrescu 	struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE];
138*b77f6600SCristian Dumitrescu 	uint32_t i;
139*b77f6600SCristian Dumitrescu 	int status;
140*b77f6600SCristian Dumitrescu 
141*b77f6600SCristian Dumitrescu 	/* RETA setting */
142*b77f6600SCristian Dumitrescu 	memset(reta_conf, 0, sizeof(reta_conf));
143*b77f6600SCristian Dumitrescu 
144*b77f6600SCristian Dumitrescu 	for (i = 0; i < reta_size; i++)
145*b77f6600SCristian Dumitrescu 		reta_conf[i / RTE_RETA_GROUP_SIZE].mask = UINT64_MAX;
146*b77f6600SCristian Dumitrescu 
147*b77f6600SCristian Dumitrescu 	for (i = 0; i < reta_size; i++) {
148*b77f6600SCristian Dumitrescu 		uint32_t reta_id = i / RTE_RETA_GROUP_SIZE;
149*b77f6600SCristian Dumitrescu 		uint32_t reta_pos = i % RTE_RETA_GROUP_SIZE;
150*b77f6600SCristian Dumitrescu 		uint32_t rss_qs_pos = i % rss->n_queues;
151*b77f6600SCristian Dumitrescu 
152*b77f6600SCristian Dumitrescu 		reta_conf[reta_id].reta[reta_pos] =
153*b77f6600SCristian Dumitrescu 			(uint16_t) rss->queue_id[rss_qs_pos];
154*b77f6600SCristian Dumitrescu 	}
155*b77f6600SCristian Dumitrescu 
156*b77f6600SCristian Dumitrescu 	/* RETA update */
157*b77f6600SCristian Dumitrescu 	status = rte_eth_dev_rss_reta_update(port_id,
158*b77f6600SCristian Dumitrescu 		reta_conf,
159*b77f6600SCristian Dumitrescu 		reta_size);
160*b77f6600SCristian Dumitrescu 
161*b77f6600SCristian Dumitrescu 	return status;
162*b77f6600SCristian Dumitrescu }
163*b77f6600SCristian Dumitrescu 
164*b77f6600SCristian Dumitrescu struct link *
165*b77f6600SCristian Dumitrescu link_create(struct obj *obj, const char *name, struct link_params *params)
166*b77f6600SCristian Dumitrescu {
167*b77f6600SCristian Dumitrescu 	struct rte_eth_dev_info port_info;
168*b77f6600SCristian Dumitrescu 	struct rte_eth_conf port_conf;
169*b77f6600SCristian Dumitrescu 	struct link *link;
170*b77f6600SCristian Dumitrescu 	struct link_params_rss *rss;
171*b77f6600SCristian Dumitrescu 	struct mempool *mempool;
172*b77f6600SCristian Dumitrescu 	uint32_t cpu_id, i;
173*b77f6600SCristian Dumitrescu 	int status;
174*b77f6600SCristian Dumitrescu 	uint16_t port_id;
175*b77f6600SCristian Dumitrescu 
176*b77f6600SCristian Dumitrescu 	/* Check input params */
177*b77f6600SCristian Dumitrescu 	if ((name == NULL) ||
178*b77f6600SCristian Dumitrescu 		link_find(obj, name) ||
179*b77f6600SCristian Dumitrescu 		(params == NULL) ||
180*b77f6600SCristian Dumitrescu 		(params->rx.n_queues == 0) ||
181*b77f6600SCristian Dumitrescu 		(params->rx.queue_size == 0) ||
182*b77f6600SCristian Dumitrescu 		(params->tx.n_queues == 0) ||
183*b77f6600SCristian Dumitrescu 		(params->tx.queue_size == 0))
184*b77f6600SCristian Dumitrescu 		return NULL;
185*b77f6600SCristian Dumitrescu 
186*b77f6600SCristian Dumitrescu 	port_id = params->port_id;
187*b77f6600SCristian Dumitrescu 	if (params->dev_name) {
188*b77f6600SCristian Dumitrescu 		status = rte_eth_dev_get_port_by_name(params->dev_name,
189*b77f6600SCristian Dumitrescu 			&port_id);
190*b77f6600SCristian Dumitrescu 
191*b77f6600SCristian Dumitrescu 		if (status)
192*b77f6600SCristian Dumitrescu 			return NULL;
193*b77f6600SCristian Dumitrescu 	} else
194*b77f6600SCristian Dumitrescu 		if (!rte_eth_dev_is_valid_port(port_id))
195*b77f6600SCristian Dumitrescu 			return NULL;
196*b77f6600SCristian Dumitrescu 
197*b77f6600SCristian Dumitrescu 	if (rte_eth_dev_info_get(port_id, &port_info) != 0)
198*b77f6600SCristian Dumitrescu 		return NULL;
199*b77f6600SCristian Dumitrescu 
200*b77f6600SCristian Dumitrescu 	mempool = mempool_find(obj, params->rx.mempool_name);
201*b77f6600SCristian Dumitrescu 	if (mempool == NULL)
202*b77f6600SCristian Dumitrescu 		return NULL;
203*b77f6600SCristian Dumitrescu 
204*b77f6600SCristian Dumitrescu 	rss = params->rx.rss;
205*b77f6600SCristian Dumitrescu 	if (rss) {
206*b77f6600SCristian Dumitrescu 		if ((port_info.reta_size == 0) ||
207*b77f6600SCristian Dumitrescu 			(port_info.reta_size > ETH_RSS_RETA_SIZE_512))
208*b77f6600SCristian Dumitrescu 			return NULL;
209*b77f6600SCristian Dumitrescu 
210*b77f6600SCristian Dumitrescu 		if ((rss->n_queues == 0) ||
211*b77f6600SCristian Dumitrescu 			(rss->n_queues >= LINK_RXQ_RSS_MAX))
212*b77f6600SCristian Dumitrescu 			return NULL;
213*b77f6600SCristian Dumitrescu 
214*b77f6600SCristian Dumitrescu 		for (i = 0; i < rss->n_queues; i++)
215*b77f6600SCristian Dumitrescu 			if (rss->queue_id[i] >= port_info.max_rx_queues)
216*b77f6600SCristian Dumitrescu 				return NULL;
217*b77f6600SCristian Dumitrescu 	}
218*b77f6600SCristian Dumitrescu 
219*b77f6600SCristian Dumitrescu 	/**
220*b77f6600SCristian Dumitrescu 	 * Resource create
221*b77f6600SCristian Dumitrescu 	 */
222*b77f6600SCristian Dumitrescu 	/* Port */
223*b77f6600SCristian Dumitrescu 	memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
224*b77f6600SCristian Dumitrescu 	if (rss) {
225*b77f6600SCristian Dumitrescu 		port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
226*b77f6600SCristian Dumitrescu 		port_conf.rx_adv_conf.rss_conf.rss_hf =
227*b77f6600SCristian Dumitrescu 			(ETH_RSS_IP | ETH_RSS_TCP | ETH_RSS_UDP) &
228*b77f6600SCristian Dumitrescu 			port_info.flow_type_rss_offloads;
229*b77f6600SCristian Dumitrescu 	}
230*b77f6600SCristian Dumitrescu 
231*b77f6600SCristian Dumitrescu 	cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id);
232*b77f6600SCristian Dumitrescu 	if (cpu_id == (uint32_t) SOCKET_ID_ANY)
233*b77f6600SCristian Dumitrescu 		cpu_id = 0;
234*b77f6600SCristian Dumitrescu 
235*b77f6600SCristian Dumitrescu 	status = rte_eth_dev_configure(
236*b77f6600SCristian Dumitrescu 		port_id,
237*b77f6600SCristian Dumitrescu 		params->rx.n_queues,
238*b77f6600SCristian Dumitrescu 		params->tx.n_queues,
239*b77f6600SCristian Dumitrescu 		&port_conf);
240*b77f6600SCristian Dumitrescu 
241*b77f6600SCristian Dumitrescu 	if (status < 0)
242*b77f6600SCristian Dumitrescu 		return NULL;
243*b77f6600SCristian Dumitrescu 
244*b77f6600SCristian Dumitrescu 	if (params->promiscuous) {
245*b77f6600SCristian Dumitrescu 		status = rte_eth_promiscuous_enable(port_id);
246*b77f6600SCristian Dumitrescu 		if (status != 0)
247*b77f6600SCristian Dumitrescu 			return NULL;
248*b77f6600SCristian Dumitrescu 	}
249*b77f6600SCristian Dumitrescu 
250*b77f6600SCristian Dumitrescu 	/* Port RX */
251*b77f6600SCristian Dumitrescu 	for (i = 0; i < params->rx.n_queues; i++) {
252*b77f6600SCristian Dumitrescu 		status = rte_eth_rx_queue_setup(
253*b77f6600SCristian Dumitrescu 			port_id,
254*b77f6600SCristian Dumitrescu 			i,
255*b77f6600SCristian Dumitrescu 			params->rx.queue_size,
256*b77f6600SCristian Dumitrescu 			cpu_id,
257*b77f6600SCristian Dumitrescu 			NULL,
258*b77f6600SCristian Dumitrescu 			mempool->m);
259*b77f6600SCristian Dumitrescu 
260*b77f6600SCristian Dumitrescu 		if (status < 0)
261*b77f6600SCristian Dumitrescu 			return NULL;
262*b77f6600SCristian Dumitrescu 	}
263*b77f6600SCristian Dumitrescu 
264*b77f6600SCristian Dumitrescu 	/* Port TX */
265*b77f6600SCristian Dumitrescu 	for (i = 0; i < params->tx.n_queues; i++) {
266*b77f6600SCristian Dumitrescu 		status = rte_eth_tx_queue_setup(
267*b77f6600SCristian Dumitrescu 			port_id,
268*b77f6600SCristian Dumitrescu 			i,
269*b77f6600SCristian Dumitrescu 			params->tx.queue_size,
270*b77f6600SCristian Dumitrescu 			cpu_id,
271*b77f6600SCristian Dumitrescu 			NULL);
272*b77f6600SCristian Dumitrescu 
273*b77f6600SCristian Dumitrescu 		if (status < 0)
274*b77f6600SCristian Dumitrescu 			return NULL;
275*b77f6600SCristian Dumitrescu 	}
276*b77f6600SCristian Dumitrescu 
277*b77f6600SCristian Dumitrescu 	/* Port start */
278*b77f6600SCristian Dumitrescu 	status = rte_eth_dev_start(port_id);
279*b77f6600SCristian Dumitrescu 	if (status < 0)
280*b77f6600SCristian Dumitrescu 		return NULL;
281*b77f6600SCristian Dumitrescu 
282*b77f6600SCristian Dumitrescu 	if (rss) {
283*b77f6600SCristian Dumitrescu 		status = rss_setup(port_id, port_info.reta_size, rss);
284*b77f6600SCristian Dumitrescu 
285*b77f6600SCristian Dumitrescu 		if (status) {
286*b77f6600SCristian Dumitrescu 			rte_eth_dev_stop(port_id);
287*b77f6600SCristian Dumitrescu 			return NULL;
288*b77f6600SCristian Dumitrescu 		}
289*b77f6600SCristian Dumitrescu 	}
290*b77f6600SCristian Dumitrescu 
291*b77f6600SCristian Dumitrescu 	/* Port link up */
292*b77f6600SCristian Dumitrescu 	status = rte_eth_dev_set_link_up(port_id);
293*b77f6600SCristian Dumitrescu 	if ((status < 0) && (status != -ENOTSUP)) {
294*b77f6600SCristian Dumitrescu 		rte_eth_dev_stop(port_id);
295*b77f6600SCristian Dumitrescu 		return NULL;
296*b77f6600SCristian Dumitrescu 	}
297*b77f6600SCristian Dumitrescu 
298*b77f6600SCristian Dumitrescu 	/* Node allocation */
299*b77f6600SCristian Dumitrescu 	link = calloc(1, sizeof(struct link));
300*b77f6600SCristian Dumitrescu 	if (link == NULL) {
301*b77f6600SCristian Dumitrescu 		rte_eth_dev_stop(port_id);
302*b77f6600SCristian Dumitrescu 		return NULL;
303*b77f6600SCristian Dumitrescu 	}
304*b77f6600SCristian Dumitrescu 
305*b77f6600SCristian Dumitrescu 	/* Node fill in */
306*b77f6600SCristian Dumitrescu 	strlcpy(link->name, name, sizeof(link->name));
307*b77f6600SCristian Dumitrescu 	link->port_id = port_id;
308*b77f6600SCristian Dumitrescu 	rte_eth_dev_get_name_by_port(port_id, link->dev_name);
309*b77f6600SCristian Dumitrescu 	link->n_rxq = params->rx.n_queues;
310*b77f6600SCristian Dumitrescu 	link->n_txq = params->tx.n_queues;
311*b77f6600SCristian Dumitrescu 
312*b77f6600SCristian Dumitrescu 	/* Node add to list */
313*b77f6600SCristian Dumitrescu 	TAILQ_INSERT_TAIL(&obj->link_list, link, node);
314*b77f6600SCristian Dumitrescu 
315*b77f6600SCristian Dumitrescu 	return link;
316*b77f6600SCristian Dumitrescu }
317*b77f6600SCristian Dumitrescu 
318*b77f6600SCristian Dumitrescu int
319*b77f6600SCristian Dumitrescu link_is_up(struct obj *obj, const char *name)
320*b77f6600SCristian Dumitrescu {
321*b77f6600SCristian Dumitrescu 	struct rte_eth_link link_params;
322*b77f6600SCristian Dumitrescu 	struct link *link;
323*b77f6600SCristian Dumitrescu 
324*b77f6600SCristian Dumitrescu 	/* Check input params */
325*b77f6600SCristian Dumitrescu 	if (!obj || !name)
326*b77f6600SCristian Dumitrescu 		return 0;
327*b77f6600SCristian Dumitrescu 
328*b77f6600SCristian Dumitrescu 	link = link_find(obj, name);
329*b77f6600SCristian Dumitrescu 	if (link == NULL)
330*b77f6600SCristian Dumitrescu 		return 0;
331*b77f6600SCristian Dumitrescu 
332*b77f6600SCristian Dumitrescu 	/* Resource */
333*b77f6600SCristian Dumitrescu 	if (rte_eth_link_get(link->port_id, &link_params) < 0)
334*b77f6600SCristian Dumitrescu 		return 0;
335*b77f6600SCristian Dumitrescu 
336*b77f6600SCristian Dumitrescu 	return (link_params.link_status == ETH_LINK_DOWN) ? 0 : 1;
337*b77f6600SCristian Dumitrescu }
338*b77f6600SCristian Dumitrescu 
339*b77f6600SCristian Dumitrescu struct link *
340*b77f6600SCristian Dumitrescu link_find(struct obj *obj, const char *name)
341*b77f6600SCristian Dumitrescu {
342*b77f6600SCristian Dumitrescu 	struct link *link;
343*b77f6600SCristian Dumitrescu 
344*b77f6600SCristian Dumitrescu 	if (!obj || !name)
345*b77f6600SCristian Dumitrescu 		return NULL;
346*b77f6600SCristian Dumitrescu 
347*b77f6600SCristian Dumitrescu 	TAILQ_FOREACH(link, &obj->link_list, node)
348*b77f6600SCristian Dumitrescu 		if (strcmp(link->name, name) == 0)
349*b77f6600SCristian Dumitrescu 			return link;
350*b77f6600SCristian Dumitrescu 
351*b77f6600SCristian Dumitrescu 	return NULL;
352*b77f6600SCristian Dumitrescu }
353*b77f6600SCristian Dumitrescu 
354*b77f6600SCristian Dumitrescu struct link *
355*b77f6600SCristian Dumitrescu link_next(struct obj *obj, struct link *link)
356*b77f6600SCristian Dumitrescu {
357*b77f6600SCristian Dumitrescu 	return (link == NULL) ?
358*b77f6600SCristian Dumitrescu 		TAILQ_FIRST(&obj->link_list) : TAILQ_NEXT(link, node);
359*b77f6600SCristian Dumitrescu }
360*b77f6600SCristian Dumitrescu 
361*b77f6600SCristian Dumitrescu /*
362*b77f6600SCristian Dumitrescu  * pipeline
363*b77f6600SCristian Dumitrescu  */
364*b77f6600SCristian Dumitrescu #ifndef PIPELINE_MSGQ_SIZE
365*b77f6600SCristian Dumitrescu #define PIPELINE_MSGQ_SIZE                                 64
366*b77f6600SCristian Dumitrescu #endif
367*b77f6600SCristian Dumitrescu 
368*b77f6600SCristian Dumitrescu struct pipeline *
369*b77f6600SCristian Dumitrescu pipeline_create(struct obj *obj, const char *name, int numa_node)
370*b77f6600SCristian Dumitrescu {
371*b77f6600SCristian Dumitrescu 	struct pipeline *pipeline;
372*b77f6600SCristian Dumitrescu 	struct rte_swx_pipeline *p = NULL;
373*b77f6600SCristian Dumitrescu 	int status;
374*b77f6600SCristian Dumitrescu 
375*b77f6600SCristian Dumitrescu 	/* Check input params */
376*b77f6600SCristian Dumitrescu 	if ((name == NULL) ||
377*b77f6600SCristian Dumitrescu 		pipeline_find(obj, name))
378*b77f6600SCristian Dumitrescu 		return NULL;
379*b77f6600SCristian Dumitrescu 
380*b77f6600SCristian Dumitrescu 	/* Resource create */
381*b77f6600SCristian Dumitrescu 	status = rte_swx_pipeline_config(&p, numa_node);
382*b77f6600SCristian Dumitrescu 	if (status)
383*b77f6600SCristian Dumitrescu 		goto error;
384*b77f6600SCristian Dumitrescu 
385*b77f6600SCristian Dumitrescu 	status = rte_swx_pipeline_port_in_type_register(p,
386*b77f6600SCristian Dumitrescu 		"ethdev",
387*b77f6600SCristian Dumitrescu 		&rte_swx_port_ethdev_reader_ops);
388*b77f6600SCristian Dumitrescu 	if (status)
389*b77f6600SCristian Dumitrescu 		goto error;
390*b77f6600SCristian Dumitrescu 
391*b77f6600SCristian Dumitrescu 	status = rte_swx_pipeline_port_out_type_register(p,
392*b77f6600SCristian Dumitrescu 		"ethdev",
393*b77f6600SCristian Dumitrescu 		&rte_swx_port_ethdev_writer_ops);
394*b77f6600SCristian Dumitrescu 	if (status)
395*b77f6600SCristian Dumitrescu 		goto error;
396*b77f6600SCristian Dumitrescu 
397*b77f6600SCristian Dumitrescu #ifdef RTE_PORT_PCAP
398*b77f6600SCristian Dumitrescu 	status = rte_swx_pipeline_port_in_type_register(p,
399*b77f6600SCristian Dumitrescu 		"source",
400*b77f6600SCristian Dumitrescu 		&rte_swx_port_source_ops);
401*b77f6600SCristian Dumitrescu 	if (status)
402*b77f6600SCristian Dumitrescu 		goto error;
403*b77f6600SCristian Dumitrescu #endif
404*b77f6600SCristian Dumitrescu 
405*b77f6600SCristian Dumitrescu 	status = rte_swx_pipeline_port_out_type_register(p,
406*b77f6600SCristian Dumitrescu 		"sink",
407*b77f6600SCristian Dumitrescu 		&rte_swx_port_sink_ops);
408*b77f6600SCristian Dumitrescu 	if (status)
409*b77f6600SCristian Dumitrescu 		goto error;
410*b77f6600SCristian Dumitrescu 
411*b77f6600SCristian Dumitrescu 	status = rte_swx_pipeline_table_type_register(p,
412*b77f6600SCristian Dumitrescu 		"exact",
413*b77f6600SCristian Dumitrescu 		RTE_SWX_TABLE_MATCH_EXACT,
414*b77f6600SCristian Dumitrescu 		&rte_swx_table_exact_match_ops);
415*b77f6600SCristian Dumitrescu 	if (status)
416*b77f6600SCristian Dumitrescu 		goto error;
417*b77f6600SCristian Dumitrescu 
418*b77f6600SCristian Dumitrescu 	/* Node allocation */
419*b77f6600SCristian Dumitrescu 	pipeline = calloc(1, sizeof(struct pipeline));
420*b77f6600SCristian Dumitrescu 	if (pipeline == NULL)
421*b77f6600SCristian Dumitrescu 		goto error;
422*b77f6600SCristian Dumitrescu 
423*b77f6600SCristian Dumitrescu 	/* Node fill in */
424*b77f6600SCristian Dumitrescu 	strlcpy(pipeline->name, name, sizeof(pipeline->name));
425*b77f6600SCristian Dumitrescu 	pipeline->p = p;
426*b77f6600SCristian Dumitrescu 	pipeline->timer_period_ms = 10;
427*b77f6600SCristian Dumitrescu 
428*b77f6600SCristian Dumitrescu 	/* Node add to list */
429*b77f6600SCristian Dumitrescu 	TAILQ_INSERT_TAIL(&obj->pipeline_list, pipeline, node);
430*b77f6600SCristian Dumitrescu 
431*b77f6600SCristian Dumitrescu 	return pipeline;
432*b77f6600SCristian Dumitrescu 
433*b77f6600SCristian Dumitrescu error:
434*b77f6600SCristian Dumitrescu 	rte_swx_pipeline_free(p);
435*b77f6600SCristian Dumitrescu 	return NULL;
436*b77f6600SCristian Dumitrescu }
437*b77f6600SCristian Dumitrescu 
438*b77f6600SCristian Dumitrescu struct pipeline *
439*b77f6600SCristian Dumitrescu pipeline_find(struct obj *obj, const char *name)
440*b77f6600SCristian Dumitrescu {
441*b77f6600SCristian Dumitrescu 	struct pipeline *pipeline;
442*b77f6600SCristian Dumitrescu 
443*b77f6600SCristian Dumitrescu 	if (!obj || !name)
444*b77f6600SCristian Dumitrescu 		return NULL;
445*b77f6600SCristian Dumitrescu 
446*b77f6600SCristian Dumitrescu 	TAILQ_FOREACH(pipeline, &obj->pipeline_list, node)
447*b77f6600SCristian Dumitrescu 		if (strcmp(name, pipeline->name) == 0)
448*b77f6600SCristian Dumitrescu 			return pipeline;
449*b77f6600SCristian Dumitrescu 
450*b77f6600SCristian Dumitrescu 	return NULL;
451*b77f6600SCristian Dumitrescu }
452*b77f6600SCristian Dumitrescu 
453*b77f6600SCristian Dumitrescu /*
454*b77f6600SCristian Dumitrescu  * obj
455*b77f6600SCristian Dumitrescu  */
456*b77f6600SCristian Dumitrescu struct obj *
457*b77f6600SCristian Dumitrescu obj_init(void)
458*b77f6600SCristian Dumitrescu {
459*b77f6600SCristian Dumitrescu 	struct obj *obj;
460*b77f6600SCristian Dumitrescu 
461*b77f6600SCristian Dumitrescu 	obj = calloc(1, sizeof(struct obj));
462*b77f6600SCristian Dumitrescu 	if (!obj)
463*b77f6600SCristian Dumitrescu 		return NULL;
464*b77f6600SCristian Dumitrescu 
465*b77f6600SCristian Dumitrescu 	TAILQ_INIT(&obj->mempool_list);
466*b77f6600SCristian Dumitrescu 	TAILQ_INIT(&obj->link_list);
467*b77f6600SCristian Dumitrescu 	TAILQ_INIT(&obj->pipeline_list);
468*b77f6600SCristian Dumitrescu 
469*b77f6600SCristian Dumitrescu 	return obj;
470*b77f6600SCristian Dumitrescu }
471