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