1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606 * Copyright(c) 2016-2017 Intel Corporation
3a9643ea8Slogwang */
4a9643ea8Slogwang
5a9643ea8Slogwang #include <string.h>
6a9643ea8Slogwang
7a9643ea8Slogwang #include <rte_common.h>
8a9643ea8Slogwang #include <rte_malloc.h>
9a9643ea8Slogwang #include <rte_cryptodev_pmd.h>
10a9643ea8Slogwang
11a9643ea8Slogwang #include "null_crypto_pmd_private.h"
12a9643ea8Slogwang
13a9643ea8Slogwang static const struct rte_cryptodev_capabilities null_crypto_pmd_capabilities[] = {
14a9643ea8Slogwang { /* NULL (AUTH) */
15a9643ea8Slogwang .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
16a9643ea8Slogwang {.sym = {
17a9643ea8Slogwang .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
18a9643ea8Slogwang {.auth = {
19a9643ea8Slogwang .algo = RTE_CRYPTO_AUTH_NULL,
20a9643ea8Slogwang .block_size = 1,
21a9643ea8Slogwang .key_size = {
22a9643ea8Slogwang .min = 0,
23a9643ea8Slogwang .max = 0,
24a9643ea8Slogwang .increment = 0
25a9643ea8Slogwang },
26a9643ea8Slogwang .digest_size = {
27a9643ea8Slogwang .min = 0,
28a9643ea8Slogwang .max = 0,
29a9643ea8Slogwang .increment = 0
30a9643ea8Slogwang },
312bfe3f2eSlogwang .iv_size = { 0 }
32a9643ea8Slogwang }, },
33a9643ea8Slogwang }, },
34a9643ea8Slogwang },
35a9643ea8Slogwang { /* NULL (CIPHER) */
36a9643ea8Slogwang .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
37a9643ea8Slogwang {.sym = {
38a9643ea8Slogwang .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
39a9643ea8Slogwang {.cipher = {
40a9643ea8Slogwang .algo = RTE_CRYPTO_CIPHER_NULL,
41a9643ea8Slogwang .block_size = 1,
42a9643ea8Slogwang .key_size = {
43a9643ea8Slogwang .min = 0,
44a9643ea8Slogwang .max = 0,
45a9643ea8Slogwang .increment = 0
46a9643ea8Slogwang },
472bfe3f2eSlogwang .iv_size = { 0 }
48a9643ea8Slogwang }, },
49a9643ea8Slogwang }, }
50a9643ea8Slogwang },
51a9643ea8Slogwang RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
52a9643ea8Slogwang };
53a9643ea8Slogwang
54a9643ea8Slogwang /** Configure device */
55a9643ea8Slogwang static int
null_crypto_pmd_config(__rte_unused struct rte_cryptodev * dev,__rte_unused struct rte_cryptodev_config * config)562bfe3f2eSlogwang null_crypto_pmd_config(__rte_unused struct rte_cryptodev *dev,
572bfe3f2eSlogwang __rte_unused struct rte_cryptodev_config *config)
58a9643ea8Slogwang {
59a9643ea8Slogwang return 0;
60a9643ea8Slogwang }
61a9643ea8Slogwang
62a9643ea8Slogwang /** Start device */
63a9643ea8Slogwang static int
null_crypto_pmd_start(__rte_unused struct rte_cryptodev * dev)64a9643ea8Slogwang null_crypto_pmd_start(__rte_unused struct rte_cryptodev *dev)
65a9643ea8Slogwang {
66a9643ea8Slogwang return 0;
67a9643ea8Slogwang }
68a9643ea8Slogwang
69a9643ea8Slogwang /** Stop device */
70a9643ea8Slogwang static void
null_crypto_pmd_stop(__rte_unused struct rte_cryptodev * dev)71a9643ea8Slogwang null_crypto_pmd_stop(__rte_unused struct rte_cryptodev *dev)
72a9643ea8Slogwang {
73a9643ea8Slogwang }
74a9643ea8Slogwang
75a9643ea8Slogwang /** Close device */
76a9643ea8Slogwang static int
null_crypto_pmd_close(__rte_unused struct rte_cryptodev * dev)77a9643ea8Slogwang null_crypto_pmd_close(__rte_unused struct rte_cryptodev *dev)
78a9643ea8Slogwang {
79a9643ea8Slogwang return 0;
80a9643ea8Slogwang }
81a9643ea8Slogwang
82a9643ea8Slogwang /** Get device statistics */
83a9643ea8Slogwang static void
null_crypto_pmd_stats_get(struct rte_cryptodev * dev,struct rte_cryptodev_stats * stats)84a9643ea8Slogwang null_crypto_pmd_stats_get(struct rte_cryptodev *dev,
85a9643ea8Slogwang struct rte_cryptodev_stats *stats)
86a9643ea8Slogwang {
87a9643ea8Slogwang int qp_id;
88a9643ea8Slogwang
89a9643ea8Slogwang for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
90a9643ea8Slogwang struct null_crypto_qp *qp = dev->data->queue_pairs[qp_id];
91a9643ea8Slogwang
92a9643ea8Slogwang stats->enqueued_count += qp->qp_stats.enqueued_count;
93a9643ea8Slogwang stats->dequeued_count += qp->qp_stats.dequeued_count;
94a9643ea8Slogwang
95a9643ea8Slogwang stats->enqueue_err_count += qp->qp_stats.enqueue_err_count;
96a9643ea8Slogwang stats->dequeue_err_count += qp->qp_stats.dequeue_err_count;
97a9643ea8Slogwang }
98a9643ea8Slogwang }
99a9643ea8Slogwang
100a9643ea8Slogwang /** Reset device statistics */
101a9643ea8Slogwang static void
null_crypto_pmd_stats_reset(struct rte_cryptodev * dev)102a9643ea8Slogwang null_crypto_pmd_stats_reset(struct rte_cryptodev *dev)
103a9643ea8Slogwang {
104a9643ea8Slogwang int qp_id;
105a9643ea8Slogwang
106a9643ea8Slogwang for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
107a9643ea8Slogwang struct null_crypto_qp *qp = dev->data->queue_pairs[qp_id];
108a9643ea8Slogwang
109a9643ea8Slogwang memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
110a9643ea8Slogwang }
111a9643ea8Slogwang }
112a9643ea8Slogwang
113a9643ea8Slogwang
114a9643ea8Slogwang /** Get device info */
115a9643ea8Slogwang static void
null_crypto_pmd_info_get(struct rte_cryptodev * dev,struct rte_cryptodev_info * dev_info)116a9643ea8Slogwang null_crypto_pmd_info_get(struct rte_cryptodev *dev,
117a9643ea8Slogwang struct rte_cryptodev_info *dev_info)
118a9643ea8Slogwang {
119a9643ea8Slogwang struct null_crypto_private *internals = dev->data->dev_private;
120a9643ea8Slogwang
121a9643ea8Slogwang if (dev_info != NULL) {
1222bfe3f2eSlogwang dev_info->driver_id = dev->driver_id;
123a9643ea8Slogwang dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
124d30ea906Sjfb8856606 /* No limit of number of sessions */
125d30ea906Sjfb8856606 dev_info->sym.max_nb_sessions = 0;
126a9643ea8Slogwang dev_info->feature_flags = dev->feature_flags;
127a9643ea8Slogwang dev_info->capabilities = null_crypto_pmd_capabilities;
128a9643ea8Slogwang }
129a9643ea8Slogwang }
130a9643ea8Slogwang
131a9643ea8Slogwang /** Release queue pair */
132a9643ea8Slogwang static int
null_crypto_pmd_qp_release(struct rte_cryptodev * dev,uint16_t qp_id)133a9643ea8Slogwang null_crypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
134a9643ea8Slogwang {
135a9643ea8Slogwang if (dev->data->queue_pairs[qp_id] != NULL) {
1361646932aSjfb8856606 struct null_crypto_qp *qp = dev->data->queue_pairs[qp_id];
1371646932aSjfb8856606
1381646932aSjfb8856606 if (qp->processed_pkts)
1391646932aSjfb8856606 rte_ring_free(qp->processed_pkts);
1401646932aSjfb8856606
141a9643ea8Slogwang rte_free(dev->data->queue_pairs[qp_id]);
142a9643ea8Slogwang dev->data->queue_pairs[qp_id] = NULL;
143a9643ea8Slogwang }
144a9643ea8Slogwang return 0;
145a9643ea8Slogwang }
146a9643ea8Slogwang
147a9643ea8Slogwang /** set a unique name for the queue pair based on it's name, dev_id and qp_id */
148a9643ea8Slogwang static int
null_crypto_pmd_qp_set_unique_name(struct rte_cryptodev * dev,struct null_crypto_qp * qp)149a9643ea8Slogwang null_crypto_pmd_qp_set_unique_name(struct rte_cryptodev *dev,
150a9643ea8Slogwang struct null_crypto_qp *qp)
151a9643ea8Slogwang {
152a9643ea8Slogwang unsigned n = snprintf(qp->name, sizeof(qp->name),
153a9643ea8Slogwang "null_crypto_pmd_%u_qp_%u",
154a9643ea8Slogwang dev->data->dev_id, qp->id);
155a9643ea8Slogwang
1562bfe3f2eSlogwang if (n >= sizeof(qp->name))
157a9643ea8Slogwang return -1;
158a9643ea8Slogwang
159a9643ea8Slogwang return 0;
160a9643ea8Slogwang }
161a9643ea8Slogwang
162a9643ea8Slogwang /** Create a ring to place process packets on */
163a9643ea8Slogwang static struct rte_ring *
null_crypto_pmd_qp_create_processed_pkts_ring(struct null_crypto_qp * qp,unsigned ring_size,int socket_id)164a9643ea8Slogwang null_crypto_pmd_qp_create_processed_pkts_ring(struct null_crypto_qp *qp,
165a9643ea8Slogwang unsigned ring_size, int socket_id)
166a9643ea8Slogwang {
167a9643ea8Slogwang struct rte_ring *r;
168a9643ea8Slogwang
169a9643ea8Slogwang r = rte_ring_lookup(qp->name);
170a9643ea8Slogwang if (r) {
1712bfe3f2eSlogwang if (rte_ring_get_size(r) >= ring_size) {
172d30ea906Sjfb8856606 NULL_LOG(INFO,
173d30ea906Sjfb8856606 "Reusing existing ring %s for "
174d30ea906Sjfb8856606 " processed packets", qp->name);
175a9643ea8Slogwang return r;
176a9643ea8Slogwang }
177a9643ea8Slogwang
178d30ea906Sjfb8856606 NULL_LOG(INFO,
179d30ea906Sjfb8856606 "Unable to reuse existing ring %s for "
180d30ea906Sjfb8856606 " processed packets", qp->name);
181a9643ea8Slogwang return NULL;
182a9643ea8Slogwang }
183a9643ea8Slogwang
184a9643ea8Slogwang return rte_ring_create(qp->name, ring_size, socket_id,
185a9643ea8Slogwang RING_F_SP_ENQ | RING_F_SC_DEQ);
186a9643ea8Slogwang }
187a9643ea8Slogwang
188a9643ea8Slogwang /** Setup a queue pair */
189a9643ea8Slogwang static int
null_crypto_pmd_qp_setup(struct rte_cryptodev * dev,uint16_t qp_id,const struct rte_cryptodev_qp_conf * qp_conf,int socket_id)190a9643ea8Slogwang null_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
191a9643ea8Slogwang const struct rte_cryptodev_qp_conf *qp_conf,
192*4418919fSjohnjiang int socket_id)
193a9643ea8Slogwang {
194a9643ea8Slogwang struct null_crypto_private *internals = dev->data->dev_private;
195a9643ea8Slogwang struct null_crypto_qp *qp;
196a9643ea8Slogwang int retval;
197a9643ea8Slogwang
198a9643ea8Slogwang if (qp_id >= internals->max_nb_qpairs) {
199d30ea906Sjfb8856606 NULL_LOG(ERR, "Invalid qp_id %u, greater than maximum "
200a9643ea8Slogwang "number of queue pairs supported (%u).",
201a9643ea8Slogwang qp_id, internals->max_nb_qpairs);
202a9643ea8Slogwang return (-EINVAL);
203a9643ea8Slogwang }
204a9643ea8Slogwang
205a9643ea8Slogwang /* Free memory prior to re-allocation if needed. */
206a9643ea8Slogwang if (dev->data->queue_pairs[qp_id] != NULL)
207a9643ea8Slogwang null_crypto_pmd_qp_release(dev, qp_id);
208a9643ea8Slogwang
209a9643ea8Slogwang /* Allocate the queue pair data structure. */
210a9643ea8Slogwang qp = rte_zmalloc_socket("Null Crypto PMD Queue Pair", sizeof(*qp),
211a9643ea8Slogwang RTE_CACHE_LINE_SIZE, socket_id);
212a9643ea8Slogwang if (qp == NULL) {
213d30ea906Sjfb8856606 NULL_LOG(ERR, "Failed to allocate queue pair memory");
214a9643ea8Slogwang return (-ENOMEM);
215a9643ea8Slogwang }
216a9643ea8Slogwang
217a9643ea8Slogwang qp->id = qp_id;
218a9643ea8Slogwang dev->data->queue_pairs[qp_id] = qp;
219a9643ea8Slogwang
220a9643ea8Slogwang retval = null_crypto_pmd_qp_set_unique_name(dev, qp);
221a9643ea8Slogwang if (retval) {
222d30ea906Sjfb8856606 NULL_LOG(ERR, "Failed to create unique name for null "
223a9643ea8Slogwang "crypto device");
224d30ea906Sjfb8856606
225a9643ea8Slogwang goto qp_setup_cleanup;
226a9643ea8Slogwang }
227a9643ea8Slogwang
228a9643ea8Slogwang qp->processed_pkts = null_crypto_pmd_qp_create_processed_pkts_ring(qp,
229a9643ea8Slogwang qp_conf->nb_descriptors, socket_id);
230a9643ea8Slogwang if (qp->processed_pkts == NULL) {
231d30ea906Sjfb8856606 NULL_LOG(ERR, "Failed to create unique name for null "
232a9643ea8Slogwang "crypto device");
233a9643ea8Slogwang goto qp_setup_cleanup;
234a9643ea8Slogwang }
235a9643ea8Slogwang
236*4418919fSjohnjiang qp->sess_mp = qp_conf->mp_session;
237*4418919fSjohnjiang qp->sess_mp_priv = qp_conf->mp_session_private;
238a9643ea8Slogwang
239a9643ea8Slogwang memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
240a9643ea8Slogwang
241a9643ea8Slogwang return 0;
242a9643ea8Slogwang
243a9643ea8Slogwang qp_setup_cleanup:
244a9643ea8Slogwang if (qp)
245a9643ea8Slogwang rte_free(qp);
246a9643ea8Slogwang
247a9643ea8Slogwang return -1;
248a9643ea8Slogwang }
249a9643ea8Slogwang
250a9643ea8Slogwang /** Returns the size of the NULL crypto session structure */
251a9643ea8Slogwang static unsigned
null_crypto_pmd_sym_session_get_size(struct rte_cryptodev * dev __rte_unused)252d30ea906Sjfb8856606 null_crypto_pmd_sym_session_get_size(struct rte_cryptodev *dev __rte_unused)
253a9643ea8Slogwang {
254a9643ea8Slogwang return sizeof(struct null_crypto_session);
255a9643ea8Slogwang }
256a9643ea8Slogwang
257a9643ea8Slogwang /** Configure a null crypto session from a crypto xform chain */
2582bfe3f2eSlogwang static int
null_crypto_pmd_sym_session_configure(struct rte_cryptodev * dev __rte_unused,struct rte_crypto_sym_xform * xform,struct rte_cryptodev_sym_session * sess,struct rte_mempool * mp)259d30ea906Sjfb8856606 null_crypto_pmd_sym_session_configure(struct rte_cryptodev *dev __rte_unused,
2602bfe3f2eSlogwang struct rte_crypto_sym_xform *xform,
2612bfe3f2eSlogwang struct rte_cryptodev_sym_session *sess,
2622bfe3f2eSlogwang struct rte_mempool *mp)
263a9643ea8Slogwang {
2642bfe3f2eSlogwang void *sess_private_data;
2652bfe3f2eSlogwang int ret;
266a9643ea8Slogwang
267a9643ea8Slogwang if (unlikely(sess == NULL)) {
268d30ea906Sjfb8856606 NULL_LOG(ERR, "invalid session struct");
2692bfe3f2eSlogwang return -EINVAL;
270a9643ea8Slogwang }
271a9643ea8Slogwang
2722bfe3f2eSlogwang if (rte_mempool_get(mp, &sess_private_data)) {
273d30ea906Sjfb8856606 NULL_LOG(ERR,
2742bfe3f2eSlogwang "Couldn't get object from session mempool");
2752bfe3f2eSlogwang return -ENOMEM;
2762bfe3f2eSlogwang }
2772bfe3f2eSlogwang
2782bfe3f2eSlogwang ret = null_crypto_set_session_parameters(sess_private_data, xform);
2792bfe3f2eSlogwang if (ret != 0) {
280d30ea906Sjfb8856606 NULL_LOG(ERR, "failed configure session parameters");
2812bfe3f2eSlogwang
2822bfe3f2eSlogwang /* Return session to mempool */
2832bfe3f2eSlogwang rte_mempool_put(mp, sess_private_data);
2842bfe3f2eSlogwang return ret;
2852bfe3f2eSlogwang }
2862bfe3f2eSlogwang
287d30ea906Sjfb8856606 set_sym_session_private_data(sess, dev->driver_id,
2882bfe3f2eSlogwang sess_private_data);
2892bfe3f2eSlogwang
2902bfe3f2eSlogwang return 0;
291a9643ea8Slogwang }
292a9643ea8Slogwang
293a9643ea8Slogwang /** Clear the memory of session so it doesn't leave key material behind */
294a9643ea8Slogwang static void
null_crypto_pmd_sym_session_clear(struct rte_cryptodev * dev,struct rte_cryptodev_sym_session * sess)295d30ea906Sjfb8856606 null_crypto_pmd_sym_session_clear(struct rte_cryptodev *dev,
2962bfe3f2eSlogwang struct rte_cryptodev_sym_session *sess)
297a9643ea8Slogwang {
2982bfe3f2eSlogwang uint8_t index = dev->driver_id;
299d30ea906Sjfb8856606 void *sess_priv = get_sym_session_private_data(sess, index);
3002bfe3f2eSlogwang
3012bfe3f2eSlogwang /* Zero out the whole structure */
3022bfe3f2eSlogwang if (sess_priv) {
3032bfe3f2eSlogwang memset(sess_priv, 0, sizeof(struct null_crypto_session));
3042bfe3f2eSlogwang struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
305d30ea906Sjfb8856606 set_sym_session_private_data(sess, index, NULL);
3062bfe3f2eSlogwang rte_mempool_put(sess_mp, sess_priv);
3072bfe3f2eSlogwang }
308a9643ea8Slogwang }
309a9643ea8Slogwang
310d30ea906Sjfb8856606 static struct rte_cryptodev_ops pmd_ops = {
311a9643ea8Slogwang .dev_configure = null_crypto_pmd_config,
312a9643ea8Slogwang .dev_start = null_crypto_pmd_start,
313a9643ea8Slogwang .dev_stop = null_crypto_pmd_stop,
314a9643ea8Slogwang .dev_close = null_crypto_pmd_close,
315a9643ea8Slogwang
316a9643ea8Slogwang .stats_get = null_crypto_pmd_stats_get,
317a9643ea8Slogwang .stats_reset = null_crypto_pmd_stats_reset,
318a9643ea8Slogwang
319a9643ea8Slogwang .dev_infos_get = null_crypto_pmd_info_get,
320a9643ea8Slogwang
321a9643ea8Slogwang .queue_pair_setup = null_crypto_pmd_qp_setup,
322a9643ea8Slogwang .queue_pair_release = null_crypto_pmd_qp_release,
323a9643ea8Slogwang
324d30ea906Sjfb8856606 .sym_session_get_size = null_crypto_pmd_sym_session_get_size,
325d30ea906Sjfb8856606 .sym_session_configure = null_crypto_pmd_sym_session_configure,
326d30ea906Sjfb8856606 .sym_session_clear = null_crypto_pmd_sym_session_clear
327a9643ea8Slogwang };
328a9643ea8Slogwang
329a9643ea8Slogwang struct rte_cryptodev_ops *null_crypto_pmd_ops = &pmd_ops;
330