1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Intel Corporation
10 #include <rte_common.h>
12 #include "rte_swx_pipeline.h"
14 #define CHECK(condition, err_code) \
20 #define CHECK_NAME(name, err_code) \
21 CHECK((name) && (name)[0], err_code)
27 TAILQ_ENTRY(port_in_type) node;
28 char name[RTE_SWX_NAME_SIZE];
29 struct rte_swx_port_in_ops ops;
32 TAILQ_HEAD(port_in_type_tailq, port_in_type);
35 TAILQ_ENTRY(port_in) node;
36 struct port_in_type *type;
41 TAILQ_HEAD(port_in_tailq, port_in);
43 struct port_in_runtime {
44 rte_swx_port_in_pkt_rx_t pkt_rx;
51 struct rte_swx_pipeline {
52 struct port_in_type_tailq port_in_types;
53 struct port_in_tailq ports_in;
55 struct port_in_runtime *in;
65 static struct port_in_type *
66 port_in_type_find(struct rte_swx_pipeline *p, const char *name)
68 struct port_in_type *elem;
73 TAILQ_FOREACH(elem, &p->port_in_types, node)
74 if (strcmp(elem->name, name) == 0)
81 rte_swx_pipeline_port_in_type_register(struct rte_swx_pipeline *p,
83 struct rte_swx_port_in_ops *ops)
85 struct port_in_type *elem;
88 CHECK_NAME(name, EINVAL);
90 CHECK(ops->create, EINVAL);
91 CHECK(ops->free, EINVAL);
92 CHECK(ops->pkt_rx, EINVAL);
93 CHECK(ops->stats_read, EINVAL);
95 CHECK(!port_in_type_find(p, name), EEXIST);
97 /* Node allocation. */
98 elem = calloc(1, sizeof(struct port_in_type));
101 /* Node initialization. */
102 strcpy(elem->name, name);
103 memcpy(&elem->ops, ops, sizeof(*ops));
105 /* Node add to tailq. */
106 TAILQ_INSERT_TAIL(&p->port_in_types, elem, node);
111 static struct port_in *
112 port_in_find(struct rte_swx_pipeline *p, uint32_t port_id)
114 struct port_in *port;
116 TAILQ_FOREACH(port, &p->ports_in, node)
117 if (port->id == port_id)
124 rte_swx_pipeline_port_in_config(struct rte_swx_pipeline *p,
126 const char *port_type_name,
129 struct port_in_type *type = NULL;
130 struct port_in *port = NULL;
135 CHECK(!port_in_find(p, port_id), EINVAL);
137 CHECK_NAME(port_type_name, EINVAL);
138 type = port_in_type_find(p, port_type_name);
141 obj = type->ops.create(args);
144 /* Node allocation. */
145 port = calloc(1, sizeof(struct port_in));
148 /* Node initialization. */
153 /* Node add to tailq. */
154 TAILQ_INSERT_TAIL(&p->ports_in, port, node);
155 if (p->n_ports_in < port_id + 1)
156 p->n_ports_in = port_id + 1;
162 port_in_build(struct rte_swx_pipeline *p)
164 struct port_in *port;
167 CHECK(p->n_ports_in, EINVAL);
168 CHECK(rte_is_power_of_2(p->n_ports_in), EINVAL);
170 for (i = 0; i < p->n_ports_in; i++)
171 CHECK(port_in_find(p, i), EINVAL);
173 p->in = calloc(p->n_ports_in, sizeof(struct port_in_runtime));
174 CHECK(p->in, ENOMEM);
176 TAILQ_FOREACH(port, &p->ports_in, node) {
177 struct port_in_runtime *in = &p->in[port->id];
179 in->pkt_rx = port->type->ops.pkt_rx;
187 port_in_build_free(struct rte_swx_pipeline *p)
194 port_in_free(struct rte_swx_pipeline *p)
196 port_in_build_free(p);
200 struct port_in *port;
202 port = TAILQ_FIRST(&p->ports_in);
206 TAILQ_REMOVE(&p->ports_in, port, node);
207 port->type->ops.free(port->obj);
211 /* Input port types. */
213 struct port_in_type *elem;
215 elem = TAILQ_FIRST(&p->port_in_types);
219 TAILQ_REMOVE(&p->port_in_types, elem, node);
228 rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node)
230 struct rte_swx_pipeline *pipeline;
232 /* Check input parameters. */
235 /* Memory allocation. */
236 pipeline = calloc(1, sizeof(struct rte_swx_pipeline));
237 CHECK(pipeline, ENOMEM);
239 /* Initialization. */
240 TAILQ_INIT(&pipeline->port_in_types);
241 TAILQ_INIT(&pipeline->ports_in);
243 pipeline->numa_node = numa_node;
250 rte_swx_pipeline_free(struct rte_swx_pipeline *p)
261 rte_swx_pipeline_build(struct rte_swx_pipeline *p)
266 CHECK(p->build_done == 0, EEXIST);
268 status = port_in_build(p);
276 port_in_build_free(p);