xref: /dpdk/lib/node/ethdev_ctrl.c (revision 77b88bf5c6af4fa24a3562fa027e6e09443e95a3)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(C) 2020 Marvell International Ltd.
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
5*77b88bf5SRakesh Kudurumalla #include <errno.h>
672b452c5SDmitry Kozlyuk #include <stdlib.h>
772b452c5SDmitry Kozlyuk 
899a2dd95SBruce Richardson #include <rte_ethdev.h>
999a2dd95SBruce Richardson #include <rte_graph.h>
1099a2dd95SBruce Richardson 
1199a2dd95SBruce Richardson #include "rte_node_eth_api.h"
1299a2dd95SBruce Richardson 
1399a2dd95SBruce Richardson #include "ethdev_rx_priv.h"
1499a2dd95SBruce Richardson #include "ethdev_tx_priv.h"
1599a2dd95SBruce Richardson #include "ip4_rewrite_priv.h"
1616ac29cbSAmit Prakash Shukla #include "ip6_rewrite_priv.h"
1799a2dd95SBruce Richardson #include "node_private.h"
1899a2dd95SBruce Richardson 
1999a2dd95SBruce Richardson static struct ethdev_ctrl {
2099a2dd95SBruce Richardson 	uint16_t nb_graphs;
2199a2dd95SBruce Richardson } ctrl;
2299a2dd95SBruce Richardson 
2399a2dd95SBruce Richardson int
rte_node_eth_config(struct rte_node_ethdev_config * conf,uint16_t nb_confs,uint16_t nb_graphs)2499a2dd95SBruce Richardson rte_node_eth_config(struct rte_node_ethdev_config *conf, uint16_t nb_confs,
2599a2dd95SBruce Richardson 		    uint16_t nb_graphs)
2699a2dd95SBruce Richardson {
2799a2dd95SBruce Richardson 	struct rte_node_register *ip4_rewrite_node;
2816ac29cbSAmit Prakash Shukla 	struct rte_node_register *ip6_rewrite_node;
2999a2dd95SBruce Richardson 	struct ethdev_tx_node_main *tx_node_data;
3099a2dd95SBruce Richardson 	uint16_t tx_q_used, rx_q_used, port_id;
3199a2dd95SBruce Richardson 	struct rte_node_register *tx_node;
3299a2dd95SBruce Richardson 	char name[RTE_NODE_NAMESIZE];
3399a2dd95SBruce Richardson 	const char *next_nodes = name;
3499a2dd95SBruce Richardson 	struct rte_mempool *mp;
3599a2dd95SBruce Richardson 	int i, j, rc;
3699a2dd95SBruce Richardson 	uint32_t id;
3799a2dd95SBruce Richardson 
3899a2dd95SBruce Richardson 	ip4_rewrite_node = ip4_rewrite_node_get();
3916ac29cbSAmit Prakash Shukla 	ip6_rewrite_node = ip6_rewrite_node_get();
4099a2dd95SBruce Richardson 	tx_node_data = ethdev_tx_node_data_get();
4199a2dd95SBruce Richardson 	tx_node = ethdev_tx_node_get();
4299a2dd95SBruce Richardson 	for (i = 0; i < nb_confs; i++) {
4399a2dd95SBruce Richardson 		port_id = conf[i].port_id;
4499a2dd95SBruce Richardson 
4599a2dd95SBruce Richardson 		if (!rte_eth_dev_is_valid_port(port_id))
4699a2dd95SBruce Richardson 			return -EINVAL;
4799a2dd95SBruce Richardson 
4899a2dd95SBruce Richardson 		/* Check for mbuf minimum private size requirement */
4999a2dd95SBruce Richardson 		for (j = 0; j < conf[i].mp_count; j++) {
5099a2dd95SBruce Richardson 			mp = conf[i].mp[j];
5199a2dd95SBruce Richardson 			if (!mp)
5299a2dd95SBruce Richardson 				continue;
5399a2dd95SBruce Richardson 			/* Check for minimum private space */
5499a2dd95SBruce Richardson 			if (rte_pktmbuf_priv_size(mp) < NODE_MBUF_PRIV2_SIZE) {
5599a2dd95SBruce Richardson 				node_err("ethdev",
5699a2dd95SBruce Richardson 					 "Minimum mbuf priv size requirement not met by mp %s",
5799a2dd95SBruce Richardson 					 mp->name);
5899a2dd95SBruce Richardson 				return -EINVAL;
5999a2dd95SBruce Richardson 			}
6099a2dd95SBruce Richardson 		}
6199a2dd95SBruce Richardson 
6299a2dd95SBruce Richardson 		rx_q_used = conf[i].num_rx_queues;
6399a2dd95SBruce Richardson 		tx_q_used = conf[i].num_tx_queues;
6499a2dd95SBruce Richardson 		/* Check if we have a txq for each worker */
6599a2dd95SBruce Richardson 		if (tx_q_used < nb_graphs)
6699a2dd95SBruce Richardson 			return -EINVAL;
6799a2dd95SBruce Richardson 
6899a2dd95SBruce Richardson 		/* Create node for each rx port queue pair */
6999a2dd95SBruce Richardson 		for (j = 0; j < rx_q_used; j++) {
7099a2dd95SBruce Richardson 			struct ethdev_rx_node_main *rx_node_data;
7199a2dd95SBruce Richardson 			struct rte_node_register *rx_node;
7299a2dd95SBruce Richardson 			ethdev_rx_node_elem_t *elem;
7399a2dd95SBruce Richardson 
7499a2dd95SBruce Richardson 			rx_node_data = ethdev_rx_get_node_data_get();
7599a2dd95SBruce Richardson 			rx_node = ethdev_rx_node_get();
7699a2dd95SBruce Richardson 			snprintf(name, sizeof(name), "%u-%u", port_id, j);
7799a2dd95SBruce Richardson 			/* Clone a new rx node with same edges as parent */
7899a2dd95SBruce Richardson 			id = rte_node_clone(rx_node->id, name);
7999a2dd95SBruce Richardson 			if (id == RTE_NODE_ID_INVALID)
8099a2dd95SBruce Richardson 				return -EIO;
8199a2dd95SBruce Richardson 
8299a2dd95SBruce Richardson 			/* Add it to list of ethdev rx nodes for lookup */
8399a2dd95SBruce Richardson 			elem = malloc(sizeof(ethdev_rx_node_elem_t));
84d914c010SShiqi Liu 			if (elem == NULL)
85d914c010SShiqi Liu 				return -ENOMEM;
8699a2dd95SBruce Richardson 			memset(elem, 0, sizeof(ethdev_rx_node_elem_t));
8799a2dd95SBruce Richardson 			elem->ctx.port_id = port_id;
8899a2dd95SBruce Richardson 			elem->ctx.queue_id = j;
89b4de7aafSVamsi Attunuru 			elem->ctx.cls_next = ETHDEV_RX_NEXT_PKT_CLS;
9099a2dd95SBruce Richardson 			elem->nid = id;
9199a2dd95SBruce Richardson 			elem->next = rx_node_data->head;
9299a2dd95SBruce Richardson 			rx_node_data->head = elem;
9399a2dd95SBruce Richardson 
9499a2dd95SBruce Richardson 			node_dbg("ethdev", "Rx node %s-%s: is at %u",
9599a2dd95SBruce Richardson 				 rx_node->name, name, id);
9699a2dd95SBruce Richardson 		}
9799a2dd95SBruce Richardson 
9899a2dd95SBruce Richardson 		/* Create a per port tx node from base node */
9999a2dd95SBruce Richardson 		snprintf(name, sizeof(name), "%u", port_id);
10099a2dd95SBruce Richardson 		/* Clone a new node with same edges as parent */
10199a2dd95SBruce Richardson 		id = rte_node_clone(tx_node->id, name);
10299a2dd95SBruce Richardson 		tx_node_data->nodes[port_id] = id;
10399a2dd95SBruce Richardson 
10499a2dd95SBruce Richardson 		node_dbg("ethdev", "Tx node %s-%s: is at %u", tx_node->name,
10599a2dd95SBruce Richardson 			 name, id);
10699a2dd95SBruce Richardson 
10799a2dd95SBruce Richardson 		/* Prepare the actual name of the cloned node */
10899a2dd95SBruce Richardson 		snprintf(name, sizeof(name), "ethdev_tx-%u", port_id);
10999a2dd95SBruce Richardson 
11099a2dd95SBruce Richardson 		/* Add this tx port node as next to ip4_rewrite_node */
11199a2dd95SBruce Richardson 		rte_node_edge_update(ip4_rewrite_node->id, RTE_EDGE_ID_INVALID,
11299a2dd95SBruce Richardson 				     &next_nodes, 1);
11399a2dd95SBruce Richardson 		/* Assuming edge id is the last one alloc'ed */
11499a2dd95SBruce Richardson 		rc = ip4_rewrite_set_next(
11599a2dd95SBruce Richardson 			port_id, rte_node_edge_count(ip4_rewrite_node->id) - 1);
11699a2dd95SBruce Richardson 		if (rc < 0)
11799a2dd95SBruce Richardson 			return rc;
11816ac29cbSAmit Prakash Shukla 
11916ac29cbSAmit Prakash Shukla 		/* Add this tx port node as next to ip6_rewrite_node */
12016ac29cbSAmit Prakash Shukla 		rte_node_edge_update(ip6_rewrite_node->id, RTE_EDGE_ID_INVALID,
12116ac29cbSAmit Prakash Shukla 				     &next_nodes, 1);
12216ac29cbSAmit Prakash Shukla 		/* Assuming edge id is the last one alloc'ed */
12316ac29cbSAmit Prakash Shukla 		rc = ip6_rewrite_set_next(
12416ac29cbSAmit Prakash Shukla 			port_id, rte_node_edge_count(ip6_rewrite_node->id) - 1);
12516ac29cbSAmit Prakash Shukla 		if (rc < 0)
12616ac29cbSAmit Prakash Shukla 			return rc;
12716ac29cbSAmit Prakash Shukla 
12899a2dd95SBruce Richardson 	}
12999a2dd95SBruce Richardson 
13099a2dd95SBruce Richardson 	ctrl.nb_graphs = nb_graphs;
13199a2dd95SBruce Richardson 	return 0;
13299a2dd95SBruce Richardson }
133*77b88bf5SRakesh Kudurumalla 
134*77b88bf5SRakesh Kudurumalla int
rte_node_ethdev_rx_next_update(rte_node_t id,const char * edge_name)135*77b88bf5SRakesh Kudurumalla rte_node_ethdev_rx_next_update(rte_node_t id, const char *edge_name)
136*77b88bf5SRakesh Kudurumalla {
137*77b88bf5SRakesh Kudurumalla 	struct ethdev_rx_node_main *data;
138*77b88bf5SRakesh Kudurumalla 	ethdev_rx_node_elem_t *elem;
139*77b88bf5SRakesh Kudurumalla 	char **next_nodes;
140*77b88bf5SRakesh Kudurumalla 	int rc = -EINVAL;
141*77b88bf5SRakesh Kudurumalla 	uint16_t i = 0;
142*77b88bf5SRakesh Kudurumalla 	uint32_t size;
143*77b88bf5SRakesh Kudurumalla 
144*77b88bf5SRakesh Kudurumalla 	if (edge_name == NULL)
145*77b88bf5SRakesh Kudurumalla 		goto exit;
146*77b88bf5SRakesh Kudurumalla 
147*77b88bf5SRakesh Kudurumalla 	size = rte_node_edge_get(id, NULL);
148*77b88bf5SRakesh Kudurumalla 
149*77b88bf5SRakesh Kudurumalla 	if (size == RTE_NODE_ID_INVALID)
150*77b88bf5SRakesh Kudurumalla 		goto exit;
151*77b88bf5SRakesh Kudurumalla 
152*77b88bf5SRakesh Kudurumalla 	next_nodes = calloc((size / sizeof(char *)) + 1, sizeof(*next_nodes));
153*77b88bf5SRakesh Kudurumalla 	if (next_nodes == NULL) {
154*77b88bf5SRakesh Kudurumalla 		rc = -ENOMEM;
155*77b88bf5SRakesh Kudurumalla 		goto exit;
156*77b88bf5SRakesh Kudurumalla 	}
157*77b88bf5SRakesh Kudurumalla 
158*77b88bf5SRakesh Kudurumalla 	size = rte_node_edge_get(id, next_nodes);
159*77b88bf5SRakesh Kudurumalla 
160*77b88bf5SRakesh Kudurumalla 	while (next_nodes[i] != NULL) {
161*77b88bf5SRakesh Kudurumalla 		if (strcmp(edge_name, next_nodes[i]) == 0) {
162*77b88bf5SRakesh Kudurumalla 			data = ethdev_rx_get_node_data_get();
163*77b88bf5SRakesh Kudurumalla 			elem = data->head;
164*77b88bf5SRakesh Kudurumalla 			while (elem->next != data->head) {
165*77b88bf5SRakesh Kudurumalla 				if (elem->nid == id) {
166*77b88bf5SRakesh Kudurumalla 					elem->ctx.cls_next = i;
167*77b88bf5SRakesh Kudurumalla 					rc = 0;
168*77b88bf5SRakesh Kudurumalla 					goto found;
169*77b88bf5SRakesh Kudurumalla 				}
170*77b88bf5SRakesh Kudurumalla 				elem = elem->next;
171*77b88bf5SRakesh Kudurumalla 			}
172*77b88bf5SRakesh Kudurumalla 		}
173*77b88bf5SRakesh Kudurumalla 		i++;
174*77b88bf5SRakesh Kudurumalla 	}
175*77b88bf5SRakesh Kudurumalla found:
176*77b88bf5SRakesh Kudurumalla 	free(next_nodes);
177*77b88bf5SRakesh Kudurumalla exit:
178*77b88bf5SRakesh Kudurumalla 	return rc;
179*77b88bf5SRakesh Kudurumalla }
180