1af668035SAkhil Goyal /* SPDX-License-Identifier: BSD-3-Clause
2af668035SAkhil Goyal * Copyright(c) 2017 Intel Corporation
3af668035SAkhil Goyal */
4af668035SAkhil Goyal
5cb7b6898STal Shnaiderman #include <sys/queue.h>
62fd66f75SAkhil Goyal #include <rte_errno.h>
7af668035SAkhil Goyal #include <rte_string_fns.h>
8af668035SAkhil Goyal #include <rte_malloc.h>
9af668035SAkhil Goyal
10af668035SAkhil Goyal #include "cryptodev_pmd.h"
11af668035SAkhil Goyal
12af668035SAkhil Goyal /**
13af668035SAkhil Goyal * Parse name from argument
14af668035SAkhil Goyal */
15af668035SAkhil Goyal static int
rte_cryptodev_pmd_parse_name_arg(const char * key __rte_unused,const char * value,void * extra_args)16af668035SAkhil Goyal rte_cryptodev_pmd_parse_name_arg(const char *key __rte_unused,
17af668035SAkhil Goyal const char *value, void *extra_args)
18af668035SAkhil Goyal {
19af668035SAkhil Goyal struct rte_cryptodev_pmd_init_params *params = extra_args;
20af668035SAkhil Goyal int n;
21af668035SAkhil Goyal
22af668035SAkhil Goyal n = strlcpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN);
23af668035SAkhil Goyal if (n >= RTE_CRYPTODEV_NAME_MAX_LEN)
24af668035SAkhil Goyal return -EINVAL;
25af668035SAkhil Goyal
26af668035SAkhil Goyal return 0;
27af668035SAkhil Goyal }
28af668035SAkhil Goyal
29af668035SAkhil Goyal /**
30af668035SAkhil Goyal * Parse unsigned integer from argument
31af668035SAkhil Goyal */
32af668035SAkhil Goyal static int
rte_cryptodev_pmd_parse_uint_arg(const char * key __rte_unused,const char * value,void * extra_args)33af668035SAkhil Goyal rte_cryptodev_pmd_parse_uint_arg(const char *key __rte_unused,
34af668035SAkhil Goyal const char *value, void *extra_args)
35af668035SAkhil Goyal {
36af668035SAkhil Goyal int i;
37af668035SAkhil Goyal char *end;
38af668035SAkhil Goyal errno = 0;
39af668035SAkhil Goyal
40af668035SAkhil Goyal i = strtol(value, &end, 10);
41af668035SAkhil Goyal if (*end != 0 || errno != 0 || i < 0)
42af668035SAkhil Goyal return -EINVAL;
43af668035SAkhil Goyal
44af668035SAkhil Goyal *((uint32_t *)extra_args) = i;
45af668035SAkhil Goyal return 0;
46af668035SAkhil Goyal }
47af668035SAkhil Goyal
48af668035SAkhil Goyal int
rte_cryptodev_pmd_parse_input_args(struct rte_cryptodev_pmd_init_params * params,const char * args)49af668035SAkhil Goyal rte_cryptodev_pmd_parse_input_args(
50af668035SAkhil Goyal struct rte_cryptodev_pmd_init_params *params,
51af668035SAkhil Goyal const char *args)
52af668035SAkhil Goyal {
53af668035SAkhil Goyal struct rte_kvargs *kvlist = NULL;
54af668035SAkhil Goyal int ret = 0;
55af668035SAkhil Goyal
56af668035SAkhil Goyal if (params == NULL)
57af668035SAkhil Goyal return -EINVAL;
58af668035SAkhil Goyal
59af668035SAkhil Goyal if (args) {
60af668035SAkhil Goyal kvlist = rte_kvargs_parse(args, cryptodev_pmd_valid_params);
61af668035SAkhil Goyal if (kvlist == NULL)
62af668035SAkhil Goyal return -EINVAL;
63af668035SAkhil Goyal
64af668035SAkhil Goyal ret = rte_kvargs_process(kvlist,
65af668035SAkhil Goyal RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG,
66af668035SAkhil Goyal &rte_cryptodev_pmd_parse_uint_arg,
67af668035SAkhil Goyal ¶ms->max_nb_queue_pairs);
68af668035SAkhil Goyal if (ret < 0)
69af668035SAkhil Goyal goto free_kvlist;
70af668035SAkhil Goyal
71af668035SAkhil Goyal ret = rte_kvargs_process(kvlist,
72af668035SAkhil Goyal RTE_CRYPTODEV_PMD_SOCKET_ID_ARG,
73af668035SAkhil Goyal &rte_cryptodev_pmd_parse_uint_arg,
74af668035SAkhil Goyal ¶ms->socket_id);
75af668035SAkhil Goyal if (ret < 0)
76af668035SAkhil Goyal goto free_kvlist;
77af668035SAkhil Goyal
78af668035SAkhil Goyal ret = rte_kvargs_process(kvlist,
79af668035SAkhil Goyal RTE_CRYPTODEV_PMD_NAME_ARG,
80af668035SAkhil Goyal &rte_cryptodev_pmd_parse_name_arg,
81af668035SAkhil Goyal params);
82af668035SAkhil Goyal if (ret < 0)
83af668035SAkhil Goyal goto free_kvlist;
84af668035SAkhil Goyal }
85af668035SAkhil Goyal
86af668035SAkhil Goyal free_kvlist:
87af668035SAkhil Goyal rte_kvargs_free(kvlist);
88af668035SAkhil Goyal return ret;
89af668035SAkhil Goyal }
90af668035SAkhil Goyal
91af668035SAkhil Goyal struct rte_cryptodev *
rte_cryptodev_pmd_create(const char * name,struct rte_device * device,struct rte_cryptodev_pmd_init_params * params)92af668035SAkhil Goyal rte_cryptodev_pmd_create(const char *name,
93af668035SAkhil Goyal struct rte_device *device,
94af668035SAkhil Goyal struct rte_cryptodev_pmd_init_params *params)
95af668035SAkhil Goyal {
96af668035SAkhil Goyal struct rte_cryptodev *cryptodev;
97af668035SAkhil Goyal
98af668035SAkhil Goyal if (params->name[0] != '\0') {
99af668035SAkhil Goyal CDEV_LOG_INFO("User specified device name = %s\n", params->name);
100af668035SAkhil Goyal name = params->name;
101af668035SAkhil Goyal }
102af668035SAkhil Goyal
103af668035SAkhil Goyal CDEV_LOG_INFO("Creating cryptodev %s\n", name);
104af668035SAkhil Goyal
105af668035SAkhil Goyal CDEV_LOG_INFO("Initialisation parameters - name: %s,"
106af668035SAkhil Goyal "socket id: %d, max queue pairs: %u",
107af668035SAkhil Goyal name, params->socket_id, params->max_nb_queue_pairs);
108af668035SAkhil Goyal
109af668035SAkhil Goyal /* allocate device structure */
110af668035SAkhil Goyal cryptodev = rte_cryptodev_pmd_allocate(name, params->socket_id);
111af668035SAkhil Goyal if (cryptodev == NULL) {
112af668035SAkhil Goyal CDEV_LOG_ERR("Failed to allocate crypto device for %s", name);
113af668035SAkhil Goyal return NULL;
114af668035SAkhil Goyal }
115af668035SAkhil Goyal
116af668035SAkhil Goyal /* allocate private device structure */
117af668035SAkhil Goyal if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
118af668035SAkhil Goyal cryptodev->data->dev_private =
119af668035SAkhil Goyal rte_zmalloc_socket("cryptodev device private",
120af668035SAkhil Goyal params->private_data_size,
121af668035SAkhil Goyal RTE_CACHE_LINE_SIZE,
122af668035SAkhil Goyal params->socket_id);
123af668035SAkhil Goyal
124af668035SAkhil Goyal if (cryptodev->data->dev_private == NULL) {
125af668035SAkhil Goyal CDEV_LOG_ERR("Cannot allocate memory for cryptodev %s"
126af668035SAkhil Goyal " private data", name);
127af668035SAkhil Goyal
128af668035SAkhil Goyal rte_cryptodev_pmd_release_device(cryptodev);
129af668035SAkhil Goyal return NULL;
130af668035SAkhil Goyal }
131af668035SAkhil Goyal }
132af668035SAkhil Goyal
133af668035SAkhil Goyal cryptodev->device = device;
134af668035SAkhil Goyal
135af668035SAkhil Goyal /* initialise user call-back tail queue */
136af668035SAkhil Goyal TAILQ_INIT(&(cryptodev->link_intr_cbs));
137af668035SAkhil Goyal
138af668035SAkhil Goyal return cryptodev;
139af668035SAkhil Goyal }
140af668035SAkhil Goyal
141af668035SAkhil Goyal int
rte_cryptodev_pmd_destroy(struct rte_cryptodev * cryptodev)142af668035SAkhil Goyal rte_cryptodev_pmd_destroy(struct rte_cryptodev *cryptodev)
143af668035SAkhil Goyal {
144af668035SAkhil Goyal int retval;
145af668035SAkhil Goyal void *dev_priv = cryptodev->data->dev_private;
146af668035SAkhil Goyal
147af668035SAkhil Goyal CDEV_LOG_INFO("Closing crypto device %s", cryptodev->device->name);
148af668035SAkhil Goyal
149af668035SAkhil Goyal /* free crypto device */
150af668035SAkhil Goyal retval = rte_cryptodev_pmd_release_device(cryptodev);
151af668035SAkhil Goyal if (retval)
152af668035SAkhil Goyal return retval;
153af668035SAkhil Goyal
154af668035SAkhil Goyal if (rte_eal_process_type() == RTE_PROC_PRIMARY)
155af668035SAkhil Goyal rte_free(dev_priv);
156af668035SAkhil Goyal
157af668035SAkhil Goyal
158af668035SAkhil Goyal cryptodev->device = NULL;
159af668035SAkhil Goyal cryptodev->data = NULL;
160af668035SAkhil Goyal
161af668035SAkhil Goyal return 0;
162af668035SAkhil Goyal }
1632fd66f75SAkhil Goyal
164*33cd3fd5SAkhil Goyal void
rte_cryptodev_pmd_probing_finish(struct rte_cryptodev * cryptodev)165*33cd3fd5SAkhil Goyal rte_cryptodev_pmd_probing_finish(struct rte_cryptodev *cryptodev)
166*33cd3fd5SAkhil Goyal {
167*33cd3fd5SAkhil Goyal if (cryptodev == NULL)
168*33cd3fd5SAkhil Goyal return;
169*33cd3fd5SAkhil Goyal /*
170*33cd3fd5SAkhil Goyal * for secondary process, at that point we expect device
171*33cd3fd5SAkhil Goyal * to be already 'usable', so shared data and all function
172*33cd3fd5SAkhil Goyal * pointers for fast-path devops have to be setup properly
173*33cd3fd5SAkhil Goyal * inside rte_cryptodev.
174*33cd3fd5SAkhil Goyal */
175*33cd3fd5SAkhil Goyal if (rte_eal_process_type() == RTE_PROC_SECONDARY)
176*33cd3fd5SAkhil Goyal cryptodev_fp_ops_set(rte_crypto_fp_ops +
177*33cd3fd5SAkhil Goyal cryptodev->data->dev_id, cryptodev);
178*33cd3fd5SAkhil Goyal }
179*33cd3fd5SAkhil Goyal
1802fd66f75SAkhil Goyal static uint16_t
dummy_crypto_enqueue_burst(__rte_unused void * qp,__rte_unused struct rte_crypto_op ** ops,__rte_unused uint16_t nb_ops)1812fd66f75SAkhil Goyal dummy_crypto_enqueue_burst(__rte_unused void *qp,
1822fd66f75SAkhil Goyal __rte_unused struct rte_crypto_op **ops,
1832fd66f75SAkhil Goyal __rte_unused uint16_t nb_ops)
1842fd66f75SAkhil Goyal {
1852fd66f75SAkhil Goyal CDEV_LOG_ERR(
1862fd66f75SAkhil Goyal "crypto enqueue burst requested for unconfigured device");
1872fd66f75SAkhil Goyal rte_errno = ENOTSUP;
1882fd66f75SAkhil Goyal return 0;
1892fd66f75SAkhil Goyal }
1902fd66f75SAkhil Goyal
1912fd66f75SAkhil Goyal static uint16_t
dummy_crypto_dequeue_burst(__rte_unused void * qp,__rte_unused struct rte_crypto_op ** ops,__rte_unused uint16_t nb_ops)1922fd66f75SAkhil Goyal dummy_crypto_dequeue_burst(__rte_unused void *qp,
1932fd66f75SAkhil Goyal __rte_unused struct rte_crypto_op **ops,
1942fd66f75SAkhil Goyal __rte_unused uint16_t nb_ops)
1952fd66f75SAkhil Goyal {
1962fd66f75SAkhil Goyal CDEV_LOG_ERR(
1972fd66f75SAkhil Goyal "crypto dequeue burst requested for unconfigured device");
1982fd66f75SAkhil Goyal rte_errno = ENOTSUP;
1992fd66f75SAkhil Goyal return 0;
2002fd66f75SAkhil Goyal }
2012fd66f75SAkhil Goyal
2022fd66f75SAkhil Goyal void
cryptodev_fp_ops_reset(struct rte_crypto_fp_ops * fp_ops)2032fd66f75SAkhil Goyal cryptodev_fp_ops_reset(struct rte_crypto_fp_ops *fp_ops)
2042fd66f75SAkhil Goyal {
2052fd66f75SAkhil Goyal static struct rte_cryptodev_cb_rcu dummy_cb[RTE_MAX_QUEUES_PER_PORT];
2062fd66f75SAkhil Goyal static void *dummy_data[RTE_MAX_QUEUES_PER_PORT];
2072fd66f75SAkhil Goyal static const struct rte_crypto_fp_ops dummy = {
2082fd66f75SAkhil Goyal .enqueue_burst = dummy_crypto_enqueue_burst,
2092fd66f75SAkhil Goyal .dequeue_burst = dummy_crypto_dequeue_burst,
2102fd66f75SAkhil Goyal .qp = {
2112fd66f75SAkhil Goyal .data = dummy_data,
2122fd66f75SAkhil Goyal .enq_cb = dummy_cb,
2132fd66f75SAkhil Goyal .deq_cb = dummy_cb,
2142fd66f75SAkhil Goyal },
2152fd66f75SAkhil Goyal };
2162fd66f75SAkhil Goyal
2172fd66f75SAkhil Goyal *fp_ops = dummy;
2182fd66f75SAkhil Goyal }
2192fd66f75SAkhil Goyal
2202fd66f75SAkhil Goyal void
cryptodev_fp_ops_set(struct rte_crypto_fp_ops * fp_ops,const struct rte_cryptodev * dev)2212fd66f75SAkhil Goyal cryptodev_fp_ops_set(struct rte_crypto_fp_ops *fp_ops,
2222fd66f75SAkhil Goyal const struct rte_cryptodev *dev)
2232fd66f75SAkhil Goyal {
2242fd66f75SAkhil Goyal fp_ops->enqueue_burst = dev->enqueue_burst;
2252fd66f75SAkhil Goyal fp_ops->dequeue_burst = dev->dequeue_burst;
2262fd66f75SAkhil Goyal fp_ops->qp.data = dev->data->queue_pairs;
2272fd66f75SAkhil Goyal fp_ops->qp.enq_cb = dev->enq_cbs;
2282fd66f75SAkhil Goyal fp_ops->qp.deq_cb = dev->deq_cbs;
2292fd66f75SAkhil Goyal }
230