4 * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
5 * Copyright (c) 2016 NXP. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Freescale Semiconductor, Inc nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <rte_cryptodev.h>
39 #include <rte_malloc.h>
40 #include <rte_memcpy.h>
41 #include <rte_string_fns.h>
42 #include <rte_cycles.h>
43 #include <rte_kvargs.h>
45 #include <rte_cryptodev_pmd.h>
46 #include <rte_common.h>
47 #include <rte_fslmc.h>
48 #include <fslmc_vfio.h>
49 #include <dpaa2_hw_pvt.h>
50 #include <dpaa2_hw_dpio.h>
51 #include <fsl_dpseci.h>
52 #include <fsl_mc_sys.h>
54 #include "dpaa2_sec_priv.h"
55 #include "dpaa2_sec_logs.h"
57 #define FSL_VENDOR_ID 0x1957
58 #define FSL_DEVICE_ID 0x410
59 #define FSL_SUBSYSTEM_SEC 1
60 #define FSL_MC_DPSECI_DEVID 3
63 dpaa2_sec_dev_configure(struct rte_cryptodev *dev __rte_unused,
64 struct rte_cryptodev_config *config __rte_unused)
66 PMD_INIT_FUNC_TRACE();
72 dpaa2_sec_dev_start(struct rte_cryptodev *dev)
74 struct dpaa2_sec_dev_private *priv = dev->data->dev_private;
75 struct fsl_mc_io *dpseci = (struct fsl_mc_io *)priv->hw;
76 struct dpseci_attr attr;
77 struct dpaa2_queue *dpaa2_q;
78 struct dpaa2_sec_qp **qp = (struct dpaa2_sec_qp **)
79 dev->data->queue_pairs;
80 struct dpseci_rx_queue_attr rx_attr;
81 struct dpseci_tx_queue_attr tx_attr;
84 PMD_INIT_FUNC_TRACE();
86 memset(&attr, 0, sizeof(struct dpseci_attr));
88 ret = dpseci_enable(dpseci, CMD_PRI_LOW, priv->token);
90 PMD_INIT_LOG(ERR, "DPSECI with HW_ID = %d ENABLE FAILED\n",
92 goto get_attr_failure;
94 ret = dpseci_get_attributes(dpseci, CMD_PRI_LOW, priv->token, &attr);
97 "DPSEC ATTRIBUTE READ FAILED, disabling DPSEC\n");
98 goto get_attr_failure;
100 for (i = 0; i < attr.num_rx_queues && qp[i]; i++) {
101 dpaa2_q = &qp[i]->rx_vq;
102 dpseci_get_rx_queue(dpseci, CMD_PRI_LOW, priv->token, i,
104 dpaa2_q->fqid = rx_attr.fqid;
105 PMD_INIT_LOG(DEBUG, "rx_fqid: %d", dpaa2_q->fqid);
107 for (i = 0; i < attr.num_tx_queues && qp[i]; i++) {
108 dpaa2_q = &qp[i]->tx_vq;
109 dpseci_get_tx_queue(dpseci, CMD_PRI_LOW, priv->token, i,
111 dpaa2_q->fqid = tx_attr.fqid;
112 PMD_INIT_LOG(DEBUG, "tx_fqid: %d", dpaa2_q->fqid);
117 dpseci_disable(dpseci, CMD_PRI_LOW, priv->token);
122 dpaa2_sec_dev_stop(struct rte_cryptodev *dev)
124 struct dpaa2_sec_dev_private *priv = dev->data->dev_private;
125 struct fsl_mc_io *dpseci = (struct fsl_mc_io *)priv->hw;
128 PMD_INIT_FUNC_TRACE();
130 ret = dpseci_disable(dpseci, CMD_PRI_LOW, priv->token);
132 PMD_INIT_LOG(ERR, "Failure in disabling dpseci %d device",
137 ret = dpseci_reset(dpseci, CMD_PRI_LOW, priv->token);
139 PMD_INIT_LOG(ERR, "SEC Device cannot be reset:Error = %0x\n",
146 dpaa2_sec_dev_close(struct rte_cryptodev *dev)
148 struct dpaa2_sec_dev_private *priv = dev->data->dev_private;
149 struct fsl_mc_io *dpseci = (struct fsl_mc_io *)priv->hw;
152 PMD_INIT_FUNC_TRACE();
154 /* Function is reverse of dpaa2_sec_dev_init.
155 * It does the following:
156 * 1. Detach a DPSECI from attached resources i.e. buffer pools, dpbp_id
157 * 2. Close the DPSECI device
158 * 3. Free the allocated resources.
161 /*Close the device at underlying layer*/
162 ret = dpseci_close(dpseci, CMD_PRI_LOW, priv->token);
164 PMD_INIT_LOG(ERR, "Failure closing dpseci device with"
165 " error code %d\n", ret);
169 /*Free the allocated memory for ethernet private data and dpseci*/
177 dpaa2_sec_dev_infos_get(struct rte_cryptodev *dev,
178 struct rte_cryptodev_info *info)
180 struct dpaa2_sec_dev_private *internals = dev->data->dev_private;
182 PMD_INIT_FUNC_TRACE();
184 info->max_nb_queue_pairs = internals->max_nb_queue_pairs;
185 info->feature_flags = dev->feature_flags;
186 info->capabilities = dpaa2_sec_capabilities;
187 info->sym.max_nb_sessions = internals->max_nb_sessions;
188 info->dev_type = RTE_CRYPTODEV_DPAA2_SEC_PMD;
192 static struct rte_cryptodev_ops crypto_ops = {
193 .dev_configure = dpaa2_sec_dev_configure,
194 .dev_start = dpaa2_sec_dev_start,
195 .dev_stop = dpaa2_sec_dev_stop,
196 .dev_close = dpaa2_sec_dev_close,
197 .dev_infos_get = dpaa2_sec_dev_infos_get,
201 dpaa2_sec_uninit(const struct rte_cryptodev_driver *crypto_drv __rte_unused,
202 struct rte_cryptodev *dev)
204 PMD_INIT_LOG(INFO, "Closing DPAA2_SEC device %s on numa socket %u\n",
205 dev->data->name, rte_socket_id());
211 dpaa2_sec_dev_init(struct rte_cryptodev *cryptodev)
213 struct dpaa2_sec_dev_private *internals;
214 struct rte_device *dev = cryptodev->device;
215 struct rte_dpaa2_device *dpaa2_dev;
216 struct fsl_mc_io *dpseci;
218 struct dpseci_attr attr;
221 PMD_INIT_FUNC_TRACE();
222 dpaa2_dev = container_of(dev, struct rte_dpaa2_device, device);
223 if (dpaa2_dev == NULL) {
224 PMD_INIT_LOG(ERR, "dpaa2_device not found\n");
227 hw_id = dpaa2_dev->object_id;
229 cryptodev->dev_type = RTE_CRYPTODEV_DPAA2_SEC_PMD;
230 cryptodev->dev_ops = &crypto_ops;
232 cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
233 RTE_CRYPTODEV_FF_HW_ACCELERATED |
234 RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING;
236 internals = cryptodev->data->dev_private;
237 internals->max_nb_sessions = RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS;
240 * For secondary processes, we don't initialise any further as primary
241 * has already done this work. Only check we don't need a different
244 if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
245 PMD_INIT_LOG(DEBUG, "Device already init by primary process");
248 /*Open the rte device via MC and save the handle for further use*/
249 dpseci = (struct fsl_mc_io *)rte_calloc(NULL, 1,
250 sizeof(struct fsl_mc_io), 0);
253 "Error in allocating the memory for dpsec object");
256 dpseci->regs = rte_mcp_ptr_list[0];
258 retcode = dpseci_open(dpseci, CMD_PRI_LOW, hw_id, &token);
260 PMD_INIT_LOG(ERR, "Cannot open the dpsec device: Error = %x",
264 retcode = dpseci_get_attributes(dpseci, CMD_PRI_LOW, token, &attr);
267 "Cannot get dpsec device attributed: Error = %x",
271 sprintf(cryptodev->data->name, "dpsec-%u", hw_id);
273 internals->max_nb_queue_pairs = attr.num_tx_queues;
274 cryptodev->data->nb_queue_pairs = internals->max_nb_queue_pairs;
275 internals->hw = dpseci;
276 internals->token = token;
278 PMD_INIT_LOG(DEBUG, "driver %s: created\n", cryptodev->data->name);
282 PMD_INIT_LOG(ERR, "driver %s: create failed\n", cryptodev->data->name);
284 /* dpaa2_sec_uninit(crypto_dev_name); */
289 cryptodev_dpaa2_sec_probe(struct rte_dpaa2_driver *dpaa2_drv,
290 struct rte_dpaa2_device *dpaa2_dev)
292 struct rte_cryptodev *cryptodev;
293 char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
297 sprintf(cryptodev_name, "dpsec-%d", dpaa2_dev->object_id);
299 cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id());
300 if (cryptodev == NULL)
303 if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
304 cryptodev->data->dev_private = rte_zmalloc_socket(
305 "cryptodev private structure",
306 sizeof(struct dpaa2_sec_dev_private),
310 if (cryptodev->data->dev_private == NULL)
311 rte_panic("Cannot allocate memzone for private "
315 dpaa2_dev->cryptodev = cryptodev;
316 cryptodev->device = &dpaa2_dev->device;
317 cryptodev->driver = (struct rte_cryptodev_driver *)dpaa2_drv;
319 /* init user callbacks */
320 TAILQ_INIT(&(cryptodev->link_intr_cbs));
322 /* Invoke PMD device initialization function */
323 retval = dpaa2_sec_dev_init(cryptodev);
327 if (rte_eal_process_type() == RTE_PROC_PRIMARY)
328 rte_free(cryptodev->data->dev_private);
330 cryptodev->attached = RTE_CRYPTODEV_DETACHED;
336 cryptodev_dpaa2_sec_remove(struct rte_dpaa2_device *dpaa2_dev)
338 struct rte_cryptodev *cryptodev;
341 cryptodev = dpaa2_dev->cryptodev;
342 if (cryptodev == NULL)
345 ret = dpaa2_sec_uninit(NULL, cryptodev);
349 /* free crypto device */
350 rte_cryptodev_pmd_release_device(cryptodev);
352 if (rte_eal_process_type() == RTE_PROC_PRIMARY)
353 rte_free(cryptodev->data->dev_private);
355 cryptodev->device = NULL;
356 cryptodev->driver = NULL;
357 cryptodev->data = NULL;
362 static struct rte_dpaa2_driver rte_dpaa2_sec_driver = {
363 .drv_type = DPAA2_MC_DPSECI_DEVID,
365 .name = "DPAA2 SEC PMD"
367 .probe = cryptodev_dpaa2_sec_probe,
368 .remove = cryptodev_dpaa2_sec_remove,
371 RTE_PMD_REGISTER_DPAA2(dpaa2_sec_pmd, rte_dpaa2_sec_driver);