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