Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136880320
D45592.id140228.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D45592.id140228.diff
View Options
diff --git a/sys/arm64/qoriq/caam/caam.c b/sys/arm64/qoriq/caam/caam.c
--- a/sys/arm64/qoriq/caam/caam.c
+++ b/sys/arm64/qoriq/caam/caam.c
@@ -11,6 +11,9 @@
#include <sys/cdefs.h>
#include "opt_caam.h" /* For the CAAM_DEBUG option */
+#ifdef CAAM_DEBUG
+#include "caam_test.h"
+#endif
#include <sys/param.h>
#include <sys/bus.h>
@@ -28,10 +31,13 @@
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
+#include <opencrypto/cryptodev.h>
+#include "cryptodev_if.h"
+
#include "caam.h"
+#include "caam_crypto.h"
#include "caam_debug.h"
#include "caam_internal.h"
-#include "caam_test.h"
#include "caam_trng.h"
#include "jr/caam_jobdesc.h"
#include "jr/caam_jr.h"
@@ -428,21 +434,29 @@
goto cleanup_jobrings;
}
+ rv = caam_crypto_attach(dev);
+ if (rv != 0) {
+ CAAM_LOG_ERROR("caam_crypto_attach failed rv=(%d)\n", rv);
+ goto cleanup_trng;
+ }
+
#ifdef CAAM_DEBUG
/* Add the caam test device for development */
rv = caam_test_attach(dev);
if (rv != 0) {
CAAM_LOG_ERROR("caam_test_attach failed rv=(%d)\n", rv);
- goto cleanup_trng;
+ goto cleanup_crypto;
}
#endif
return (0);
#ifdef CAAM_DEBUG
+cleanup_crypto:
+ caam_crypto_detach(dev);
+#endif
cleanup_trng:
caam_trng_detach(dev);
-#endif
cleanup_jobrings:
caam_jobrings_detach(dev);
cleanup_rman:
@@ -505,6 +519,8 @@
{
struct caam_softc *sc = device_get_softc(dev);
+ caam_crypto_detach(dev);
+
/* Remove TRNG drivers */
caam_trng_detach(dev);
#ifdef CAAM_DEBUG
@@ -661,6 +677,11 @@
DEVMETHOD(bus_activate_resource, caam_activate_resource),
DEVMETHOD(bus_release_resource, caam_release_resource),
+ DEVMETHOD(cryptodev_probesession, caam_crypto_probesession),
+ DEVMETHOD(cryptodev_newsession, caam_crypto_newsession),
+ DEVMETHOD(cryptodev_freesession, caam_crypto_freesession),
+ DEVMETHOD(cryptodev_process, caam_crypto_process),
+
DEVMETHOD_END
};
@@ -668,4 +689,5 @@
simplebus_driver);
DRIVER_MODULE(caam, simplebus, caam_driver, 0, 0);
+MODULE_DEPEND(caam, crypto, 1, 1, 1);
MODULE_VERSION(caam, 1);
diff --git a/sys/arm64/qoriq/caam/caam_crypto.h b/sys/arm64/qoriq/caam/caam_crypto.h
new file mode 100644
--- /dev/null
+++ b/sys/arm64/qoriq/caam/caam_crypto.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2024 Alstom Group
+ * Copyright 2024 Sii Poland
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CAAM_CRYPTO_H
+#define CAAM_CRYPTO_H
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/rwlock.h>
+#include <sys/smp.h>
+
+#include <machine/bus.h>
+#include <machine/vfp.h>
+
+#include <opencrypto/cryptodev.h>
+#include <opencrypto/xform.h>
+
+/*
+ * @brief Register with crypto framework and get assigned crypto id.
+ *
+ * @param [in] dev caam device handle
+ *
+ * @retval :: 0 is returned on success
+ * @retval :: errno is returned on internal error
+ */
+int caam_crypto_attach(device_t dev);
+
+/*
+ * @brief Unregister assigned crypto id from crypto framework.
+ *
+ * @param [in] dev caam device handle
+ */
+void caam_crypto_detach(device_t dev);
+
+/*
+ * @brief CAAM cryptodev_probesession devmethod.
+ *
+ * Informs crypto framework about CAAM crypto supported operations.
+ *
+ * @param [in] dev caam device handle
+ *
+ * @retval :: int acceleration type CAAM provides for probed algorithm
+ * @retval :: errno EINVAL on unsuppored operations
+ */
+int caam_crypto_probesession(device_t dev,
+ const struct crypto_session_params *csp);
+
+/*
+ * @brief CAAM cryptodev_freesession devmethod.
+ *
+ * Free a crypto session.
+ *
+ * @param [in] dev caam device handle
+ * @param [in] cses crypto session id
+ */
+void caam_crypto_freesession(device_t dev, crypto_session_t cses);
+
+/*
+ * @brief CAAM cryptodev_newsession devmethod.
+ *
+ * Initialize a new crypto session.
+ *
+ * @param [in] dev caam device handle
+ * @param [in] cses crypto session id
+ * @param [in] csp crypto session parameters
+ *
+ * @retval :: 0 is returned on success
+ * @retval :: errno is returned on internal error
+ */
+int caam_crypto_newsession(device_t dev, crypto_session_t cses,
+ const struct crypto_session_params *csp);
+
+/*
+ * @brief CAAM cryptodev_process devmethod.
+ *
+ * Start processing a crypto request.
+ *
+ * @param [in] dev caam device handle
+ * @param [in] crp Structure describing complete operation
+ * @param [in] hint processing hint
+ *
+ * @retval :: 0 is returned on success
+ * @retval :: errno is returned on internal error
+ */
+int caam_crypto_process(device_t dev, struct cryptop *crp, int hint);
+
+#endif /* CAAM_CRYPTO_H */
diff --git a/sys/arm64/qoriq/caam/caam_crypto.c b/sys/arm64/qoriq/caam/caam_crypto.c
new file mode 100644
--- /dev/null
+++ b/sys/arm64/qoriq/caam/caam_crypto.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2024 Alstom Group
+ * Copyright 2024 Sii Poland
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/mutex.h>
+#include <sys/rwlock.h>
+#include <sys/smp.h>
+#include <sys/uio.h>
+
+#include <machine/bus.h>
+#include <machine/vfp.h>
+
+#include <opencrypto/cryptodev.h>
+#include <opencrypto/xform.h>
+
+#include "caam.h"
+#include "caam_crypto.h"
+#include "caam_debug.h"
+#include "caam_internal.h"
+#include "jr/caam_desc_helper.h"
+#include "jr/caam_jobdesc.h"
+#include "jr/caam_jr.h"
+#include "jr/caam_jr_hw.h"
+
+SDT_PROVIDER_DEFINE(caam_crypto);
+SDT_PROBE_DEFINE0(caam_crypto, , func, process__start);
+SDT_PROBE_DEFINE0(caam_crypto, , func, process__end);
+
+MALLOC_DEFINE(M_CAAM_CRYPTO, "caam_crypto", "CAAM crypto device");
+
+struct caam_session {
+ size_t keylen;
+ size_t data_size;
+ bool encrypt;
+
+ struct caam_softc *sc;
+};
+
+struct caam_operation {
+ struct job_descriptor jobdesc;
+ size_t keylen;
+ bool encrypt;
+
+ caam_jr_dma_map_t data;
+ caam_jr_dma_map_t key;
+ caam_jr_dma_map_t sgtm;
+
+ uint8_t iv[AES_XTS_IV_LEN];
+ struct caam_sgt_entry sgt[MAX_SGT_ENTRIES];
+
+ struct caam_session *ses;
+ struct cryptop *crp;
+ device_t jr_dev;
+};
+
+MALLOC_DEFINE(M_CAAM, "caam", "caam cryptography buffers");
+
+static void
+dma_data_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ struct caam_sgt_entry *sg;
+ struct caam_operation *op;
+
+ op = (struct caam_operation *)arg;
+
+ if (error) {
+ CAAM_LOG_WARN("dma_data_callback error: %i!\n", error);
+ return;
+ }
+
+ if (nseg == 1) {
+ op->data.bus_addr = segs[0].ds_addr;
+ return;
+ }
+
+ op->data.bus_addr = 0;
+ for (int i = 0; i < nseg; i++) {
+ sg = &op->sgt[i];
+
+ sg->ptr_hi = htobe32(PHYS_ADDR_HI(segs[i].ds_addr));
+ sg->ptr_lo = htobe32(PHYS_ADDR_LO(segs[i].ds_addr));
+ sg->len_f_e = segs[i].ds_len;
+ sg->offset = 0;
+
+ if (i == nseg - 1) {
+ sg->len_f_e |= CAAM_SGT_FINAL;
+ }
+ sg->len_f_e = htobe32(sg->len_f_e);
+ }
+}
+
+static void
+caam_aes_xts_build_desc(struct caam_operation *op, bool little_endian)
+{
+ uint32_t *iv_ptr = (uint32_t *)op->iv;
+ uint32_t *desc = op->jobdesc.desc;
+
+ caam_jobdesc_init(desc);
+
+ caam_jobdesc_add_word(desc, DESC_HEADER(0));
+
+ caam_jobdesc_add_word(desc, LD_KEY_PLAIN(CLASS_1, REG, op->keylen));
+ caam_jobdesc_add_ptr(desc, op->key.bus_addr, little_endian);
+
+ caam_jobdesc_add_word(desc, LD_IMM_OFF(CLASS_1, REG_CTX, 8, 0x28));
+ caam_jobdesc_add_word(desc, 0);
+ caam_jobdesc_add_word(desc, 1 << 15);
+
+ /* NOTE: This will not work on big endian platforms */
+ caam_jobdesc_add_word(desc, LD_IMM_OFF(CLASS_1, REG_CTX, 8, 0x20));
+ caam_jobdesc_add_word(desc, htobe32(iv_ptr[0]));
+ caam_jobdesc_add_word(desc, htobe32(iv_ptr[1]));
+
+ caam_jobdesc_add_word(desc,
+ CIPHER_INIT_FINAL(OP_ALGO(AES), op->encrypt) | ALGO_AAI(AES_XTS));
+
+ if (op->data.bus_addr != 0) {
+ caam_jobdesc_add_word(desc, FIFO_LD_EXT(CLASS_1, MSG, LAST_C1));
+ caam_jobdesc_add_ptr(desc, op->data.bus_addr, little_endian);
+ caam_jobdesc_add_word(desc, op->data.buflen);
+
+ caam_jobdesc_add_word(desc, FIFO_ST_EXT(MSG_DATA));
+ caam_jobdesc_add_ptr(desc, op->data.bus_addr, little_endian);
+ caam_jobdesc_add_word(desc, op->data.buflen);
+ } else {
+ caam_jobdesc_add_word(desc,
+ FIFO_LD_SGT_EXT(CLASS_1, MSG, LAST_C1));
+ caam_jobdesc_add_ptr(desc, op->sgtm.bus_addr, little_endian);
+ caam_jobdesc_add_word(desc, op->data.buflen);
+
+ caam_jobdesc_add_word(desc, FIFO_ST_SGT_EXT(MSG_DATA));
+ caam_jobdesc_add_ptr(desc, op->sgtm.bus_addr, little_endian);
+ caam_jobdesc_add_word(desc, op->data.buflen);
+ }
+}
+
+int
+caam_crypto_probesession(device_t dev, const struct crypto_session_params *csp)
+{
+ if (csp->csp_flags != 0)
+ return (EINVAL);
+ switch (csp->csp_mode) {
+ case CSP_MODE_CIPHER:
+ switch (csp->csp_cipher_alg) {
+ case CRYPTO_AES_XTS:
+ if (csp->csp_ivlen != AES_XTS_IV_LEN)
+ return (EINVAL);
+ switch (csp->csp_cipher_klen * 8) {
+ case 256:
+ case 512:
+ break;
+ default:
+ return (EINVAL);
+ }
+ break;
+ default:
+ return (EINVAL);
+ }
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (CRYPTODEV_PROBE_HARDWARE);
+}
+
+void
+caam_crypto_freesession(device_t dev, crypto_session_t cses)
+{
+ /* Nothing to do */
+}
+
+/*
+ * Generate a new software session.
+ */
+int
+caam_crypto_newsession(device_t dev, crypto_session_t cses,
+ const struct crypto_session_params *csp)
+{
+ struct caam_session *ses;
+ struct caam_softc *sc;
+
+ sc = device_get_softc(dev);
+ ses = crypto_get_driver_session(cses);
+ if (ses == NULL) {
+ CAAM_LOG_DEV_WARN(dev, "Cannot create new session\n");
+ return (EINVAL);
+ }
+
+ ses->sc = sc;
+
+ return (0);
+}
+
+static void
+crypto_process_done(uint32_t *desc, uint32_t status, void *arg, device_t dev)
+{
+#if defined(CAAM_JR_MODE_ASYNC)
+ struct caam_operation *op;
+ bus_dma_tag_t jr_data_tag;
+ int rv = 0;
+
+ op = (struct caam_operation *)arg;
+ if (status != 0)
+ op->crp->crp_etype = EIO;
+ else
+ op->crp->crp_etype = 0;
+
+ jr_data_tag = caam_jr_get_data_tag(op->jr_dev);
+
+ rv = caam_jr_dma_unmap(op->jr_dev, &op->key, JR_MAP_NOSYNC);
+ if (rv != 0) {
+ CAAM_LOG_ERROR("%s: Failed to destroy key\n", __func__);
+ }
+
+ bus_dmamap_sync(jr_data_tag, op->data.mmap, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(jr_data_tag, op->data.mmap);
+ rv = bus_dmamap_destroy(jr_data_tag, op->data.mmap);
+ if (rv != 0) {
+ CAAM_LOG_ERROR("%s: Failed to destroy data\n", __func__);
+ }
+
+ if (op->data.bus_addr == 0) {
+ rv = caam_jr_dma_unmap(op->jr_dev, &op->sgtm, JR_MAP_NOSYNC);
+ if (rv != 0) {
+ CAAM_LOG_ERROR("%s: Failed to destroy sgt\n", __func__);
+ }
+ }
+
+ jr_pool_release(&op->ses->sc->jr_pool, op->jr_dev);
+
+ crypto_done(op->crp);
+
+ free(op, M_CAAM_CRYPTO);
+#endif /* CAAM_JR_MODE_ASYNC */
+}
+
+int
+caam_crypto_process(device_t dev, struct cryptop *crp, int hint)
+{
+ const struct crypto_session_params *csp;
+ struct caam_session *ses;
+ const void *key_vaddr;
+ int rv = 0;
+ struct caam_operation *op;
+ struct caam_softc *sc;
+ bus_dma_tag_t jr_data_tag;
+
+ SDT_PROBE0(caam_crypto, , func, process__start);
+
+ sc = device_get_softc(dev);
+ ses = crypto_get_driver_session(crp->crp_session);
+ csp = crypto_get_params(crp->crp_session);
+ ses->keylen = csp->csp_cipher_klen;
+ ses->data_size = crp->crp_payload_length;
+ ses->encrypt = CRYPTO_OP_IS_ENCRYPT(crp->crp_op);
+
+ op = malloc_aligned(sizeof(struct caam_operation), PAGE_SIZE,
+ M_CAAM_CRYPTO, M_NOWAIT);
+ if (op == NULL) {
+ CAAM_LOG_DEV_WARN(dev,
+ "Failed to allocate caam operation structure\n");
+ rv = ENOMEM;
+ goto exit;
+ }
+
+ op->keylen = ses->keylen;
+ op->data.buflen = ses->data_size;
+ op->encrypt = ses->encrypt;
+ op->ses = ses;
+ op->crp = crp;
+
+ op->jobdesc.arg = op;
+ op->jobdesc.callback = crypto_process_done;
+
+ op->jr_dev = jr_pool_acquire(&sc->jr_pool);
+ if (op->jr_dev == 0) {
+ CAAM_LOG_DEV_WARN(dev, "Failed to acquire JR\n");
+ rv = EAGAIN;
+ goto operation_cleanup;
+ }
+ jr_data_tag = caam_jr_get_data_tag(op->jr_dev);
+
+ crypto_read_iv(crp, op->iv);
+ if (crp->crp_cipher_key)
+ key_vaddr = crp->crp_cipher_key;
+ else
+ key_vaddr = csp->csp_cipher_key;
+
+ /* Map and sync the key buffer */
+ rv = caam_jr_dma_map(op->jr_dev, &op->key, __DECONST(void *, key_vaddr),
+ ses->keylen, BUS_DMA_COHERENT, BUS_DMA_NOWAIT, JR_MAP_SYNC);
+ if (rv != 0) {
+ CAAM_LOG_DEV_WARN(dev, "Failed to create key map\n");
+ goto release_jr;
+ }
+
+ /* Map and sync the data buffer */
+ rv = bus_dmamap_create(jr_data_tag, BUS_DMA_COHERENT, &op->data.mmap);
+ if (rv != 0) {
+ CAAM_LOG_DEV_WARN(dev, "Failed to create data map\n");
+ goto key_map_cleanup;
+ }
+ op->data.bus_addr = ULONG_MAX;
+ rv = bus_dmamap_load_crp_buffer(jr_data_tag, op->data.mmap,
+ &crp->crp_buf, dma_data_callback, op, BUS_DMA_NOWAIT);
+ if ((rv != 0) || (op->data.bus_addr == ULONG_MAX)) {
+ CAAM_LOG_DEV_WARN(dev, "Failed to load data map\n");
+ goto data_map_cleanup;
+ }
+ bus_dmamap_sync(jr_data_tag, op->data.mmap, BUS_DMASYNC_PREWRITE);
+
+ /* If scatter gather is used map and sync the sgt buffer */
+ if (op->data.bus_addr == 0) {
+ rv = caam_jr_dma_map(op->jr_dev, &op->sgtm, op->sgt,
+ sizeof(op->sgt), BUS_DMA_COHERENT, BUS_DMA_NOWAIT,
+ JR_MAP_SYNC);
+ if (rv != 0) {
+ CAAM_LOG_DEV_WARN(dev, "Failed to create sgt map\n");
+ goto data_load_cleanup;
+ }
+ }
+
+ caam_aes_xts_build_desc(op, sc->little_endian);
+#if defined(CAAM_JR_MODE_ASYNC)
+ rv = caam_run_descriptor_jr_async(dev, &op->jobdesc, op->jr_dev);
+#else
+ rv = caam_run_descriptor_jr_blocking(dev, &op->jobdesc, op->jr_dev);
+#endif /* defined(CAAM_JR_MODE_ASYNC) */
+ if (rv != 0) {
+ CAAM_LOG_DEV_WARN(dev, "Failed to run job descriptor\n");
+ goto sgt_map_cleanup;
+ }
+
+#if defined(CAAM_JR_MODE_ASYNC)
+ return (0);
+#endif /* defined(CAAM_JR_MODE_ASYNC) */
+
+ /* For S/G paddr should be set to 0 */
+sgt_map_cleanup:
+ if (op->data.bus_addr == 0)
+ caam_jr_dma_unmap(op->jr_dev, &op->sgtm, JR_MAP_NOSYNC);
+data_load_cleanup:
+ bus_dmamap_unload(jr_data_tag, op->data.mmap);
+data_map_cleanup:
+ bus_dmamap_destroy(jr_data_tag, op->data.mmap);
+key_map_cleanup:
+ caam_jr_dma_unmap(op->jr_dev, &op->key, JR_MAP_NOSYNC);
+release_jr:
+ jr_pool_release(&sc->jr_pool, op->jr_dev);
+operation_cleanup:
+ free(op, M_CAAM_CRYPTO);
+exit:
+ crp->crp_etype = rv;
+ crypto_done(crp);
+
+ SDT_PROBE0(caam_crypto, , func, process__end);
+
+ return (0);
+}
+
+int
+caam_crypto_attach(device_t dev)
+{
+ struct caam_softc *sc;
+ int error = 0;
+
+ sc = device_get_softc(dev);
+
+ sc->crypto_id = crypto_get_driverid(dev,
+ sizeof(struct caam_session), CRYPTOCAP_F_HARDWARE);
+ if (sc->crypto_id < 0) {
+ CAAM_LOG_DEV_WARN(dev,
+ "Failed to initialize crypto device\n");
+ return (ENXIO);
+ }
+
+ return (error);
+}
+
+void
+caam_crypto_detach(device_t dev)
+{
+ struct caam_softc *sc;
+
+ sc = device_get_softc(dev);
+ crypto_unregister_all(sc->crypto_id);
+}
diff --git a/sys/arm64/qoriq/caam/caam_internal.h b/sys/arm64/qoriq/caam/caam_internal.h
--- a/sys/arm64/qoriq/caam/caam_internal.h
+++ b/sys/arm64/qoriq/caam/caam_internal.h
@@ -31,6 +31,8 @@
bool little_endian;
struct jr_pool jr_pool;
+
+ int32_t crypto_id;
};
#endif /* CAAM_INTERNAL_H */
diff --git a/sys/arm64/qoriq/caam/caam_test.c b/sys/arm64/qoriq/caam/caam_test.c
--- a/sys/arm64/qoriq/caam/caam_test.c
+++ b/sys/arm64/qoriq/caam/caam_test.c
@@ -26,7 +26,6 @@
#include "caam_internal.h"
#include "caam_test.h"
#include "jr/caam_jobdesc.h"
-#include "jr/caam_jr_hw.h"
/* Reference to the CAAM device on witch to execute the tests. */
static device_t g_caam_dev;
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -687,6 +687,7 @@
arm64/qoriq/clk/qoriq_clk_pll.c optional clk soc_nxp_ls
arm64/qoriq/clk/qoriq_clkgen.c optional clk soc_nxp_ls fdt
arm64/qoriq/caam/caam.c optional caam soc_nxp_ls
+arm64/qoriq/caam/caam_crypto.c optional caam soc_nxp_ls
arm64/qoriq/caam/caam_trng.c optional caam soc_nxp_ls
arm64/qoriq/caam/caam_test.c optional caam caam_debug soc_nxp_ls
arm64/qoriq/caam/jr/caam_jr.c optional caam soc_nxp_ls
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 21, 9:09 AM (21 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25758271
Default Alt Text
D45592.id140228.diff (15 KB)
Attached To
Mode
D45592: caam: Add caam_crypto support in caam driver
Attached
Detach File
Event Timeline
Log In to Comment