xref: /dpdk/examples/pipeline/obj.c (revision def657a3478bbdabd989ac29304dc4ee408049ef)
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 #include <rte_cryptodev.h>
11 
12 #include "obj.h"
13 
14 /*
15  * ethdev
16  */
17 static struct rte_eth_conf port_conf_default = {
18 	.link_speeds = 0,
19 	.rxmode = {
20 		.mq_mode = RTE_ETH_MQ_RX_NONE,
21 		.mtu = 9000 - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN), /* Jumbo frame MTU */
22 	},
23 	.rx_adv_conf = {
24 		.rss_conf = {
25 			.rss_key = NULL,
26 			.rss_key_len = 40,
27 			.rss_hf = 0,
28 		},
29 	},
30 	.txmode = {
31 		.mq_mode = RTE_ETH_MQ_TX_NONE,
32 	},
33 	.lpbk_mode = 0,
34 };
35 
36 #define RETA_CONF_SIZE     (RTE_ETH_RSS_RETA_SIZE_512 / RTE_ETH_RETA_GROUP_SIZE)
37 
38 static int
rss_setup(uint16_t port_id,uint16_t reta_size,struct ethdev_params_rss * rss)39 rss_setup(uint16_t port_id,
40 	uint16_t reta_size,
41 	struct ethdev_params_rss *rss)
42 {
43 	struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE];
44 	uint32_t i;
45 	int status;
46 
47 	/* RETA setting */
48 	memset(reta_conf, 0, sizeof(reta_conf));
49 
50 	for (i = 0; i < reta_size; i++)
51 		reta_conf[i / RTE_ETH_RETA_GROUP_SIZE].mask = UINT64_MAX;
52 
53 	for (i = 0; i < reta_size; i++) {
54 		uint32_t reta_id = i / RTE_ETH_RETA_GROUP_SIZE;
55 		uint32_t reta_pos = i % RTE_ETH_RETA_GROUP_SIZE;
56 		uint32_t rss_qs_pos = i % rss->n_queues;
57 
58 		reta_conf[reta_id].reta[reta_pos] =
59 			(uint16_t) rss->queue_id[rss_qs_pos];
60 	}
61 
62 	/* RETA update */
63 	status = rte_eth_dev_rss_reta_update(port_id,
64 		reta_conf,
65 		reta_size);
66 
67 	return status;
68 }
69 
70 int
ethdev_config(const char * name,struct ethdev_params * params)71 ethdev_config(const char *name, struct ethdev_params *params)
72 {
73 	struct rte_eth_dev_info port_info;
74 	struct rte_eth_conf port_conf;
75 	struct ethdev_params_rss *rss;
76 	struct rte_mempool *mempool;
77 	uint32_t i;
78 	int numa_node, status;
79 	uint16_t port_id = 0;
80 
81 	/* Check input params */
82 	if (!name ||
83 	    !name[0] ||
84 	    !params ||
85 	    !params->rx.n_queues ||
86 	    !params->rx.queue_size ||
87 	    !params->tx.n_queues ||
88 	    !params->tx.queue_size)
89 		return -EINVAL;
90 
91 	status = rte_eth_dev_get_port_by_name(name, &port_id);
92 	if (status)
93 		return -EINVAL;
94 
95 	status = rte_eth_dev_info_get(port_id, &port_info);
96 	if (status)
97 		return -EINVAL;
98 
99 	mempool = rte_mempool_lookup(params->rx.mempool_name);
100 	if (!mempool)
101 		return -EINVAL;
102 
103 	rss = params->rx.rss;
104 	if (rss) {
105 		if (!port_info.reta_size || port_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512)
106 			return -EINVAL;
107 
108 		if (!rss->n_queues || rss->n_queues >= ETHDEV_RXQ_RSS_MAX)
109 			return -EINVAL;
110 
111 		for (i = 0; i < rss->n_queues; i++)
112 			if (rss->queue_id[i] >= port_info.max_rx_queues)
113 				return -EINVAL;
114 	}
115 
116 	/* Port */
117 	memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
118 	if (rss) {
119 		uint64_t rss_hf = RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP;
120 
121 		port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
122 		port_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf & port_info.flow_type_rss_offloads;
123 	}
124 
125 	numa_node = rte_eth_dev_socket_id(port_id);
126 	if (numa_node == SOCKET_ID_ANY)
127 		numa_node = 0;
128 
129 	status = rte_eth_dev_configure(
130 		port_id,
131 		params->rx.n_queues,
132 		params->tx.n_queues,
133 		&port_conf);
134 
135 	if (status < 0)
136 		return -EINVAL;
137 
138 	if (params->promiscuous) {
139 		status = rte_eth_promiscuous_enable(port_id);
140 		if (status)
141 			return -EINVAL;
142 	}
143 
144 	/* Port RX */
145 	for (i = 0; i < params->rx.n_queues; i++) {
146 		status = rte_eth_rx_queue_setup(
147 			port_id,
148 			i,
149 			params->rx.queue_size,
150 			numa_node,
151 			NULL,
152 			mempool);
153 
154 		if (status < 0)
155 			return -EINVAL;
156 	}
157 
158 	/* Port TX */
159 	for (i = 0; i < params->tx.n_queues; i++) {
160 		status = rte_eth_tx_queue_setup(
161 			port_id,
162 			i,
163 			params->tx.queue_size,
164 			numa_node,
165 			NULL);
166 
167 		if (status < 0)
168 			return -EINVAL;
169 	}
170 
171 	/* Port start */
172 	status = rte_eth_dev_start(port_id);
173 	if (status < 0)
174 		return -EINVAL;
175 
176 	if (rss) {
177 		status = rss_setup(port_id, port_info.reta_size, rss);
178 
179 		if (status) {
180 			rte_eth_dev_stop(port_id);
181 			return -EINVAL;
182 		}
183 	}
184 
185 	/* Port link up */
186 	status = rte_eth_dev_set_link_up(port_id);
187 	if ((status < 0) && (status != -ENOTSUP)) {
188 		rte_eth_dev_stop(port_id);
189 		return -EINVAL;
190 	}
191 
192 	return 0;
193 }
194 
195 /*
196  * cryptodev
197  */
198 int
cryptodev_config(const char * name,struct cryptodev_params * params)199 cryptodev_config(const char *name, struct cryptodev_params *params)
200 {
201 	struct rte_cryptodev_info dev_info;
202 	struct rte_cryptodev_config dev_conf;
203 	struct rte_cryptodev_qp_conf queue_conf;
204 	uint8_t dev_id;
205 	uint32_t socket_id, i;
206 	int status;
207 
208 	/* Check input parameters. */
209 	if (!name ||
210 	    !params->n_queue_pairs ||
211 	    !params->queue_size)
212 		return -EINVAL;
213 
214 	/* Find the crypto device. */
215 	status = rte_cryptodev_get_dev_id(name);
216 	if (status < 0)
217 		return -EINVAL;
218 
219 	dev_id = (uint8_t)status;
220 
221 	rte_cryptodev_info_get(dev_id, &dev_info);
222 	if (params->n_queue_pairs > dev_info.max_nb_queue_pairs)
223 		return -EINVAL;
224 
225 	socket_id = rte_cryptodev_socket_id(dev_id);
226 
227 	/* Configure the crypto device. */
228 	memset(&dev_conf, 0, sizeof(dev_conf));
229 	dev_conf.socket_id = socket_id;
230 	dev_conf.nb_queue_pairs = params->n_queue_pairs;
231 	dev_conf.ff_disable = 0;
232 
233 	status = rte_cryptodev_configure(dev_id, &dev_conf);
234 	if (status)
235 		return status;
236 
237 	/* Configure the crypto device queue pairs. */
238 	memset(&queue_conf, 0, sizeof(queue_conf));
239 	queue_conf.nb_descriptors = params->queue_size;
240 	queue_conf.mp_session = NULL;
241 
242 	for (i = 0; i < params->n_queue_pairs; i++) {
243 		status = rte_cryptodev_queue_pair_setup(dev_id, i, &queue_conf, socket_id);
244 		if (status)
245 			return status;
246 	}
247 
248 	/* Start the crypto device. */
249 	status = rte_cryptodev_start(dev_id);
250 	if (status)
251 		return status;
252 
253 	return 0;
254 }
255