crypto/nitrox: add software queue management
[dpdk.git] / drivers / crypto / nitrox / nitrox_sym.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <stdbool.h>
6
7 #include <rte_cryptodev_pmd.h>
8 #include <rte_crypto.h>
9
10 #include "nitrox_sym.h"
11 #include "nitrox_device.h"
12 #include "nitrox_qp.h"
13 #include "nitrox_sym_reqmgr.h"
14 #include "nitrox_logs.h"
15
16 #define CRYPTODEV_NAME_NITROX_PMD crypto_nitrox_sym
17 #define NPS_PKT_IN_INSTR_SIZE 64
18
19 struct nitrox_sym_device {
20         struct rte_cryptodev *cdev;
21         struct nitrox_device *ndev;
22 };
23
24 uint8_t nitrox_sym_drv_id;
25 static const char nitrox_sym_drv_name[] = RTE_STR(CRYPTODEV_NAME_NITROX_PMD);
26 static const struct rte_driver nitrox_rte_sym_drv = {
27         .name = nitrox_sym_drv_name,
28         .alias = nitrox_sym_drv_name
29 };
30
31 static int nitrox_sym_dev_qp_release(struct rte_cryptodev *cdev,
32                                      uint16_t qp_id);
33
34 static int
35 nitrox_sym_dev_config(struct rte_cryptodev *cdev,
36                       struct rte_cryptodev_config *config)
37 {
38         struct nitrox_sym_device *sym_dev = cdev->data->dev_private;
39         struct nitrox_device *ndev = sym_dev->ndev;
40
41         if (config->nb_queue_pairs > ndev->nr_queues) {
42                 NITROX_LOG(ERR, "Invalid queue pairs, max supported %d\n",
43                            ndev->nr_queues);
44                 return -EINVAL;
45         }
46
47         return 0;
48 }
49
50 static int
51 nitrox_sym_dev_start(struct rte_cryptodev *cdev)
52 {
53         /* SE cores initialization is done in PF */
54         RTE_SET_USED(cdev);
55         return 0;
56 }
57
58 static void
59 nitrox_sym_dev_stop(struct rte_cryptodev *cdev)
60 {
61         /* SE cores cleanup is done in PF */
62         RTE_SET_USED(cdev);
63 }
64
65 static int
66 nitrox_sym_dev_close(struct rte_cryptodev *cdev)
67 {
68         int i, ret;
69
70         for (i = 0; i < cdev->data->nb_queue_pairs; i++) {
71                 ret = nitrox_sym_dev_qp_release(cdev, i);
72                 if (ret)
73                         return ret;
74         }
75
76         return 0;
77 }
78
79 static void
80 nitrox_sym_dev_info_get(struct rte_cryptodev *cdev,
81                         struct rte_cryptodev_info *info)
82 {
83         struct nitrox_sym_device *sym_dev = cdev->data->dev_private;
84         struct nitrox_device *ndev = sym_dev->ndev;
85
86         if (!info)
87                 return;
88
89         info->max_nb_queue_pairs = ndev->nr_queues;
90         info->feature_flags = cdev->feature_flags;
91         info->driver_id = nitrox_sym_drv_id;
92         info->sym.max_nb_sessions = 0;
93 }
94
95 static void
96 nitrox_sym_dev_stats_get(struct rte_cryptodev *cdev,
97                          struct rte_cryptodev_stats *stats)
98 {
99         int qp_id;
100
101         for (qp_id = 0; qp_id < cdev->data->nb_queue_pairs; qp_id++) {
102                 struct nitrox_qp *qp = cdev->data->queue_pairs[qp_id];
103
104                 if (!qp)
105                         continue;
106
107                 stats->enqueued_count += qp->stats.enqueued_count;
108                 stats->dequeued_count += qp->stats.dequeued_count;
109                 stats->enqueue_err_count += qp->stats.enqueue_err_count;
110                 stats->dequeue_err_count += qp->stats.dequeue_err_count;
111         }
112 }
113
114 static void
115 nitrox_sym_dev_stats_reset(struct rte_cryptodev *cdev)
116 {
117         int qp_id;
118
119         for (qp_id = 0; qp_id < cdev->data->nb_queue_pairs; qp_id++) {
120                 struct nitrox_qp *qp = cdev->data->queue_pairs[qp_id];
121
122                 if (!qp)
123                         continue;
124
125                 memset(&qp->stats, 0, sizeof(qp->stats));
126         }
127 }
128
129 static int
130 nitrox_sym_dev_qp_setup(struct rte_cryptodev *cdev, uint16_t qp_id,
131                         const struct rte_cryptodev_qp_conf *qp_conf,
132                         int socket_id)
133 {
134         struct nitrox_sym_device *sym_dev = cdev->data->dev_private;
135         struct nitrox_device *ndev = sym_dev->ndev;
136         struct nitrox_qp *qp = NULL;
137         int err;
138
139         NITROX_LOG(DEBUG, "queue %d\n", qp_id);
140         if (qp_id >= ndev->nr_queues) {
141                 NITROX_LOG(ERR, "queue %u invalid, max queues supported %d\n",
142                            qp_id, ndev->nr_queues);
143                 return -EINVAL;
144         }
145
146         if (cdev->data->queue_pairs[qp_id]) {
147                 err = nitrox_sym_dev_qp_release(cdev, qp_id);
148                 if (err)
149                         return err;
150         }
151
152         qp = rte_zmalloc_socket("nitrox PMD qp", sizeof(*qp),
153                                 RTE_CACHE_LINE_SIZE,
154                                 socket_id);
155         if (!qp) {
156                 NITROX_LOG(ERR, "Failed to allocate nitrox qp\n");
157                 return -ENOMEM;
158         }
159
160         qp->qno = qp_id;
161         err = nitrox_qp_setup(qp, ndev->bar_addr, cdev->data->name,
162                               qp_conf->nb_descriptors, NPS_PKT_IN_INSTR_SIZE,
163                               socket_id);
164         if (unlikely(err))
165                 goto qp_setup_err;
166
167         qp->sr_mp = nitrox_sym_req_pool_create(cdev, qp->count, qp_id,
168                                                socket_id);
169         if (unlikely(!qp->sr_mp))
170                 goto req_pool_err;
171
172         cdev->data->queue_pairs[qp_id] = qp;
173         NITROX_LOG(DEBUG, "queue %d setup done\n", qp_id);
174         return 0;
175
176 req_pool_err:
177         nitrox_qp_release(qp, ndev->bar_addr);
178 qp_setup_err:
179         rte_free(qp);
180         return err;
181 }
182
183 static int
184 nitrox_sym_dev_qp_release(struct rte_cryptodev *cdev, uint16_t qp_id)
185 {
186         struct nitrox_sym_device *sym_dev = cdev->data->dev_private;
187         struct nitrox_device *ndev = sym_dev->ndev;
188         struct nitrox_qp *qp;
189         int err;
190
191         NITROX_LOG(DEBUG, "queue %d\n", qp_id);
192         if (qp_id >= ndev->nr_queues) {
193                 NITROX_LOG(ERR, "queue %u invalid, max queues supported %d\n",
194                            qp_id, ndev->nr_queues);
195                 return -EINVAL;
196         }
197
198         qp = cdev->data->queue_pairs[qp_id];
199         if (!qp) {
200                 NITROX_LOG(DEBUG, "queue %u already freed\n", qp_id);
201                 return 0;
202         }
203
204         if (!nitrox_qp_is_empty(qp)) {
205                 NITROX_LOG(ERR, "queue %d not empty\n", qp_id);
206                 return -EAGAIN;
207         }
208
209         cdev->data->queue_pairs[qp_id] = NULL;
210         err = nitrox_qp_release(qp, ndev->bar_addr);
211         nitrox_sym_req_pool_free(qp->sr_mp);
212         rte_free(qp);
213         NITROX_LOG(DEBUG, "queue %d release done\n", qp_id);
214         return err;
215 }
216
217 static struct rte_cryptodev_ops nitrox_cryptodev_ops = {
218         .dev_configure          = nitrox_sym_dev_config,
219         .dev_start              = nitrox_sym_dev_start,
220         .dev_stop               = nitrox_sym_dev_stop,
221         .dev_close              = nitrox_sym_dev_close,
222         .dev_infos_get          = nitrox_sym_dev_info_get,
223         .stats_get              = nitrox_sym_dev_stats_get,
224         .stats_reset            = nitrox_sym_dev_stats_reset,
225         .queue_pair_setup       = nitrox_sym_dev_qp_setup,
226         .queue_pair_release     = nitrox_sym_dev_qp_release,
227         .sym_session_get_size   = NULL,
228         .sym_session_configure  = NULL,
229         .sym_session_clear      = NULL
230 };
231
232 int
233 nitrox_sym_pmd_create(struct nitrox_device *ndev)
234 {
235         char name[RTE_CRYPTODEV_NAME_MAX_LEN];
236         struct rte_cryptodev_pmd_init_params init_params = {
237                         .name = "",
238                         .socket_id = ndev->pdev->device.numa_node,
239                         .private_data_size = sizeof(struct nitrox_sym_device)
240         };
241         struct rte_cryptodev *cdev;
242
243         rte_pci_device_name(&ndev->pdev->addr, name, sizeof(name));
244         snprintf(name + strlen(name), RTE_CRYPTODEV_NAME_MAX_LEN, "_n5sym");
245         ndev->rte_sym_dev.driver = &nitrox_rte_sym_drv;
246         ndev->rte_sym_dev.numa_node = ndev->pdev->device.numa_node;
247         ndev->rte_sym_dev.devargs = NULL;
248         cdev = rte_cryptodev_pmd_create(name, &ndev->rte_sym_dev,
249                                         &init_params);
250         if (!cdev) {
251                 NITROX_LOG(ERR, "Cryptodev '%s' creation failed\n", name);
252                 return -ENODEV;
253         }
254
255         ndev->rte_sym_dev.name = cdev->data->name;
256         cdev->driver_id = nitrox_sym_drv_id;
257         cdev->dev_ops = &nitrox_cryptodev_ops;
258         cdev->enqueue_burst = NULL;
259         cdev->dequeue_burst = NULL;
260         cdev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
261                 RTE_CRYPTODEV_FF_HW_ACCELERATED;
262
263         ndev->sym_dev = cdev->data->dev_private;
264         ndev->sym_dev->cdev = cdev;
265         ndev->sym_dev->ndev = ndev;
266         NITROX_LOG(DEBUG, "Created cryptodev '%s', dev_id %d, drv_id %d\n",
267                    cdev->data->name, cdev->data->dev_id, nitrox_sym_drv_id);
268         return 0;
269 }
270
271 int
272 nitrox_sym_pmd_destroy(struct nitrox_device *ndev)
273 {
274         return rte_cryptodev_pmd_destroy(ndev->sym_dev->cdev);
275 }
276
277 static struct cryptodev_driver nitrox_crypto_drv;
278 RTE_PMD_REGISTER_CRYPTO_DRIVER(nitrox_crypto_drv,
279                 nitrox_rte_sym_drv,
280                 nitrox_sym_drv_id);