xref: /dpdk/examples/pipeline/obj.c (revision 78dffe314cd7bff9cc70385d6e5aaa546b88a6a1)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4 
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include <rte_mbuf.h>
9 #include <rte_ethdev.h>
10 
11 #include "obj.h"
12 
13 /*
14  * ethdev
15  */
16 static struct rte_eth_conf port_conf_default = {
17 	.link_speeds = 0,
18 	.rxmode = {
19 		.mq_mode = RTE_ETH_MQ_RX_NONE,
20 		.mtu = 9000 - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN), /* Jumbo frame MTU */
21 	},
22 	.rx_adv_conf = {
23 		.rss_conf = {
24 			.rss_key = NULL,
25 			.rss_key_len = 40,
26 			.rss_hf = 0,
27 		},
28 	},
29 	.txmode = {
30 		.mq_mode = RTE_ETH_MQ_TX_NONE,
31 	},
32 	.lpbk_mode = 0,
33 };
34 
35 #define RETA_CONF_SIZE     (RTE_ETH_RSS_RETA_SIZE_512 / RTE_ETH_RETA_GROUP_SIZE)
36 
37 static int
38 rss_setup(uint16_t port_id,
39 	uint16_t reta_size,
40 	struct ethdev_params_rss *rss)
41 {
42 	struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE];
43 	uint32_t i;
44 	int status;
45 
46 	/* RETA setting */
47 	memset(reta_conf, 0, sizeof(reta_conf));
48 
49 	for (i = 0; i < reta_size; i++)
50 		reta_conf[i / RTE_ETH_RETA_GROUP_SIZE].mask = UINT64_MAX;
51 
52 	for (i = 0; i < reta_size; i++) {
53 		uint32_t reta_id = i / RTE_ETH_RETA_GROUP_SIZE;
54 		uint32_t reta_pos = i % RTE_ETH_RETA_GROUP_SIZE;
55 		uint32_t rss_qs_pos = i % rss->n_queues;
56 
57 		reta_conf[reta_id].reta[reta_pos] =
58 			(uint16_t) rss->queue_id[rss_qs_pos];
59 	}
60 
61 	/* RETA update */
62 	status = rte_eth_dev_rss_reta_update(port_id,
63 		reta_conf,
64 		reta_size);
65 
66 	return status;
67 }
68 
69 int
70 ethdev_config(const char *name, struct ethdev_params *params)
71 {
72 	struct rte_eth_dev_info port_info;
73 	struct rte_eth_conf port_conf;
74 	struct ethdev_params_rss *rss;
75 	struct rte_mempool *mempool;
76 	uint32_t i;
77 	int numa_node, status;
78 	uint16_t port_id = 0;
79 
80 	/* Check input params */
81 	if (!name ||
82 	    !name[0] ||
83 	    !params ||
84 	    !params->rx.n_queues ||
85 	    !params->rx.queue_size ||
86 	    !params->tx.n_queues ||
87 	    !params->tx.queue_size)
88 		return -EINVAL;
89 
90 	status = rte_eth_dev_get_port_by_name(name, &port_id);
91 	if (status)
92 		return -EINVAL;
93 
94 	status = rte_eth_dev_info_get(port_id, &port_info);
95 	if (status)
96 		return -EINVAL;
97 
98 	mempool = rte_mempool_lookup(params->rx.mempool_name);
99 	if (!mempool)
100 		return -EINVAL;
101 
102 	rss = params->rx.rss;
103 	if (rss) {
104 		if (!port_info.reta_size || port_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512)
105 			return -EINVAL;
106 
107 		if (!rss->n_queues || rss->n_queues >= ETHDEV_RXQ_RSS_MAX)
108 			return -EINVAL;
109 
110 		for (i = 0; i < rss->n_queues; i++)
111 			if (rss->queue_id[i] >= port_info.max_rx_queues)
112 				return -EINVAL;
113 	}
114 
115 	/* Port */
116 	memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
117 	if (rss) {
118 		uint64_t rss_hf = RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP;
119 
120 		port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
121 		port_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf & port_info.flow_type_rss_offloads;
122 	}
123 
124 	numa_node = rte_eth_dev_socket_id(port_id);
125 	if (numa_node == SOCKET_ID_ANY)
126 		numa_node = 0;
127 
128 	status = rte_eth_dev_configure(
129 		port_id,
130 		params->rx.n_queues,
131 		params->tx.n_queues,
132 		&port_conf);
133 
134 	if (status < 0)
135 		return -EINVAL;
136 
137 	if (params->promiscuous) {
138 		status = rte_eth_promiscuous_enable(port_id);
139 		if (status)
140 			return -EINVAL;
141 	}
142 
143 	/* Port RX */
144 	for (i = 0; i < params->rx.n_queues; i++) {
145 		status = rte_eth_rx_queue_setup(
146 			port_id,
147 			i,
148 			params->rx.queue_size,
149 			numa_node,
150 			NULL,
151 			mempool);
152 
153 		if (status < 0)
154 			return -EINVAL;
155 	}
156 
157 	/* Port TX */
158 	for (i = 0; i < params->tx.n_queues; i++) {
159 		status = rte_eth_tx_queue_setup(
160 			port_id,
161 			i,
162 			params->tx.queue_size,
163 			numa_node,
164 			NULL);
165 
166 		if (status < 0)
167 			return -EINVAL;
168 	}
169 
170 	/* Port start */
171 	status = rte_eth_dev_start(port_id);
172 	if (status < 0)
173 		return -EINVAL;
174 
175 	if (rss) {
176 		status = rss_setup(port_id, port_info.reta_size, rss);
177 
178 		if (status) {
179 			rte_eth_dev_stop(port_id);
180 			return -EINVAL;
181 		}
182 	}
183 
184 	/* Port link up */
185 	status = rte_eth_dev_set_link_up(port_id);
186 	if ((status < 0) && (status != -ENOTSUP)) {
187 		rte_eth_dev_stop(port_id);
188 		return -EINVAL;
189 	}
190 
191 	return 0;
192 }
193