layerscape: remove support for kernel 4.14
[openwrt/staging/stintel.git] / target / linux / layerscape / patches-4.14 / 820-sec-support-layerscape.patch
diff --git a/target/linux/layerscape/patches-4.14/820-sec-support-layerscape.patch b/target/linux/layerscape/patches-4.14/820-sec-support-layerscape.patch
deleted file mode 100644 (file)
index 63f6540..0000000
+++ /dev/null
@@ -1,15294 +0,0 @@
-From ba8e92b322a3763880fdc4d19e9c7085f5504be7 Mon Sep 17 00:00:00 2001
-From: Biwen Li <biwen.li@nxp.com>
-Date: Tue, 23 Apr 2019 17:41:43 +0800
-Subject: [PATCH] sec: support layerscape
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is an integrated patch of sec for layerscape
-
-Signed-off-by: Alex Porosanu <alexandru.porosanu@nxp.com>
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Biwen Li <biwen.li@nxp.com>
-Signed-off-by: Carmen Iorga <carmen.iorga@nxp.com>
-Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
-Signed-off-by: Guanhua Gao <guanhua.gao@nxp.com>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
-Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
-Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
-Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
-Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
-Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
----
- crypto/Kconfig                      |   20 +
- crypto/Makefile                     |    1 +
- crypto/chacha20poly1305.c           |    2 -
- crypto/tcrypt.c                     |   27 +-
- crypto/testmgr.c                    |  244 ++
- crypto/testmgr.h                    |  219 ++
- crypto/tls.c                        |  607 ++++
- drivers/crypto/Makefile             |    2 +-
- drivers/crypto/caam/Kconfig         |   85 +-
- drivers/crypto/caam/Makefile        |   26 +-
- drivers/crypto/caam/caamalg.c       |  468 +++-
- drivers/crypto/caam/caamalg_desc.c  |  903 +++++-
- drivers/crypto/caam/caamalg_desc.h  |   52 +-
- drivers/crypto/caam/caamalg_qi.c    | 1060 ++++++-
- drivers/crypto/caam/caamalg_qi2.c   | 5843 +++++++++++++++++++++++++++++++++++
- drivers/crypto/caam/caamalg_qi2.h   |  276 ++
- drivers/crypto/caam/caamhash.c      |  192 +-
- drivers/crypto/caam/caamhash_desc.c |  108 +
- drivers/crypto/caam/caamhash_desc.h |   49 +
- drivers/crypto/caam/caampkc.c       |   52 +-
- drivers/crypto/caam/caamrng.c       |   52 +-
- drivers/crypto/caam/compat.h        |    4 +
- drivers/crypto/caam/ctrl.c          |  194 +-
- drivers/crypto/caam/desc.h          |   89 +-
- drivers/crypto/caam/desc_constr.h   |   59 +-
- drivers/crypto/caam/dpseci.c        |  865 ++++++
- drivers/crypto/caam/dpseci.h        |  433 +++
- drivers/crypto/caam/dpseci_cmd.h    |  287 ++
- drivers/crypto/caam/error.c         |   81 +-
- drivers/crypto/caam/error.h         |    6 +-
- drivers/crypto/caam/intern.h        |  102 +-
- drivers/crypto/caam/jr.c            |   84 +
- drivers/crypto/caam/jr.h            |    2 +
- drivers/crypto/caam/key_gen.c       |   30 -
- drivers/crypto/caam/key_gen.h       |   30 +
- drivers/crypto/caam/qi.c            |  134 +-
- drivers/crypto/caam/qi.h            |    2 +-
- drivers/crypto/caam/regs.h          |   76 +-
- drivers/crypto/caam/sg_sw_qm.h      |   46 +-
- drivers/crypto/talitos.c            |    8 +
- include/crypto/chacha20.h           |    1 +
- 41 files changed, 12088 insertions(+), 733 deletions(-)
- create mode 100644 crypto/tls.c
- create mode 100644 drivers/crypto/caam/caamalg_qi2.c
- create mode 100644 drivers/crypto/caam/caamalg_qi2.h
- create mode 100644 drivers/crypto/caam/caamhash_desc.c
- create mode 100644 drivers/crypto/caam/caamhash_desc.h
- create mode 100644 drivers/crypto/caam/dpseci.c
- create mode 100644 drivers/crypto/caam/dpseci.h
- create mode 100644 drivers/crypto/caam/dpseci_cmd.h
-
---- a/crypto/Kconfig
-+++ b/crypto/Kconfig
-@@ -312,6 +312,26 @@ config CRYPTO_ECHAINIV
-         a sequence number xored with a salt.  This is the default
-         algorithm for CBC.
-+config CRYPTO_TLS
-+      tristate "TLS support"
-+      select CRYPTO_AEAD
-+      select CRYPTO_BLKCIPHER
-+      select CRYPTO_MANAGER
-+      select CRYPTO_HASH
-+      select CRYPTO_NULL
-+      select CRYPTO_AUTHENC
-+      help
-+        Support for TLS 1.0 record encryption and decryption
-+
-+        This module adds support for encryption/decryption of TLS 1.0 frames
-+        using blockcipher algorithms. The name of the resulting algorithm is
-+        "tls10(hmac(<digest>),cbc(<cipher>))". By default, the generic base
-+        algorithms are used (e.g. aes-generic, sha1-generic), but hardware
-+        accelerated versions will be used automatically if available.
-+
-+        User-space applications (OpenSSL, GnuTLS) can offload TLS 1.0
-+        operations through AF_ALG or cryptodev interfaces
-+
- comment "Block modes"
- config CRYPTO_CBC
---- a/crypto/Makefile
-+++ b/crypto/Makefile
-@@ -118,6 +118,7 @@ obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_ge
- obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o
- obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o
- obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
-+obj-$(CONFIG_CRYPTO_TLS) += tls.o
- obj-$(CONFIG_CRYPTO_LZO) += lzo.o
- obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
- obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o
---- a/crypto/chacha20poly1305.c
-+++ b/crypto/chacha20poly1305.c
-@@ -22,8 +22,6 @@
- #include "internal.h"
--#define CHACHAPOLY_IV_SIZE    12
--
- struct chachapoly_instance_ctx {
-       struct crypto_skcipher_spawn chacha;
-       struct crypto_ahash_spawn poly;
---- a/crypto/tcrypt.c
-+++ b/crypto/tcrypt.c
-@@ -76,7 +76,7 @@ static char *check[] = {
-       "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta",  "fcrypt",
-       "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
-       "lzo", "cts", "zlib", "sha3-224", "sha3-256", "sha3-384", "sha3-512",
--      NULL
-+      "rsa", NULL
- };
- struct tcrypt_result {
-@@ -355,11 +355,13 @@ static void test_aead_speed(const char *
-                                              iv);
-                       aead_request_set_ad(req, aad_size);
--                      if (secs)
-+                      if (secs) {
-                               ret = test_aead_jiffies(req, enc, *b_size,
-                                                       secs);
--                      else
-+                              cond_resched();
-+                      } else {
-                               ret = test_aead_cycles(req, enc, *b_size);
-+                      }
-                       if (ret) {
-                               pr_err("%s() failed return code=%d\n", e, ret);
-@@ -736,12 +738,14 @@ static void test_ahash_speed_common(cons
-               ahash_request_set_crypt(req, sg, output, speed[i].plen);
--              if (secs)
-+              if (secs) {
-                       ret = test_ahash_jiffies(req, speed[i].blen,
-                                                speed[i].plen, output, secs);
--              else
-+                      cond_resched();
-+              } else {
-                       ret = test_ahash_cycles(req, speed[i].blen,
-                                               speed[i].plen, output);
-+              }
-               if (ret) {
-                       pr_err("hashing failed ret=%d\n", ret);
-@@ -959,12 +963,14 @@ static void test_skcipher_speed(const ch
-                       skcipher_request_set_crypt(req, sg, sg, *b_size, iv);
--                      if (secs)
-+                      if (secs) {
-                               ret = test_acipher_jiffies(req, enc,
-                                                          *b_size, secs);
--                      else
-+                              cond_resched();
-+                      } else {
-                               ret = test_acipher_cycles(req, enc,
-                                                         *b_size);
-+                      }
-                       if (ret) {
-                               pr_err("%s() failed flags=%x\n", e,
-@@ -1336,6 +1342,10 @@ static int do_test(const char *alg, u32
-               ret += tcrypt_test("hmac(sha3-512)");
-               break;
-+      case 115:
-+              ret += tcrypt_test("rsa");
-+              break;
-+
-       case 150:
-               ret += tcrypt_test("ansi_cprng");
-               break;
-@@ -1397,6 +1407,9 @@ static int do_test(const char *alg, u32
-       case 190:
-               ret += tcrypt_test("authenc(hmac(sha512),cbc(des3_ede))");
-               break;
-+      case 191:
-+              ret += tcrypt_test("tls10(hmac(sha1),cbc(aes))");
-+              break;
-       case 200:
-               test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
-                               speed_template_16_24_32);
---- a/crypto/testmgr.c
-+++ b/crypto/testmgr.c
-@@ -117,6 +117,13 @@ struct drbg_test_suite {
-       unsigned int count;
- };
-+struct tls_test_suite {
-+      struct {
-+              struct tls_testvec *vecs;
-+              unsigned int count;
-+      } enc, dec;
-+};
-+
- struct akcipher_test_suite {
-       const struct akcipher_testvec *vecs;
-       unsigned int count;
-@@ -140,6 +147,7 @@ struct alg_test_desc {
-               struct hash_test_suite hash;
-               struct cprng_test_suite cprng;
-               struct drbg_test_suite drbg;
-+              struct tls_test_suite tls;
-               struct akcipher_test_suite akcipher;
-               struct kpp_test_suite kpp;
-       } suite;
-@@ -991,6 +999,233 @@ static int test_aead(struct crypto_aead
-       return 0;
- }
-+static int __test_tls(struct crypto_aead *tfm, int enc,
-+                    struct tls_testvec *template, unsigned int tcount,
-+                    const bool diff_dst)
-+{
-+      const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
-+      unsigned int i, k, authsize;
-+      char *q;
-+      struct aead_request *req;
-+      struct scatterlist *sg;
-+      struct scatterlist *sgout;
-+      const char *e, *d;
-+      struct tcrypt_result result;
-+      void *input;
-+      void *output;
-+      void *assoc;
-+      char *iv;
-+      char *key;
-+      char *xbuf[XBUFSIZE];
-+      char *xoutbuf[XBUFSIZE];
-+      char *axbuf[XBUFSIZE];
-+      int ret = -ENOMEM;
-+
-+      if (testmgr_alloc_buf(xbuf))
-+              goto out_noxbuf;
-+
-+      if (diff_dst && testmgr_alloc_buf(xoutbuf))
-+              goto out_nooutbuf;
-+
-+      if (testmgr_alloc_buf(axbuf))
-+              goto out_noaxbuf;
-+
-+      iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
-+      if (!iv)
-+              goto out_noiv;
-+
-+      key = kzalloc(MAX_KEYLEN, GFP_KERNEL);
-+      if (!key)
-+              goto out_nokey;
-+
-+      sg = kmalloc(sizeof(*sg) * 8 * (diff_dst ? 2 : 1), GFP_KERNEL);
-+      if (!sg)
-+              goto out_nosg;
-+
-+      sgout = sg + 8;
-+
-+      d = diff_dst ? "-ddst" : "";
-+      e = enc ? "encryption" : "decryption";
-+
-+      init_completion(&result.completion);
-+
-+      req = aead_request_alloc(tfm, GFP_KERNEL);
-+      if (!req) {
-+              pr_err("alg: tls%s: Failed to allocate request for %s\n",
-+                     d, algo);
-+              goto out;
-+      }
-+
-+      aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-+                                tcrypt_complete, &result);
-+
-+      for (i = 0; i < tcount; i++) {
-+              input = xbuf[0];
-+              assoc = axbuf[0];
-+
-+              ret = -EINVAL;
-+              if (WARN_ON(template[i].ilen > PAGE_SIZE ||
-+                          template[i].alen > PAGE_SIZE))
-+                      goto out;
-+
-+              memcpy(assoc, template[i].assoc, template[i].alen);
-+              memcpy(input, template[i].input, template[i].ilen);
-+
-+              if (template[i].iv)
-+                      memcpy(iv, template[i].iv, MAX_IVLEN);
-+              else
-+                      memset(iv, 0, MAX_IVLEN);
-+
-+              crypto_aead_clear_flags(tfm, ~0);
-+
-+              if (template[i].klen > MAX_KEYLEN) {
-+                      pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
-+                             d, i, algo, template[i].klen, MAX_KEYLEN);
-+                      ret = -EINVAL;
-+                      goto out;
-+              }
-+              memcpy(key, template[i].key, template[i].klen);
-+
-+              ret = crypto_aead_setkey(tfm, key, template[i].klen);
-+              if (!ret == template[i].fail) {
-+                      pr_err("alg: tls%s: setkey failed on test %d for %s: flags=%x\n",
-+                             d, i, algo, crypto_aead_get_flags(tfm));
-+                      goto out;
-+              } else if (ret)
-+                      continue;
-+
-+              authsize = 20;
-+              ret = crypto_aead_setauthsize(tfm, authsize);
-+              if (ret) {
-+                      pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n",
-+                             d, authsize, i, algo);
-+                      goto out;
-+              }
-+
-+              k = !!template[i].alen;
-+              sg_init_table(sg, k + 1);
-+              sg_set_buf(&sg[0], assoc, template[i].alen);
-+              sg_set_buf(&sg[k], input, (enc ? template[i].rlen :
-+                                         template[i].ilen));
-+              output = input;
-+
-+              if (diff_dst) {
-+                      sg_init_table(sgout, k + 1);
-+                      sg_set_buf(&sgout[0], assoc, template[i].alen);
-+
-+                      output = xoutbuf[0];
-+                      sg_set_buf(&sgout[k], output,
-+                                 (enc ? template[i].rlen : template[i].ilen));
-+              }
-+
-+              aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
-+                                     template[i].ilen, iv);
-+
-+              aead_request_set_ad(req, template[i].alen);
-+
-+              ret = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
-+
-+              switch (ret) {
-+              case 0:
-+                      if (template[i].novrfy) {
-+                              /* verification was supposed to fail */
-+                              pr_err("alg: tls%s: %s failed on test %d for %s: ret was 0, expected -EBADMSG\n",
-+                                     d, e, i, algo);
-+                              /* so really, we got a bad message */
-+                              ret = -EBADMSG;
-+                              goto out;
-+                      }
-+                      break;
-+              case -EINPROGRESS:
-+              case -EBUSY:
-+                      wait_for_completion(&result.completion);
-+                      reinit_completion(&result.completion);
-+                      ret = result.err;
-+                      if (!ret)
-+                              break;
-+              case -EBADMSG:
-+                      /* verification failure was expected */
-+                      if (template[i].novrfy)
-+                              continue;
-+                      /* fall through */
-+              default:
-+                      pr_err("alg: tls%s: %s failed on test %d for %s: ret=%d\n",
-+                             d, e, i, algo, -ret);
-+                      goto out;
-+              }
-+
-+              q = output;
-+              if (memcmp(q, template[i].result, template[i].rlen)) {
-+                      pr_err("alg: tls%s: Test %d failed on %s for %s\n",
-+                             d, i, e, algo);
-+                      hexdump(q, template[i].rlen);
-+                      pr_err("should be:\n");
-+                      hexdump(template[i].result, template[i].rlen);
-+                      ret = -EINVAL;
-+                      goto out;
-+              }
-+      }
-+
-+out:
-+      aead_request_free(req);
-+
-+      kfree(sg);
-+out_nosg:
-+      kfree(key);
-+out_nokey:
-+      kfree(iv);
-+out_noiv:
-+      testmgr_free_buf(axbuf);
-+out_noaxbuf:
-+      if (diff_dst)
-+              testmgr_free_buf(xoutbuf);
-+out_nooutbuf:
-+      testmgr_free_buf(xbuf);
-+out_noxbuf:
-+      return ret;
-+}
-+
-+static int test_tls(struct crypto_aead *tfm, int enc,
-+                  struct tls_testvec *template, unsigned int tcount)
-+{
-+      int ret;
-+      /* test 'dst == src' case */
-+      ret = __test_tls(tfm, enc, template, tcount, false);
-+      if (ret)
-+              return ret;
-+      /* test 'dst != src' case */
-+      return __test_tls(tfm, enc, template, tcount, true);
-+}
-+
-+static int alg_test_tls(const struct alg_test_desc *desc, const char *driver,
-+                      u32 type, u32 mask)
-+{
-+      struct crypto_aead *tfm;
-+      int err = 0;
-+
-+      tfm = crypto_alloc_aead(driver, type, mask);
-+      if (IS_ERR(tfm)) {
-+              pr_err("alg: aead: Failed to load transform for %s: %ld\n",
-+                     driver, PTR_ERR(tfm));
-+              return PTR_ERR(tfm);
-+      }
-+
-+      if (desc->suite.tls.enc.vecs) {
-+              err = test_tls(tfm, ENCRYPT, desc->suite.tls.enc.vecs,
-+                             desc->suite.tls.enc.count);
-+              if (err)
-+                      goto out;
-+      }
-+
-+      if (!err && desc->suite.tls.dec.vecs)
-+              err = test_tls(tfm, DECRYPT, desc->suite.tls.dec.vecs,
-+                             desc->suite.tls.dec.count);
-+
-+out:
-+      crypto_free_aead(tfm);
-+      return err;
-+}
-+
- static int test_cipher(struct crypto_cipher *tfm, int enc,
-                      const struct cipher_testvec *template,
-                      unsigned int tcount)
-@@ -3524,6 +3759,15 @@ static const struct alg_test_desc alg_te
-                       .hash = __VECS(tgr192_tv_template)
-               }
-       }, {
-+              .alg = "tls10(hmac(sha1),cbc(aes))",
-+              .test = alg_test_tls,
-+              .suite = {
-+                      .tls = {
-+                              .enc = __VECS(tls_enc_tv_template),
-+                              .dec = __VECS(tls_dec_tv_template)
-+                      }
-+              }
-+      }, {
-               .alg = "vmac(aes)",
-               .test = alg_test_hash,
-               .suite = {
---- a/crypto/testmgr.h
-+++ b/crypto/testmgr.h
-@@ -125,6 +125,20 @@ struct drbg_testvec {
-       size_t expectedlen;
- };
-+struct tls_testvec {
-+      char *key;      /* wrapped keys for encryption and authentication */
-+      char *iv;       /* initialization vector */
-+      char *input;    /* input data */
-+      char *assoc;    /* associated data: seq num, type, version, input len */
-+      char *result;   /* result data */
-+      unsigned char fail;     /* the test failure is expected */
-+      unsigned char novrfy;   /* dec verification failure expected */
-+      unsigned char klen;     /* key length */
-+      unsigned short ilen;    /* input data length */
-+      unsigned short alen;    /* associated data length */
-+      unsigned short rlen;    /* result length */
-+};
-+
- struct akcipher_testvec {
-       const unsigned char *key;
-       const unsigned char *m;
-@@ -153,6 +167,211 @@ struct kpp_testvec {
- static const char zeroed_string[48];
- /*
-+ * TLS1.0 synthetic test vectors
-+ */
-+static struct tls_testvec tls_enc_tv_template[] = {
-+      {
-+#ifdef __LITTLE_ENDIAN
-+              .key    = "\x08\x00"            /* rta length */
-+                      "\x01\x00"              /* rta type */
-+#else
-+              .key    = "\x00\x08"            /* rta length */
-+                      "\x00\x01"              /* rta type */
-+#endif
-+                      "\x00\x00\x00\x10"      /* enc key length */
-+                      "authenticationkey20benckeyis16_bytes",
-+              .klen   = 8 + 20 + 16,
-+              .iv     = "iv0123456789abcd",
-+              .input  = "Single block msg",
-+              .ilen   = 16,
-+              .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-+                      "\x00\x03\x01\x00\x10",
-+              .alen   = 13,
-+              .result = "\xd5\xac\xb\xd2\xac\xad\x3f\xb1"
-+                      "\x59\x79\x1e\x91\x5f\x52\x14\x9c"
-+                      "\xc0\x75\xd8\x4c\x97\x0f\x07\x73"
-+                      "\xdc\x89\x47\x49\x49\xcb\x30\x6b"
-+                      "\x1b\x45\x23\xa1\xd0\x51\xcf\x02"
-+                      "\x2e\xa8\x5d\xa0\xfe\xca\x82\x61",
-+              .rlen   = 16 + 20 + 12,
-+      }, {
-+#ifdef __LITTLE_ENDIAN
-+              .key    = "\x08\x00"            /* rta length */
-+                      "\x01\x00"              /* rta type */
-+#else
-+              .key    = "\x00\x08"            /* rta length */
-+                      "\x00\x01"              /* rta type */
-+#endif
-+                      "\x00\x00\x00\x10"      /* enc key length */
-+                      "authenticationkey20benckeyis16_bytes",
-+              .klen   = 8 + 20 + 16,
-+              .iv     = "iv0123456789abcd",
-+              .input  = "",
-+              .ilen   = 0,
-+              .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-+                      "\x00\x03\x01\x00\x00",
-+              .alen   = 13,
-+              .result = "\x58\x2a\x11\xc\x86\x8e\x4b\x67"
-+                      "\x2d\x16\x26\x1a\xac\x4b\xe2\x1a"
-+                      "\xe9\x6a\xcc\x4d\x6f\x79\x8a\x45"
-+                      "\x1f\x4e\x27\xf2\xa7\x59\xb4\x5a",
-+              .rlen   = 20 + 12,
-+      }, {
-+#ifdef __LITTLE_ENDIAN
-+              .key    = "\x08\x00"            /* rta length */
-+                      "\x01\x00"              /* rta type */
-+#else
-+              .key    = "\x00\x08"            /* rta length */
-+                      "\x00\x01"              /* rta type */
-+#endif
-+                      "\x00\x00\x00\x10"      /* enc key length */
-+                      "authenticationkey20benckeyis16_bytes",
-+              .klen   = 8 + 20 + 16,
-+              .iv     = "iv0123456789abcd",
-+              .input  = "285 bytes plaintext285 bytes plaintext285 bytes"
-+                      " plaintext285 bytes plaintext285 bytes plaintext285"
-+                      " bytes plaintext285 bytes plaintext285 bytes"
-+                      " plaintext285 bytes plaintext285 bytes plaintext285"
-+                      " bytes plaintext285 bytes plaintext285 bytes"
-+                      " plaintext285 bytes plaintext285 bytes plaintext285"
-+                      " bytes plaintext285 bytes plaintext",
-+              .ilen   = 285,
-+              .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-+                      "\x00\x03\x01\x01\x1d",
-+              .alen   = 13,
-+              .result = "\x80\x23\x82\x44\x14\x2a\x1d\x94\xc\xc2\x1d\xd"
-+                      "\x3a\x32\x89\x4c\x57\x30\xa8\x89\x76\x46\xcc\x90"
-+                      "\x1d\x88\xb8\xa6\x1a\x58\xe\x2d\xeb\x2c\xc7\x3a"
-+                      "\x52\x4e\xdb\xb3\x1e\x83\x11\xf5\x3c\xce\x6e\x94"
-+                      "\xd3\x26\x6a\x9a\xd\xbd\xc7\x98\xb9\xb3\x3a\x51"
-+                      "\x1e\x4\x84\x8a\x8f\x54\x9a\x51\x69\x9c\xce\x31"
-+                      "\x8d\x5d\x8b\xee\x5f\x70\xc\xc9\xb8\x50\x54\xf8"
-+                      "\xb2\x4a\x7a\xcd\xeb\x7a\x82\x81\xc6\x41\xc8\x50"
-+                      "\x91\x8d\xc8\xed\xcd\x40\x8f\x55\xd1\xec\xc9\xac"
-+                      "\x15\x18\xf9\x20\xa0\xed\x18\xa1\xe3\x56\xe3\x14"
-+                      "\xe5\xe8\x66\x63\x20\xed\xe4\x62\x9d\xa3\xa4\x1d"
-+                      "\x81\x89\x18\xf2\x36\xae\xc8\x8a\x2b\xbc\xc3\xb8"
-+                      "\x80\xf\x97\x21\x36\x39\x8\x84\x23\x18\x9e\x9c"
-+                      "\x72\x32\x75\x2d\x2e\xf9\x60\xb\xe8\xcc\xd9\x74"
-+                      "\x4\x1b\x8e\x99\xc1\x94\xee\xd0\xac\x4e\xfc\x7e"
-+                      "\xf1\x96\xb3\xe7\x14\xb8\xf2\xc\x25\x97\x82\x6b"
-+                      "\xbd\x0\x65\xab\x5c\xe3\x16\xfb\x68\xef\xea\x9d"
-+                      "\xff\x44\x1d\x2a\x44\xf5\xc8\x56\x77\xb7\xbf\x13"
-+                      "\xc8\x54\xdb\x92\xfe\x16\x4c\xbe\x18\xe9\xb\x8d"
-+                      "\xb\xd4\x43\x58\x43\xaa\xf4\x3\x80\x97\x62\xd5"
-+                      "\xdf\x3c\x28\xaa\xee\x48\x4b\x55\x41\x1b\x31\x2"
-+                      "\xbe\xa0\x1c\xbd\xb7\x22\x2a\xe5\x53\x72\x73\x20"
-+                      "\x44\x4f\xe6\x1\x2b\x34\x33\x11\x7d\xfb\x10\xc1"
-+                      "\x66\x7c\xa6\xf4\x48\x36\x5e\x2\xda\x41\x4b\x3e"
-+                      "\xe7\x80\x17\x17\xce\xf1\x3e\x6a\x8e\x26\xf3\xb7"
-+                      "\x2b\x85\xd\x31\x8d\xba\x6c\x22\xb4\x28\x55\x7e"
-+                      "\x2a\x9e\x26\xf1\x3d\x21\xac\x65",
-+              .rlen   = 285 + 20 + 15,
-+      }
-+};
-+
-+static struct tls_testvec tls_dec_tv_template[] = {
-+      {
-+#ifdef __LITTLE_ENDIAN
-+              .key    = "\x08\x00"            /* rta length */
-+                      "\x01\x00"              /* rta type */
-+#else
-+              .key    = "\x00\x08"            /* rta length */
-+                      "\x00\x01"              /* rta type */
-+#endif
-+                      "\x00\x00\x00\x10"      /* enc key length */
-+                      "authenticationkey20benckeyis16_bytes",
-+              .klen   = 8 + 20 + 16,
-+              .iv     = "iv0123456789abcd",
-+              .input  = "\xd5\xac\xb\xd2\xac\xad\x3f\xb1"
-+                      "\x59\x79\x1e\x91\x5f\x52\x14\x9c"
-+                      "\xc0\x75\xd8\x4c\x97\x0f\x07\x73"
-+                      "\xdc\x89\x47\x49\x49\xcb\x30\x6b"
-+                      "\x1b\x45\x23\xa1\xd0\x51\xcf\x02"
-+                      "\x2e\xa8\x5d\xa0\xfe\xca\x82\x61",
-+              .ilen   = 16 + 20 + 12,
-+              .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-+                      "\x00\x03\x01\x00\x30",
-+              .alen   = 13,
-+              .result = "Single block msg",
-+              .rlen   = 16,
-+      }, {
-+#ifdef __LITTLE_ENDIAN
-+              .key    = "\x08\x00"            /* rta length */
-+                      "\x01\x00"              /* rta type */
-+#else
-+              .key    = "\x00\x08"            /* rta length */
-+                      "\x00\x01"              /* rta type */
-+#endif
-+                      "\x00\x00\x00\x10"      /* enc key length */
-+                      "authenticationkey20benckeyis16_bytes",
-+              .klen   = 8 + 20 + 16,
-+              .iv     = "iv0123456789abcd",
-+              .input = "\x58\x2a\x11\xc\x86\x8e\x4b\x67"
-+                      "\x2d\x16\x26\x1a\xac\x4b\xe2\x1a"
-+                      "\xe9\x6a\xcc\x4d\x6f\x79\x8a\x45"
-+                      "\x1f\x4e\x27\xf2\xa7\x59\xb4\x5a",
-+              .ilen   = 20 + 12,
-+              .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-+                      "\x00\x03\x01\x00\x20",
-+              .alen   = 13,
-+              .result = "",
-+              .rlen   = 0,
-+      }, {
-+#ifdef __LITTLE_ENDIAN
-+              .key    = "\x08\x00"            /* rta length */
-+                      "\x01\x00"              /* rta type */
-+#else
-+              .key    = "\x00\x08"            /* rta length */
-+                      "\x00\x01"              /* rta type */
-+#endif
-+                      "\x00\x00\x00\x10"      /* enc key length */
-+                      "authenticationkey20benckeyis16_bytes",
-+              .klen   = 8 + 20 + 16,
-+              .iv     = "iv0123456789abcd",
-+              .input = "\x80\x23\x82\x44\x14\x2a\x1d\x94\xc\xc2\x1d\xd"
-+                      "\x3a\x32\x89\x4c\x57\x30\xa8\x89\x76\x46\xcc\x90"
-+                      "\x1d\x88\xb8\xa6\x1a\x58\xe\x2d\xeb\x2c\xc7\x3a"
-+                      "\x52\x4e\xdb\xb3\x1e\x83\x11\xf5\x3c\xce\x6e\x94"
-+                      "\xd3\x26\x6a\x9a\xd\xbd\xc7\x98\xb9\xb3\x3a\x51"
-+                      "\x1e\x4\x84\x8a\x8f\x54\x9a\x51\x69\x9c\xce\x31"
-+                      "\x8d\x5d\x8b\xee\x5f\x70\xc\xc9\xb8\x50\x54\xf8"
-+                      "\xb2\x4a\x7a\xcd\xeb\x7a\x82\x81\xc6\x41\xc8\x50"
-+                      "\x91\x8d\xc8\xed\xcd\x40\x8f\x55\xd1\xec\xc9\xac"
-+                      "\x15\x18\xf9\x20\xa0\xed\x18\xa1\xe3\x56\xe3\x14"
-+                      "\xe5\xe8\x66\x63\x20\xed\xe4\x62\x9d\xa3\xa4\x1d"
-+                      "\x81\x89\x18\xf2\x36\xae\xc8\x8a\x2b\xbc\xc3\xb8"
-+                      "\x80\xf\x97\x21\x36\x39\x8\x84\x23\x18\x9e\x9c"
-+                      "\x72\x32\x75\x2d\x2e\xf9\x60\xb\xe8\xcc\xd9\x74"
-+                      "\x4\x1b\x8e\x99\xc1\x94\xee\xd0\xac\x4e\xfc\x7e"
-+                      "\xf1\x96\xb3\xe7\x14\xb8\xf2\xc\x25\x97\x82\x6b"
-+                      "\xbd\x0\x65\xab\x5c\xe3\x16\xfb\x68\xef\xea\x9d"
-+                      "\xff\x44\x1d\x2a\x44\xf5\xc8\x56\x77\xb7\xbf\x13"
-+                      "\xc8\x54\xdb\x92\xfe\x16\x4c\xbe\x18\xe9\xb\x8d"
-+                      "\xb\xd4\x43\x58\x43\xaa\xf4\x3\x80\x97\x62\xd5"
-+                      "\xdf\x3c\x28\xaa\xee\x48\x4b\x55\x41\x1b\x31\x2"
-+                      "\xbe\xa0\x1c\xbd\xb7\x22\x2a\xe5\x53\x72\x73\x20"
-+                      "\x44\x4f\xe6\x1\x2b\x34\x33\x11\x7d\xfb\x10\xc1"
-+                      "\x66\x7c\xa6\xf4\x48\x36\x5e\x2\xda\x41\x4b\x3e"
-+                      "\xe7\x80\x17\x17\xce\xf1\x3e\x6a\x8e\x26\xf3\xb7"
-+                      "\x2b\x85\xd\x31\x8d\xba\x6c\x22\xb4\x28\x55\x7e"
-+                      "\x2a\x9e\x26\xf1\x3d\x21\xac\x65",
-+
-+              .ilen   = 285 + 20 + 15,
-+              .assoc  = "\x00\x01\x02\x03\x04\x05\x06\x07"
-+                      "\x00\x03\x01\x01\x40",
-+              .alen   = 13,
-+              .result = "285 bytes plaintext285 bytes plaintext285 bytes"
-+                      " plaintext285 bytes plaintext285 bytes plaintext285"
-+                      " bytes plaintext285 bytes plaintext285 bytes"
-+                      " plaintext285 bytes plaintext285 bytes plaintext285"
-+                      " bytes plaintext285 bytes plaintext285 bytes"
-+                      " plaintext285 bytes plaintext285 bytes plaintext",
-+              .rlen   = 285,
-+      }
-+};
-+
-+/*
-  * RSA test vectors. Borrowed from openSSL.
-  */
- static const struct akcipher_testvec rsa_tv_template[] = {
---- /dev/null
-+++ b/crypto/tls.c
-@@ -0,0 +1,607 @@
-+/*
-+ * Copyright 2013 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP Semiconductor, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the Free
-+ * Software Foundation; either version 2 of the License, or (at your option)
-+ * any later version.
-+ *
-+ */
-+
-+#include <crypto/internal/aead.h>
-+#include <crypto/internal/hash.h>
-+#include <crypto/internal/skcipher.h>
-+#include <crypto/authenc.h>
-+#include <crypto/null.h>
-+#include <crypto/scatterwalk.h>
-+#include <linux/err.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/rtnetlink.h>
-+
-+struct tls_instance_ctx {
-+      struct crypto_ahash_spawn auth;
-+      struct crypto_skcipher_spawn enc;
-+};
-+
-+struct crypto_tls_ctx {
-+      unsigned int reqoff;
-+      struct crypto_ahash *auth;
-+      struct crypto_skcipher *enc;
-+      struct crypto_skcipher *null;
-+};
-+
-+struct tls_request_ctx {
-+      /*
-+       * cryptlen holds the payload length in the case of encryption or
-+       * payload_len + icv_len + padding_len in case of decryption
-+       */
-+      unsigned int cryptlen;
-+      /* working space for partial results */
-+      struct scatterlist tmp[2];
-+      struct scatterlist cipher[2];
-+      struct scatterlist dst[2];
-+      char tail[];
-+};
-+
-+struct async_op {
-+      struct completion completion;
-+      int err;
-+};
-+
-+static void tls_async_op_done(struct crypto_async_request *req, int err)
-+{
-+      struct async_op *areq = req->data;
-+
-+      if (err == -EINPROGRESS)
-+              return;
-+
-+      areq->err = err;
-+      complete(&areq->completion);
-+}
-+
-+static int crypto_tls_setkey(struct crypto_aead *tls, const u8 *key,
-+                           unsigned int keylen)
-+{
-+      struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls);
-+      struct crypto_ahash *auth = ctx->auth;
-+      struct crypto_skcipher *enc = ctx->enc;
-+      struct crypto_authenc_keys keys;
-+      int err = -EINVAL;
-+
-+      if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
-+              goto badkey;
-+
-+      crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
-+      crypto_ahash_set_flags(auth, crypto_aead_get_flags(tls) &
-+                                  CRYPTO_TFM_REQ_MASK);
-+      err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen);
-+      crypto_aead_set_flags(tls, crypto_ahash_get_flags(auth) &
-+                                     CRYPTO_TFM_RES_MASK);
-+
-+      if (err)
-+              goto out;
-+
-+      crypto_skcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK);
-+      crypto_skcipher_set_flags(enc, crypto_aead_get_flags(tls) &
-+                                       CRYPTO_TFM_REQ_MASK);
-+      err = crypto_skcipher_setkey(enc, keys.enckey, keys.enckeylen);
-+      crypto_aead_set_flags(tls, crypto_skcipher_get_flags(enc) &
-+                                     CRYPTO_TFM_RES_MASK);
-+
-+out:
-+      return err;
-+
-+badkey:
-+      crypto_aead_set_flags(tls, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+      goto out;
-+}
-+
-+/**
-+ * crypto_tls_genicv - Calculate hmac digest for a TLS record
-+ * @hash:     (output) buffer to save the digest into
-+ * @src:      (input) scatterlist with the assoc and payload data
-+ * @srclen:   (input) size of the source buffer (assoclen + cryptlen)
-+ * @req:      (input) aead request
-+ **/
-+static int crypto_tls_genicv(u8 *hash, struct scatterlist *src,
-+                           unsigned int srclen, struct aead_request *req)
-+{
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls);
-+      struct tls_request_ctx *treq_ctx = aead_request_ctx(req);
-+      struct async_op ahash_op;
-+      struct ahash_request *ahreq = (void *)(treq_ctx->tail + ctx->reqoff);
-+      unsigned int flags = CRYPTO_TFM_REQ_MAY_SLEEP;
-+      int err = -EBADMSG;
-+
-+       /* Bail out if the request assoc len is 0 */
-+      if (!req->assoclen)
-+              return err;
-+
-+      init_completion(&ahash_op.completion);
-+
-+      /* the hash transform to be executed comes from the original request */
-+      ahash_request_set_tfm(ahreq, ctx->auth);
-+      /* prepare the hash request with input data and result pointer */
-+      ahash_request_set_crypt(ahreq, src, hash, srclen);
-+      /* set the notifier for when the async hash function returns */
-+      ahash_request_set_callback(ahreq, aead_request_flags(req) & flags,
-+                                 tls_async_op_done, &ahash_op);
-+
-+      /* Calculate the digest on the given data. The result is put in hash */
-+      err = crypto_ahash_digest(ahreq);
-+      if (err == -EINPROGRESS) {
-+              err = wait_for_completion_interruptible(&ahash_op.completion);
-+              if (!err)
-+                      err = ahash_op.err;
-+      }
-+
-+      return err;
-+}
-+
-+/**
-+ * crypto_tls_gen_padicv - Calculate and pad hmac digest for a TLS record
-+ * @hash:     (output) buffer to save the digest and padding into
-+ * @phashlen: (output) the size of digest + padding
-+ * @req:      (input) aead request
-+ **/
-+static int crypto_tls_gen_padicv(u8 *hash, unsigned int *phashlen,
-+                               struct aead_request *req)
-+{
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      unsigned int hash_size = crypto_aead_authsize(tls);
-+      unsigned int block_size = crypto_aead_blocksize(tls);
-+      unsigned int srclen = req->cryptlen + hash_size;
-+      unsigned int icvlen = req->cryptlen + req->assoclen;
-+      unsigned int padlen;
-+      int err;
-+
-+      err = crypto_tls_genicv(hash, req->src, icvlen, req);
-+      if (err)
-+              goto out;
-+
-+      /* add padding after digest */
-+      padlen = block_size - (srclen % block_size);
-+      memset(hash + hash_size, padlen - 1, padlen);
-+
-+      *phashlen = hash_size + padlen;
-+out:
-+      return err;
-+}
-+
-+static int crypto_tls_copy_data(struct aead_request *req,
-+                              struct scatterlist *src,
-+                              struct scatterlist *dst,
-+                              unsigned int len)
-+{
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls);
-+      SKCIPHER_REQUEST_ON_STACK(skreq, ctx->null);
-+
-+      skcipher_request_set_tfm(skreq, ctx->null);
-+      skcipher_request_set_callback(skreq, aead_request_flags(req),
-+                                    NULL, NULL);
-+      skcipher_request_set_crypt(skreq, src, dst, len, NULL);
-+
-+      return crypto_skcipher_encrypt(skreq);
-+}
-+
-+static int crypto_tls_encrypt(struct aead_request *req)
-+{
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls);
-+      struct tls_request_ctx *treq_ctx = aead_request_ctx(req);
-+      struct skcipher_request *skreq;
-+      struct scatterlist *cipher = treq_ctx->cipher;
-+      struct scatterlist *tmp = treq_ctx->tmp;
-+      struct scatterlist *sg, *src, *dst;
-+      unsigned int cryptlen, phashlen;
-+      u8 *hash = treq_ctx->tail;
-+      int err;
-+
-+      /*
-+       * The hash result is saved at the beginning of the tls request ctx
-+       * and is aligned as required by the hash transform. Enough space was
-+       * allocated in crypto_tls_init_tfm to accommodate the difference. The
-+       * requests themselves start later at treq_ctx->tail + ctx->reqoff so
-+       * the result is not overwritten by the second (cipher) request.
-+       */
-+      hash = (u8 *)ALIGN((unsigned long)hash +
-+                         crypto_ahash_alignmask(ctx->auth),
-+                         crypto_ahash_alignmask(ctx->auth) + 1);
-+
-+      /*
-+       * STEP 1: create ICV together with necessary padding
-+       */
-+      err = crypto_tls_gen_padicv(hash, &phashlen, req);
-+      if (err)
-+              return err;
-+
-+      /*
-+       * STEP 2: Hash and padding are combined with the payload
-+       * depending on the form it arrives. Scatter tables must have at least
-+       * one page of data before chaining with another table and can't have
-+       * an empty data page. The following code addresses these requirements.
-+       *
-+       * If the payload is empty, only the hash is encrypted, otherwise the
-+       * payload scatterlist is merged with the hash. A special merging case
-+       * is when the payload has only one page of data. In that case the
-+       * payload page is moved to another scatterlist and prepared there for
-+       * encryption.
-+       */
-+      if (req->cryptlen) {
-+              src = scatterwalk_ffwd(tmp, req->src, req->assoclen);
-+
-+              sg_init_table(cipher, 2);
-+              sg_set_buf(cipher + 1, hash, phashlen);
-+
-+              if (sg_is_last(src)) {
-+                      sg_set_page(cipher, sg_page(src), req->cryptlen,
-+                                  src->offset);
-+                      src = cipher;
-+              } else {
-+                      unsigned int rem_len = req->cryptlen;
-+
-+                      for (sg = src; rem_len > sg->length; sg = sg_next(sg))
-+                              rem_len -= min(rem_len, sg->length);
-+
-+                      sg_set_page(cipher, sg_page(sg), rem_len, sg->offset);
-+                      sg_chain(sg, 1, cipher);
-+              }
-+      } else {
-+              sg_init_one(cipher, hash, phashlen);
-+              src = cipher;
-+      }
-+
-+      /**
-+       * If src != dst copy the associated data from source to destination.
-+       * In both cases fast-forward passed the associated data in the dest.
-+       */
-+      if (req->src != req->dst) {
-+              err = crypto_tls_copy_data(req, req->src, req->dst,
-+                                         req->assoclen);
-+              if (err)
-+                      return err;
-+      }
-+      dst = scatterwalk_ffwd(treq_ctx->dst, req->dst, req->assoclen);
-+
-+      /*
-+       * STEP 3: encrypt the frame and return the result
-+       */
-+      cryptlen = req->cryptlen + phashlen;
-+
-+      /*
-+       * The hash and the cipher are applied at different times and their
-+       * requests can use the same memory space without interference
-+       */
-+      skreq = (void *)(treq_ctx->tail + ctx->reqoff);
-+      skcipher_request_set_tfm(skreq, ctx->enc);
-+      skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
-+      skcipher_request_set_callback(skreq, aead_request_flags(req),
-+                                    req->base.complete, req->base.data);
-+      /*
-+       * Apply the cipher transform. The result will be in req->dst when the
-+       * asynchronuous call terminates
-+       */
-+      err = crypto_skcipher_encrypt(skreq);
-+
-+      return err;
-+}
-+
-+static int crypto_tls_decrypt(struct aead_request *req)
-+{
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls);
-+      struct tls_request_ctx *treq_ctx = aead_request_ctx(req);
-+      unsigned int cryptlen = req->cryptlen;
-+      unsigned int hash_size = crypto_aead_authsize(tls);
-+      unsigned int block_size = crypto_aead_blocksize(tls);
-+      struct skcipher_request *skreq = (void *)(treq_ctx->tail + ctx->reqoff);
-+      struct scatterlist *tmp = treq_ctx->tmp;
-+      struct scatterlist *src, *dst;
-+
-+      u8 padding[255]; /* padding can be 0-255 bytes */
-+      u8 pad_size;
-+      u16 *len_field;
-+      u8 *ihash, *hash = treq_ctx->tail;
-+
-+      int paderr = 0;
-+      int err = -EINVAL;
-+      int i;
-+      struct async_op ciph_op;
-+
-+      /*
-+       * Rule out bad packets. The input packet length must be at least one
-+       * byte more than the hash_size
-+       */
-+      if (cryptlen <= hash_size || cryptlen % block_size)
-+              goto out;
-+
-+      /*
-+       * Step 1 - Decrypt the source. Fast-forward past the associated data
-+       * to the encrypted data. The result will be overwritten in place so
-+       * that the decrypted data will be adjacent to the associated data. The
-+       * last step (computing the hash) will have it's input data already
-+       * prepared and ready to be accessed at req->src.
-+       */
-+      src = scatterwalk_ffwd(tmp, req->src, req->assoclen);
-+      dst = src;
-+
-+      init_completion(&ciph_op.completion);
-+      skcipher_request_set_tfm(skreq, ctx->enc);
-+      skcipher_request_set_callback(skreq, aead_request_flags(req),
-+                                    tls_async_op_done, &ciph_op);
-+      skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv);
-+      err = crypto_skcipher_decrypt(skreq);
-+      if (err == -EINPROGRESS) {
-+              err = wait_for_completion_interruptible(&ciph_op.completion);
-+              if (!err)
-+                      err = ciph_op.err;
-+      }
-+      if (err)
-+              goto out;
-+
-+      /*
-+       * Step 2 - Verify padding
-+       * Retrieve the last byte of the payload; this is the padding size.
-+       */
-+      cryptlen -= 1;
-+      scatterwalk_map_and_copy(&pad_size, dst, cryptlen, 1, 0);
-+
-+      /* RFC recommendation for invalid padding size. */
-+      if (cryptlen < pad_size + hash_size) {
-+              pad_size = 0;
-+              paderr = -EBADMSG;
-+      }
-+      cryptlen -= pad_size;
-+      scatterwalk_map_and_copy(padding, dst, cryptlen, pad_size, 0);
-+
-+      /* Padding content must be equal with pad_size. We verify it all */
-+      for (i = 0; i < pad_size; i++)
-+              if (padding[i] != pad_size)
-+                      paderr = -EBADMSG;
-+
-+      /*
-+       * Step 3 - Verify hash
-+       * Align the digest result as required by the hash transform. Enough
-+       * space was allocated in crypto_tls_init_tfm
-+       */
-+      hash = (u8 *)ALIGN((unsigned long)hash +
-+                         crypto_ahash_alignmask(ctx->auth),
-+                         crypto_ahash_alignmask(ctx->auth) + 1);
-+      /*
-+       * Two bytes at the end of the associated data make the length field.
-+       * It must be updated with the length of the cleartext message before
-+       * the hash is calculated.
-+       */
-+      len_field = sg_virt(req->src) + req->assoclen - 2;
-+      cryptlen -= hash_size;
-+      *len_field = htons(cryptlen);
-+
-+      /* This is the hash from the decrypted packet. Save it for later */
-+      ihash = hash + hash_size;
-+      scatterwalk_map_and_copy(ihash, dst, cryptlen, hash_size, 0);
-+
-+      /* Now compute and compare our ICV with the one from the packet */
-+      err = crypto_tls_genicv(hash, req->src, cryptlen + req->assoclen, req);
-+      if (!err)
-+              err = memcmp(hash, ihash, hash_size) ? -EBADMSG : 0;
-+
-+      if (req->src != req->dst) {
-+              err = crypto_tls_copy_data(req, req->src, req->dst, cryptlen +
-+                                         req->assoclen);
-+              if (err)
-+                      goto out;
-+      }
-+
-+      /* return the first found error */
-+      if (paderr)
-+              err = paderr;
-+
-+out:
-+      aead_request_complete(req, err);
-+      return err;
-+}
-+
-+static int crypto_tls_init_tfm(struct crypto_aead *tfm)
-+{
-+      struct aead_instance *inst = aead_alg_instance(tfm);
-+      struct tls_instance_ctx *ictx = aead_instance_ctx(inst);
-+      struct crypto_tls_ctx *ctx = crypto_aead_ctx(tfm);
-+      struct crypto_ahash *auth;
-+      struct crypto_skcipher *enc;
-+      struct crypto_skcipher *null;
-+      int err;
-+
-+      auth = crypto_spawn_ahash(&ictx->auth);
-+      if (IS_ERR(auth))
-+              return PTR_ERR(auth);
-+
-+      enc = crypto_spawn_skcipher(&ictx->enc);
-+      err = PTR_ERR(enc);
-+      if (IS_ERR(enc))
-+              goto err_free_ahash;
-+
-+      null = crypto_get_default_null_skcipher2();
-+      err = PTR_ERR(null);
-+      if (IS_ERR(null))
-+              goto err_free_skcipher;
-+
-+      ctx->auth = auth;
-+      ctx->enc = enc;
-+      ctx->null = null;
-+
-+      /*
-+       * Allow enough space for two digests. The two digests will be compared
-+       * during the decryption phase. One will come from the decrypted packet
-+       * and the other will be calculated. For encryption, one digest is
-+       * padded (up to a cipher blocksize) and chained with the payload
-+       */
-+      ctx->reqoff = ALIGN(crypto_ahash_digestsize(auth) +
-+                          crypto_ahash_alignmask(auth),
-+                          crypto_ahash_alignmask(auth) + 1) +
-+                          max(crypto_ahash_digestsize(auth),
-+                              crypto_skcipher_blocksize(enc));
-+
-+      crypto_aead_set_reqsize(tfm,
-+                              sizeof(struct tls_request_ctx) +
-+                              ctx->reqoff +
-+                              max_t(unsigned int,
-+                                    crypto_ahash_reqsize(auth) +
-+                                    sizeof(struct ahash_request),
-+                                    crypto_skcipher_reqsize(enc) +
-+                                    sizeof(struct skcipher_request)));
-+
-+      return 0;
-+
-+err_free_skcipher:
-+      crypto_free_skcipher(enc);
-+err_free_ahash:
-+      crypto_free_ahash(auth);
-+      return err;
-+}
-+
-+static void crypto_tls_exit_tfm(struct crypto_aead *tfm)
-+{
-+      struct crypto_tls_ctx *ctx = crypto_aead_ctx(tfm);
-+
-+      crypto_free_ahash(ctx->auth);
-+      crypto_free_skcipher(ctx->enc);
-+      crypto_put_default_null_skcipher2();
-+}
-+
-+static void crypto_tls_free(struct aead_instance *inst)
-+{
-+      struct tls_instance_ctx *ctx = aead_instance_ctx(inst);
-+
-+      crypto_drop_skcipher(&ctx->enc);
-+      crypto_drop_ahash(&ctx->auth);
-+      kfree(inst);
-+}
-+
-+static int crypto_tls_create(struct crypto_template *tmpl, struct rtattr **tb)
-+{
-+      struct crypto_attr_type *algt;
-+      struct aead_instance *inst;
-+      struct hash_alg_common *auth;
-+      struct crypto_alg *auth_base;
-+      struct skcipher_alg *enc;
-+      struct tls_instance_ctx *ctx;
-+      const char *enc_name;
-+      int err;
-+
-+      algt = crypto_get_attr_type(tb);
-+      if (IS_ERR(algt))
-+              return PTR_ERR(algt);
-+
-+      if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
-+              return -EINVAL;
-+
-+      auth = ahash_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH,
-+                            CRYPTO_ALG_TYPE_AHASH_MASK |
-+                            crypto_requires_sync(algt->type, algt->mask));
-+      if (IS_ERR(auth))
-+              return PTR_ERR(auth);
-+
-+      auth_base = &auth->base;
-+
-+      enc_name = crypto_attr_alg_name(tb[2]);
-+      err = PTR_ERR(enc_name);
-+      if (IS_ERR(enc_name))
-+              goto out_put_auth;
-+
-+      inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
-+      err = -ENOMEM;
-+      if (!inst)
-+              goto out_put_auth;
-+
-+      ctx = aead_instance_ctx(inst);
-+
-+      err = crypto_init_ahash_spawn(&ctx->auth, auth,
-+                                    aead_crypto_instance(inst));
-+      if (err)
-+              goto err_free_inst;
-+
-+      crypto_set_skcipher_spawn(&ctx->enc, aead_crypto_instance(inst));
-+      err = crypto_grab_skcipher(&ctx->enc, enc_name, 0,
-+                                 crypto_requires_sync(algt->type,
-+                                                      algt->mask));
-+      if (err)
-+              goto err_drop_auth;
-+
-+      enc = crypto_spawn_skcipher_alg(&ctx->enc);
-+
-+      err = -ENAMETOOLONG;
-+      if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
-+                   "tls10(%s,%s)", auth_base->cra_name,
-+                   enc->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
-+              goto err_drop_enc;
-+
-+      if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
-+                   "tls10(%s,%s)", auth_base->cra_driver_name,
-+                   enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
-+              goto err_drop_enc;
-+
-+      inst->alg.base.cra_flags = (auth_base->cra_flags |
-+                                      enc->base.cra_flags) & CRYPTO_ALG_ASYNC;
-+      inst->alg.base.cra_priority = enc->base.cra_priority * 10 +
-+                                      auth_base->cra_priority;
-+      inst->alg.base.cra_blocksize = enc->base.cra_blocksize;
-+      inst->alg.base.cra_alignmask = auth_base->cra_alignmask |
-+                                      enc->base.cra_alignmask;
-+      inst->alg.base.cra_ctxsize = sizeof(struct crypto_tls_ctx);
-+
-+      inst->alg.ivsize = crypto_skcipher_alg_ivsize(enc);
-+      inst->alg.chunksize = crypto_skcipher_alg_chunksize(enc);
-+      inst->alg.maxauthsize = auth->digestsize;
-+
-+      inst->alg.init = crypto_tls_init_tfm;
-+      inst->alg.exit = crypto_tls_exit_tfm;
-+
-+      inst->alg.setkey = crypto_tls_setkey;
-+      inst->alg.encrypt = crypto_tls_encrypt;
-+      inst->alg.decrypt = crypto_tls_decrypt;
-+
-+      inst->free = crypto_tls_free;
-+
-+      err = aead_register_instance(tmpl, inst);
-+      if (err)
-+              goto err_drop_enc;
-+
-+out:
-+      crypto_mod_put(auth_base);
-+      return err;
-+
-+err_drop_enc:
-+      crypto_drop_skcipher(&ctx->enc);
-+err_drop_auth:
-+      crypto_drop_ahash(&ctx->auth);
-+err_free_inst:
-+      kfree(inst);
-+out_put_auth:
-+      goto out;
-+}
-+
-+static struct crypto_template crypto_tls_tmpl = {
-+      .name = "tls10",
-+      .create = crypto_tls_create,
-+      .module = THIS_MODULE,
-+};
-+
-+static int __init crypto_tls_module_init(void)
-+{
-+      return crypto_register_template(&crypto_tls_tmpl);
-+}
-+
-+static void __exit crypto_tls_module_exit(void)
-+{
-+      crypto_unregister_template(&crypto_tls_tmpl);
-+}
-+
-+module_init(crypto_tls_module_init);
-+module_exit(crypto_tls_module_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("TLS 1.0 record encryption");
---- a/drivers/crypto/Makefile
-+++ b/drivers/crypto/Makefile
-@@ -10,7 +10,7 @@ obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chel
- obj-$(CONFIG_CRYPTO_DEV_CPT) += cavium/cpt/
- obj-$(CONFIG_CRYPTO_DEV_NITROX) += cavium/nitrox/
- obj-$(CONFIG_CRYPTO_DEV_EXYNOS_RNG) += exynos-rng.o
--obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam/
-+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON) += caam/
- obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
- obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
- obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += img-hash.o
---- a/drivers/crypto/caam/Kconfig
-+++ b/drivers/crypto/caam/Kconfig
-@@ -1,7 +1,17 @@
-+config CRYPTO_DEV_FSL_CAAM_COMMON
-+      tristate
-+
-+config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
-+      tristate
-+
-+config CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC
-+      tristate
-+
- config CRYPTO_DEV_FSL_CAAM
--      tristate "Freescale CAAM-Multicore driver backend"
-+      tristate "Freescale CAAM-Multicore platform driver backend"
-       depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE
-       select SOC_BUS
-+      select CRYPTO_DEV_FSL_CAAM_COMMON
-       help
-         Enables the driver module for Freescale's Cryptographic Accelerator
-         and Assurance Module (CAAM), also known as the SEC version 4 (SEC4).
-@@ -12,9 +22,16 @@ config CRYPTO_DEV_FSL_CAAM
-         To compile this driver as a module, choose M here: the module
-         will be called caam.
-+if CRYPTO_DEV_FSL_CAAM
-+
-+config CRYPTO_DEV_FSL_CAAM_DEBUG
-+      bool "Enable debug output in CAAM driver"
-+      help
-+        Selecting this will enable printing of various debug
-+        information in the CAAM driver.
-+
- config CRYPTO_DEV_FSL_CAAM_JR
-       tristate "Freescale CAAM Job Ring driver backend"
--      depends on CRYPTO_DEV_FSL_CAAM
-       default y
-       help
-         Enables the driver module for Job Rings which are part of
-@@ -25,9 +42,10 @@ config CRYPTO_DEV_FSL_CAAM_JR
-         To compile this driver as a module, choose M here: the module
-         will be called caam_jr.
-+if CRYPTO_DEV_FSL_CAAM_JR
-+
- config CRYPTO_DEV_FSL_CAAM_RINGSIZE
-       int "Job Ring size"
--      depends on CRYPTO_DEV_FSL_CAAM_JR
-       range 2 9
-       default "9"
-       help
-@@ -45,7 +63,6 @@ config CRYPTO_DEV_FSL_CAAM_RINGSIZE
- config CRYPTO_DEV_FSL_CAAM_INTC
-       bool "Job Ring interrupt coalescing"
--      depends on CRYPTO_DEV_FSL_CAAM_JR
-       help
-         Enable the Job Ring's interrupt coalescing feature.
-@@ -74,9 +91,9 @@ config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THL
-         threshold. Range is 1-65535.
- config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
--      tristate "Register algorithm implementations with the Crypto API"
--      depends on CRYPTO_DEV_FSL_CAAM_JR
-+      bool "Register algorithm implementations with the Crypto API"
-       default y
-+      select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
-       select CRYPTO_AEAD
-       select CRYPTO_AUTHENC
-       select CRYPTO_BLKCIPHER
-@@ -85,13 +102,11 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
-         scatterlist crypto API (such as the linux native IPSec
-         stack) to the SEC4 via job ring.
--        To compile this as a module, choose M here: the module
--        will be called caamalg.
--
- config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI
--      tristate "Queue Interface as Crypto API backend"
--      depends on CRYPTO_DEV_FSL_CAAM_JR && FSL_DPAA && NET
-+      bool "Queue Interface as Crypto API backend"
-+      depends on FSL_SDK_DPA && NET
-       default y
-+      select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
-       select CRYPTO_AUTHENC
-       select CRYPTO_BLKCIPHER
-       help
-@@ -102,36 +117,26 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI
-         assigned to the kernel should also be more than the number of
-         job rings.
--        To compile this as a module, choose M here: the module
--        will be called caamalg_qi.
--
- config CRYPTO_DEV_FSL_CAAM_AHASH_API
--      tristate "Register hash algorithm implementations with Crypto API"
--      depends on CRYPTO_DEV_FSL_CAAM_JR
-+      bool "Register hash algorithm implementations with Crypto API"
-       default y
-+      select CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC
-       select CRYPTO_HASH
-       help
-         Selecting this will offload ahash for users of the
-         scatterlist crypto API to the SEC4 via job ring.
--        To compile this as a module, choose M here: the module
--        will be called caamhash.
--
- config CRYPTO_DEV_FSL_CAAM_PKC_API
--        tristate "Register public key cryptography implementations with Crypto API"
--        depends on CRYPTO_DEV_FSL_CAAM_JR
-+        bool "Register public key cryptography implementations with Crypto API"
-         default y
-         select CRYPTO_RSA
-         help
-           Selecting this will allow SEC Public key support for RSA.
-           Supported cryptographic primitives: encryption, decryption,
-           signature and verification.
--          To compile this as a module, choose M here: the module
--          will be called caam_pkc.
- config CRYPTO_DEV_FSL_CAAM_RNG_API
--      tristate "Register caam device for hwrng API"
--      depends on CRYPTO_DEV_FSL_CAAM_JR
-+      bool "Register caam device for hwrng API"
-       default y
-       select CRYPTO_RNG
-       select HW_RANDOM
-@@ -139,16 +144,24 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API
-         Selecting this will register the SEC4 hardware rng to
-         the hw_random API for suppying the kernel entropy pool.
--        To compile this as a module, choose M here: the module
--        will be called caamrng.
-+endif # CRYPTO_DEV_FSL_CAAM_JR
--config CRYPTO_DEV_FSL_CAAM_DEBUG
--      bool "Enable debug output in CAAM driver"
--      depends on CRYPTO_DEV_FSL_CAAM
--      help
--        Selecting this will enable printing of various debug
--        information in the CAAM driver.
-+endif # CRYPTO_DEV_FSL_CAAM
--config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
--      def_tristate (CRYPTO_DEV_FSL_CAAM_CRYPTO_API || \
--                    CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI)
-+config CRYPTO_DEV_FSL_DPAA2_CAAM
-+      tristate "QorIQ DPAA2 CAAM (DPSECI) driver"
-+      depends on FSL_MC_DPIO
-+      select CRYPTO_DEV_FSL_CAAM_COMMON
-+      select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
-+      select CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC
-+      select CRYPTO_BLKCIPHER
-+      select CRYPTO_AUTHENC
-+      select CRYPTO_AEAD
-+      select CRYPTO_HASH
-+      ---help---
-+        CAAM driver for QorIQ Data Path Acceleration Architecture 2.
-+        It handles DPSECI DPAA2 objects that sit on the Management Complex
-+        (MC) fsl-mc bus.
-+
-+        To compile this as a module, choose M here: the module
-+        will be called dpaa2_caam.
---- a/drivers/crypto/caam/Makefile
-+++ b/drivers/crypto/caam/Makefile
-@@ -6,19 +6,27 @@ ifeq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG
-       ccflags-y := -DDEBUG
- endif
-+ccflags-y += -DVERSION=\"\"
-+
-+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON) += error.o
- obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
- obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
--obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
--obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o
- obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o
--obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
--obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
--obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caam_pkc.o
--
--caam-objs := ctrl.o
--caam_jr-objs := jr.o key_gen.o error.o
--caam_pkc-y := caampkc.o pkc_desc.o
-+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o
-+
-+caam-y := ctrl.o
-+caam_jr-y := jr.o key_gen.o
-+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
-+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o
-+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
-+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
-+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o
-+
-+caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o
- ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),)
-       ccflags-y += -DCONFIG_CAAM_QI
--      caam-objs += qi.o
- endif
-+
-+obj-$(CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM) += dpaa2_caam.o
-+
-+dpaa2_caam-y    := caamalg_qi2.o dpseci.o
---- a/drivers/crypto/caam/caamalg.c
-+++ b/drivers/crypto/caam/caamalg.c
-@@ -71,6 +71,8 @@
- #define AUTHENC_DESC_JOB_IO_LEN               (AEAD_DESC_JOB_IO_LEN + \
-                                        CAAM_CMD_SZ * 5)
-+#define CHACHAPOLY_DESC_JOB_IO_LEN    (AEAD_DESC_JOB_IO_LEN + CAAM_CMD_SZ * 6)
-+
- #define DESC_MAX_USED_BYTES           (CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN)
- #define DESC_MAX_USED_LEN             (DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
-@@ -108,6 +110,7 @@ struct caam_ctx {
-       dma_addr_t sh_desc_dec_dma;
-       dma_addr_t sh_desc_givenc_dma;
-       dma_addr_t key_dma;
-+      enum dma_data_direction dir;
-       struct device *jrdev;
-       struct alginfo adata;
-       struct alginfo cdata;
-@@ -118,6 +121,7 @@ static int aead_null_set_sh_desc(struct
- {
-       struct caam_ctx *ctx = crypto_aead_ctx(aead);
-       struct device *jrdev = ctx->jrdev;
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
-       u32 *desc;
-       int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
-                       ctx->adata.keylen_pad;
-@@ -136,9 +140,10 @@ static int aead_null_set_sh_desc(struct
-       /* aead_encrypt shared descriptor */
-       desc = ctx->sh_desc_enc;
--      cnstr_shdsc_aead_null_encap(desc, &ctx->adata, ctx->authsize);
-+      cnstr_shdsc_aead_null_encap(desc, &ctx->adata, ctx->authsize,
-+                                  ctrlpriv->era);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       /*
-        * Job Descriptor and Shared Descriptors
-@@ -154,9 +159,10 @@ static int aead_null_set_sh_desc(struct
-       /* aead_decrypt shared descriptor */
-       desc = ctx->sh_desc_dec;
--      cnstr_shdsc_aead_null_decap(desc, &ctx->adata, ctx->authsize);
-+      cnstr_shdsc_aead_null_decap(desc, &ctx->adata, ctx->authsize,
-+                                  ctrlpriv->era);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       return 0;
- }
-@@ -168,6 +174,7 @@ static int aead_set_sh_desc(struct crypt
-       unsigned int ivsize = crypto_aead_ivsize(aead);
-       struct caam_ctx *ctx = crypto_aead_ctx(aead);
-       struct device *jrdev = ctx->jrdev;
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
-       u32 ctx1_iv_off = 0;
-       u32 *desc, *nonce = NULL;
-       u32 inl_mask;
-@@ -234,9 +241,9 @@ static int aead_set_sh_desc(struct crypt
-       desc = ctx->sh_desc_enc;
-       cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize,
-                              ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
--                             false);
-+                             false, ctrlpriv->era);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
- skip_enc:
-       /*
-@@ -266,9 +273,9 @@ skip_enc:
-       desc = ctx->sh_desc_dec;
-       cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
-                              ctx->authsize, alg->caam.geniv, is_rfc3686,
--                             nonce, ctx1_iv_off, false);
-+                             nonce, ctx1_iv_off, false, ctrlpriv->era);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       if (!alg->caam.geniv)
-               goto skip_givenc;
-@@ -300,9 +307,9 @@ skip_enc:
-       desc = ctx->sh_desc_enc;
-       cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
-                                 ctx->authsize, is_rfc3686, nonce,
--                                ctx1_iv_off, false);
-+                                ctx1_iv_off, false, ctrlpriv->era);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
- skip_givenc:
-       return 0;
-@@ -323,6 +330,7 @@ static int gcm_set_sh_desc(struct crypto
- {
-       struct caam_ctx *ctx = crypto_aead_ctx(aead);
-       struct device *jrdev = ctx->jrdev;
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-       u32 *desc;
-       int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
-                       ctx->cdata.keylen;
-@@ -344,9 +352,9 @@ static int gcm_set_sh_desc(struct crypto
-       }
-       desc = ctx->sh_desc_enc;
--      cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ctx->authsize);
-+      cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       /*
-        * Job Descriptor and Shared Descriptors
-@@ -361,9 +369,9 @@ static int gcm_set_sh_desc(struct crypto
-       }
-       desc = ctx->sh_desc_dec;
--      cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ctx->authsize);
-+      cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       return 0;
- }
-@@ -382,6 +390,7 @@ static int rfc4106_set_sh_desc(struct cr
- {
-       struct caam_ctx *ctx = crypto_aead_ctx(aead);
-       struct device *jrdev = ctx->jrdev;
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-       u32 *desc;
-       int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
-                       ctx->cdata.keylen;
-@@ -403,9 +412,10 @@ static int rfc4106_set_sh_desc(struct cr
-       }
-       desc = ctx->sh_desc_enc;
--      cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ctx->authsize);
-+      cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
-+                                false);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       /*
-        * Job Descriptor and Shared Descriptors
-@@ -420,9 +430,10 @@ static int rfc4106_set_sh_desc(struct cr
-       }
-       desc = ctx->sh_desc_dec;
--      cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ctx->authsize);
-+      cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
-+                                false);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       return 0;
- }
-@@ -442,6 +453,7 @@ static int rfc4543_set_sh_desc(struct cr
- {
-       struct caam_ctx *ctx = crypto_aead_ctx(aead);
-       struct device *jrdev = ctx->jrdev;
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-       u32 *desc;
-       int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
-                       ctx->cdata.keylen;
-@@ -463,9 +475,10 @@ static int rfc4543_set_sh_desc(struct cr
-       }
-       desc = ctx->sh_desc_enc;
--      cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ctx->authsize);
-+      cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
-+                                false);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       /*
-        * Job Descriptor and Shared Descriptors
-@@ -480,9 +493,10 @@ static int rfc4543_set_sh_desc(struct cr
-       }
-       desc = ctx->sh_desc_dec;
--      cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ctx->authsize);
-+      cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
-+                                false);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       return 0;
- }
-@@ -498,11 +512,67 @@ static int rfc4543_setauthsize(struct cr
-       return 0;
- }
-+static int chachapoly_set_sh_desc(struct crypto_aead *aead)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *jrdev = ctx->jrdev;
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      u32 *desc;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      desc = ctx->sh_desc_enc;
-+      cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
-+                             ctx->authsize, true, false);
-+      dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
-+                                 desc_bytes(desc), ctx->dir);
-+
-+      desc = ctx->sh_desc_dec;
-+      cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
-+                             ctx->authsize, false, false);
-+      dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
-+                                 desc_bytes(desc), ctx->dir);
-+
-+      return 0;
-+}
-+
-+static int chachapoly_setauthsize(struct crypto_aead *aead,
-+                                unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+
-+      if (authsize != POLY1305_DIGEST_SIZE)
-+              return -EINVAL;
-+
-+      ctx->authsize = authsize;
-+      return chachapoly_set_sh_desc(aead);
-+}
-+
-+static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
-+                           unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
-+
-+      if (keylen != CHACHA20_KEY_SIZE + saltlen) {
-+              crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+              return -EINVAL;
-+      }
-+
-+      ctx->cdata.key_virt = key;
-+      ctx->cdata.keylen = keylen - saltlen;
-+
-+      return chachapoly_set_sh_desc(aead);
-+}
-+
- static int aead_setkey(struct crypto_aead *aead,
-                              const u8 *key, unsigned int keylen)
- {
-       struct caam_ctx *ctx = crypto_aead_ctx(aead);
-       struct device *jrdev = ctx->jrdev;
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
-       struct crypto_authenc_keys keys;
-       int ret = 0;
-@@ -517,6 +587,27 @@ static int aead_setkey(struct crypto_aea
-                      DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
- #endif
-+      /*
-+       * If DKP is supported, use it in the shared descriptor to generate
-+       * the split key.
-+       */
-+      if (ctrlpriv->era >= 6) {
-+              ctx->adata.keylen = keys.authkeylen;
-+              ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
-+                                                    OP_ALG_ALGSEL_MASK);
-+
-+              if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
-+                      goto badkey;
-+
-+              memcpy(ctx->key, keys.authkey, keys.authkeylen);
-+              memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
-+                     keys.enckeylen);
-+              dma_sync_single_for_device(jrdev, ctx->key_dma,
-+                                         ctx->adata.keylen_pad +
-+                                         keys.enckeylen, ctx->dir);
-+              goto skip_split_key;
-+      }
-+
-       ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, keys.authkey,
-                           keys.authkeylen, CAAM_MAX_KEY_SIZE -
-                           keys.enckeylen);
-@@ -527,12 +618,14 @@ static int aead_setkey(struct crypto_aea
-       /* postpend encryption key to auth split key */
-       memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
-       dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
--                                 keys.enckeylen, DMA_TO_DEVICE);
-+                                 keys.enckeylen, ctx->dir);
- #ifdef DEBUG
-       print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
-                      DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
-                      ctx->adata.keylen_pad + keys.enckeylen, 1);
- #endif
-+
-+skip_split_key:
-       ctx->cdata.keylen = keys.enckeylen;
-       return aead_set_sh_desc(aead);
- badkey:
-@@ -552,7 +645,7 @@ static int gcm_setkey(struct crypto_aead
- #endif
-       memcpy(ctx->key, key, keylen);
--      dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE);
-+      dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir);
-       ctx->cdata.keylen = keylen;
-       return gcm_set_sh_desc(aead);
-@@ -580,7 +673,7 @@ static int rfc4106_setkey(struct crypto_
-        */
-       ctx->cdata.keylen = keylen - 4;
-       dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
--                                 DMA_TO_DEVICE);
-+                                 ctx->dir);
-       return rfc4106_set_sh_desc(aead);
- }
-@@ -606,7 +699,7 @@ static int rfc4543_setkey(struct crypto_
-        */
-       ctx->cdata.keylen = keylen - 4;
-       dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
--                                 DMA_TO_DEVICE);
-+                                 ctx->dir);
-       return rfc4543_set_sh_desc(aead);
- }
-@@ -658,21 +751,21 @@ static int ablkcipher_setkey(struct cryp
-       cnstr_shdsc_ablkcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
-                                    ctx1_iv_off);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       /* ablkcipher_decrypt shared descriptor */
-       desc = ctx->sh_desc_dec;
-       cnstr_shdsc_ablkcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
-                                    ctx1_iv_off);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       /* ablkcipher_givencrypt shared descriptor */
-       desc = ctx->sh_desc_givenc;
-       cnstr_shdsc_ablkcipher_givencap(desc, &ctx->cdata, ivsize, is_rfc3686,
-                                       ctx1_iv_off);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_givenc_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       return 0;
- }
-@@ -701,13 +794,13 @@ static int xts_ablkcipher_setkey(struct
-       desc = ctx->sh_desc_enc;
-       cnstr_shdsc_xts_ablkcipher_encap(desc, &ctx->cdata);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       /* xts_ablkcipher_decrypt shared descriptor */
-       desc = ctx->sh_desc_dec;
-       cnstr_shdsc_xts_ablkcipher_decap(desc, &ctx->cdata);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
-       return 0;
- }
-@@ -989,9 +1082,6 @@ static void init_aead_job(struct aead_re
-               append_seq_out_ptr(desc, dst_dma,
-                                  req->assoclen + req->cryptlen - authsize,
-                                  out_options);
--
--      /* REG3 = assoclen */
--      append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
- }
- static void init_gcm_job(struct aead_request *req,
-@@ -1006,6 +1096,7 @@ static void init_gcm_job(struct aead_req
-       unsigned int last;
-       init_aead_job(req, edesc, all_contig, encrypt);
-+      append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
-       /* BUG This should not be specific to generic GCM. */
-       last = 0;
-@@ -1023,6 +1114,40 @@ static void init_gcm_job(struct aead_req
-       /* End of blank commands */
- }
-+static void init_chachapoly_job(struct aead_request *req,
-+                              struct aead_edesc *edesc, bool all_contig,
-+                              bool encrypt)
-+{
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      unsigned int assoclen = req->assoclen;
-+      u32 *desc = edesc->hw_desc;
-+      u32 ctx_iv_off = 4;
-+
-+      init_aead_job(req, edesc, all_contig, encrypt);
-+
-+      if (ivsize != CHACHAPOLY_IV_SIZE) {
-+              /* IPsec specific: CONTEXT1[223:128] = {NONCE, IV} */
-+              ctx_iv_off += 4;
-+
-+              /*
-+               * The associated data comes already with the IV but we need
-+               * to skip it when we authenticate or encrypt...
-+               */
-+              assoclen -= ivsize;
-+      }
-+
-+      append_math_add_imm_u32(desc, REG3, ZERO, IMM, assoclen);
-+
-+      /*
-+       * For IPsec load the IV further in the same register.
-+       * For RFC7539 simply load the 12 bytes nonce in a single operation
-+       */
-+      append_load_as_imm(desc, req->iv, ivsize, LDST_CLASS_1_CCB |
-+                         LDST_SRCDST_BYTE_CONTEXT |
-+                         ctx_iv_off << LDST_OFFSET_SHIFT);
-+}
-+
- static void init_authenc_job(struct aead_request *req,
-                            struct aead_edesc *edesc,
-                            bool all_contig, bool encrypt)
-@@ -1032,6 +1157,7 @@ static void init_authenc_job(struct aead
-                                                struct caam_aead_alg, aead);
-       unsigned int ivsize = crypto_aead_ivsize(aead);
-       struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
-       const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
-                              OP_ALG_AAI_CTR_MOD128);
-       const bool is_rfc3686 = alg->caam.rfc3686;
-@@ -1055,6 +1181,15 @@ static void init_authenc_job(struct aead
-       init_aead_job(req, edesc, all_contig, encrypt);
-+      /*
-+       * {REG3, DPOVRD} = assoclen, depending on whether MATH command supports
-+       * having DPOVRD as destination.
-+       */
-+      if (ctrlpriv->era < 3)
-+              append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
-+      else
-+              append_math_add_imm_u32(desc, DPOVRD, ZERO, IMM, req->assoclen);
-+
-       if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
-               append_load_as_imm(desc, req->iv, ivsize,
-                                  LDST_CLASS_1_CCB |
-@@ -1227,8 +1362,16 @@ static struct aead_edesc *aead_edesc_all
-               }
-       }
-+      /*
-+       * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
-+       * the end of the table by allocating more S/G entries.
-+       */
-       sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0;
--      sec4_sg_len += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
-+      if (mapped_dst_nents > 1)
-+              sec4_sg_len += ALIGN(mapped_dst_nents, 4);
-+      else
-+              sec4_sg_len = ALIGN(sec4_sg_len, 4);
-+
-       sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
-       /* allocate space for base edesc and hw desc commands, link tables */
-@@ -1309,6 +1452,72 @@ static int gcm_encrypt(struct aead_reque
-       return ret;
- }
-+static int chachapoly_encrypt(struct aead_request *req)
-+{
-+      struct aead_edesc *edesc;
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *jrdev = ctx->jrdev;
-+      bool all_contig;
-+      u32 *desc;
-+      int ret;
-+
-+      edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
-+                               true);
-+      if (IS_ERR(edesc))
-+              return PTR_ERR(edesc);
-+
-+      desc = edesc->hw_desc;
-+
-+      init_chachapoly_job(req, edesc, all_contig, true);
-+      print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
-+                           DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
-+                           1);
-+
-+      ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
-+      if (!ret) {
-+              ret = -EINPROGRESS;
-+      } else {
-+              aead_unmap(jrdev, edesc, req);
-+              kfree(edesc);
-+      }
-+
-+      return ret;
-+}
-+
-+static int chachapoly_decrypt(struct aead_request *req)
-+{
-+      struct aead_edesc *edesc;
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *jrdev = ctx->jrdev;
-+      bool all_contig;
-+      u32 *desc;
-+      int ret;
-+
-+      edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
-+                               false);
-+      if (IS_ERR(edesc))
-+              return PTR_ERR(edesc);
-+
-+      desc = edesc->hw_desc;
-+
-+      init_chachapoly_job(req, edesc, all_contig, false);
-+      print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
-+                           DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
-+                           1);
-+
-+      ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
-+      if (!ret) {
-+              ret = -EINPROGRESS;
-+      } else {
-+              aead_unmap(jrdev, edesc, req);
-+              kfree(edesc);
-+      }
-+
-+      return ret;
-+}
-+
- static int ipsec_gcm_encrypt(struct aead_request *req)
- {
-       if (req->assoclen < 8)
-@@ -1496,7 +1705,25 @@ static struct ablkcipher_edesc *ablkciph
-       sec4_sg_ents = 1 + mapped_src_nents;
-       dst_sg_idx = sec4_sg_ents;
--      sec4_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
-+
-+      /*
-+       * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
-+       * the end of the table by allocating more S/G entries. Logic:
-+       * if (src != dst && output S/G)
-+       *      pad output S/G, if needed
-+       * else if (src == dst && S/G)
-+       *      overlapping S/Gs; pad one of them
-+       * else if (input S/G) ...
-+       *      pad input S/G, if needed
-+       */
-+      if (mapped_dst_nents > 1)
-+              sec4_sg_ents += ALIGN(mapped_dst_nents, 4);
-+      else if ((req->src == req->dst) && (mapped_src_nents > 1))
-+              sec4_sg_ents = max(ALIGN(sec4_sg_ents, 4),
-+                                 1 + ALIGN(mapped_src_nents, 4));
-+      else
-+              sec4_sg_ents = ALIGN(sec4_sg_ents, 4);
-+
-       sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
-       /*
-@@ -3199,6 +3426,50 @@ static struct caam_aead_alg driver_aeads
-                       .geniv = true,
-               },
-       },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "rfc7539(chacha20,poly1305)",
-+                              .cra_driver_name = "rfc7539-chacha20-poly1305-"
-+                                                 "caam",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = chachapoly_setkey,
-+                      .setauthsize = chachapoly_setauthsize,
-+                      .encrypt = chachapoly_encrypt,
-+                      .decrypt = chachapoly_decrypt,
-+                      .ivsize = CHACHAPOLY_IV_SIZE,
-+                      .maxauthsize = POLY1305_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
-+                                         OP_ALG_AAI_AEAD,
-+                      .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
-+                                         OP_ALG_AAI_AEAD,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "rfc7539esp(chacha20,poly1305)",
-+                              .cra_driver_name = "rfc7539esp-chacha20-"
-+                                                 "poly1305-caam",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = chachapoly_setkey,
-+                      .setauthsize = chachapoly_setauthsize,
-+                      .encrypt = chachapoly_encrypt,
-+                      .decrypt = chachapoly_decrypt,
-+                      .ivsize = 8,
-+                      .maxauthsize = POLY1305_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
-+                                         OP_ALG_AAI_AEAD,
-+                      .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
-+                                         OP_ALG_AAI_AEAD,
-+              },
-+      },
- };
- struct caam_crypto_alg {
-@@ -3207,9 +3478,11 @@ struct caam_crypto_alg {
-       struct caam_alg_entry caam;
- };
--static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam)
-+static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
-+                         bool uses_dkp)
- {
-       dma_addr_t dma_addr;
-+      struct caam_drv_private *priv;
-       ctx->jrdev = caam_jr_alloc();
-       if (IS_ERR(ctx->jrdev)) {
-@@ -3217,10 +3490,16 @@ static int caam_init_common(struct caam_
-               return PTR_ERR(ctx->jrdev);
-       }
-+      priv = dev_get_drvdata(ctx->jrdev->parent);
-+      if (priv->era >= 6 && uses_dkp)
-+              ctx->dir = DMA_BIDIRECTIONAL;
-+      else
-+              ctx->dir = DMA_TO_DEVICE;
-+
-       dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_enc,
-                                       offsetof(struct caam_ctx,
-                                                sh_desc_enc_dma),
--                                      DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
-+                                      ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
-       if (dma_mapping_error(ctx->jrdev, dma_addr)) {
-               dev_err(ctx->jrdev, "unable to map key, shared descriptors\n");
-               caam_jr_free(ctx->jrdev);
-@@ -3248,7 +3527,7 @@ static int caam_cra_init(struct crypto_t
-                container_of(alg, struct caam_crypto_alg, crypto_alg);
-       struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
--      return caam_init_common(ctx, &caam_alg->caam);
-+      return caam_init_common(ctx, &caam_alg->caam, false);
- }
- static int caam_aead_init(struct crypto_aead *tfm)
-@@ -3258,14 +3537,15 @@ static int caam_aead_init(struct crypto_
-                container_of(alg, struct caam_aead_alg, aead);
-       struct caam_ctx *ctx = crypto_aead_ctx(tfm);
--      return caam_init_common(ctx, &caam_alg->caam);
-+      return caam_init_common(ctx, &caam_alg->caam,
-+                              alg->setkey == aead_setkey);
- }
- static void caam_exit_common(struct caam_ctx *ctx)
- {
-       dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_enc_dma,
-                              offsetof(struct caam_ctx, sh_desc_enc_dma),
--                             DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
-+                             ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
-       caam_jr_free(ctx->jrdev);
- }
-@@ -3279,7 +3559,7 @@ static void caam_aead_exit(struct crypto
-       caam_exit_common(crypto_aead_ctx(tfm));
- }
--static void __exit caam_algapi_exit(void)
-+void caam_algapi_exit(void)
- {
-       struct caam_crypto_alg *t_alg, *n;
-@@ -3358,56 +3638,52 @@ static void caam_aead_alg_init(struct ca
-       alg->exit = caam_aead_exit;
- }
--static int __init caam_algapi_init(void)
-+int caam_algapi_init(struct device *ctrldev)
- {
--      struct device_node *dev_node;
--      struct platform_device *pdev;
--      struct device *ctrldev;
--      struct caam_drv_private *priv;
-+      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
-       int i = 0, err = 0;
--      u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
-+      u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst;
-       unsigned int md_limit = SHA512_DIGEST_SIZE;
-       bool registered = false;
--      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
--      if (!dev_node) {
--              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
--              if (!dev_node)
--                      return -ENODEV;
--      }
--
--      pdev = of_find_device_by_node(dev_node);
--      if (!pdev) {
--              of_node_put(dev_node);
--              return -ENODEV;
--      }
--
--      ctrldev = &pdev->dev;
--      priv = dev_get_drvdata(ctrldev);
--      of_node_put(dev_node);
--
--      /*
--       * If priv is NULL, it's probably because the caam driver wasn't
--       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
--       */
--      if (!priv)
--              return -ENODEV;
--
--
-       INIT_LIST_HEAD(&alg_list);
-       /*
-        * Register crypto algorithms the device supports.
-        * First, detect presence and attributes of DES, AES, and MD blocks.
-        */
--      cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
--      cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
--      des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
--      aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
--      md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
-+      if (priv->era < 10) {
-+              u32 cha_vid, cha_inst;
-+
-+              cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
-+              aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
-+              md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
-+
-+              cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
-+              des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
-+                         CHA_ID_LS_DES_SHIFT;
-+              aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
-+              md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
-+              ccha_inst = 0;
-+              ptha_inst = 0;
-+      } else {
-+              u32 aesa, mdha;
-+
-+              aesa = rd_reg32(&priv->ctrl->vreg.aesa);
-+              mdha = rd_reg32(&priv->ctrl->vreg.mdha);
-+
-+              aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
-+              md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
-+
-+              des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
-+              aes_inst = aesa & CHA_VER_NUM_MASK;
-+              md_inst = mdha & CHA_VER_NUM_MASK;
-+              ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK;
-+              ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK;
-+      }
-       /* If MD is present, limit digest size based on LP256 */
--      if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
-+      if (md_inst && md_vid  == CHA_VER_VID_MD_LP256)
-               md_limit = SHA256_DIGEST_SIZE;
-       for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
-@@ -3429,10 +3705,10 @@ static int __init caam_algapi_init(void)
-                * Check support for AES modes not available
-                * on LP devices.
-                */
--              if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
--                      if ((alg->class1_alg_type & OP_ALG_AAI_MASK) ==
--                           OP_ALG_AAI_XTS)
--                              continue;
-+              if (aes_vid == CHA_VER_VID_AES_LP &&
-+                  (alg->class1_alg_type & OP_ALG_AAI_MASK) ==
-+                  OP_ALG_AAI_XTS)
-+                      continue;
-               t_alg = caam_alg_alloc(alg);
-               if (IS_ERR(t_alg)) {
-@@ -3471,21 +3747,28 @@ static int __init caam_algapi_init(void)
-               if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
-                               continue;
-+              /* Skip CHACHA20 algorithms if not supported by device */
-+              if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && !ccha_inst)
-+                      continue;
-+
-+              /* Skip POLY1305 algorithms if not supported by device */
-+              if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst)
-+                      continue;
-+
-               /*
-                * Check support for AES algorithms not available
-                * on LP devices.
-                */
--              if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
--                      if (alg_aai == OP_ALG_AAI_GCM)
--                              continue;
-+              if (aes_vid  == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM)
-+                      continue;
-               /*
-                * Skip algorithms requiring message digests
-                * if MD or MD size is not supported by device.
-                */
--              if (c2_alg_sel &&
--                  (!md_inst || (t_alg->aead.maxauthsize > md_limit)))
--                              continue;
-+              if ((c2_alg_sel & ~OP_ALG_ALGSEL_SUBMASK) == 0x40 &&
-+                  (!md_inst || t_alg->aead.maxauthsize > md_limit))
-+                      continue;
-               caam_aead_alg_init(t_alg);
-@@ -3505,10 +3788,3 @@ static int __init caam_algapi_init(void)
-       return err;
- }
--
--module_init(caam_algapi_init);
--module_exit(caam_algapi_exit);
--
--MODULE_LICENSE("GPL");
--MODULE_DESCRIPTION("FSL CAAM support for crypto API");
--MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
---- a/drivers/crypto/caam/caamalg_desc.c
-+++ b/drivers/crypto/caam/caamalg_desc.c
-@@ -45,16 +45,16 @@ static inline void append_dec_op1(u32 *d
-  * cnstr_shdsc_aead_null_encap - IPSec ESP encapsulation shared descriptor
-  *                               (non-protocol) with no (null) encryption.
-  * @desc: pointer to buffer used for descriptor construction
-- * @adata: pointer to authentication transform definitions. Note that since a
-- *         split key is to be used, the size of the split key itself is
-- *         specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
-- *         SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
-+ * @adata: pointer to authentication transform definitions.
-+ *         A split key is required for SEC Era < 6; the size of the split key
-+ *         is specified in this case. Valid algorithm values - one of
-+ *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
-+ *         with OP_ALG_AAI_HMAC_PRECOMP.
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-- *
-- * Note: Requires an MDHA split key.
-+ * @era: SEC Era
-  */
- void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
--                               unsigned int icvsize)
-+                               unsigned int icvsize, int era)
- {
-       u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
-@@ -63,13 +63,18 @@ void cnstr_shdsc_aead_null_encap(u32 * c
-       /* Skip if already shared */
-       key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-                                  JUMP_COND_SHRD);
--      if (adata->key_inline)
--              append_key_as_imm(desc, adata->key_virt, adata->keylen_pad,
--                                adata->keylen, CLASS_2 | KEY_DEST_MDHA_SPLIT |
--                                KEY_ENC);
--      else
--              append_key(desc, adata->key_dma, adata->keylen, CLASS_2 |
--                         KEY_DEST_MDHA_SPLIT | KEY_ENC);
-+      if (era < 6) {
-+              if (adata->key_inline)
-+                      append_key_as_imm(desc, adata->key_virt,
-+                                        adata->keylen_pad, adata->keylen,
-+                                        CLASS_2 | KEY_DEST_MDHA_SPLIT |
-+                                        KEY_ENC);
-+              else
-+                      append_key(desc, adata->key_dma, adata->keylen,
-+                                 CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
-+      } else {
-+              append_proto_dkp(desc, adata);
-+      }
-       set_jump_tgt_here(desc, key_jump_cmd);
-       /* assoclen + cryptlen = seqinlen */
-@@ -121,16 +126,16 @@ EXPORT_SYMBOL(cnstr_shdsc_aead_null_enca
-  * cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
-  *                               (non-protocol) with no (null) decryption.
-  * @desc: pointer to buffer used for descriptor construction
-- * @adata: pointer to authentication transform definitions. Note that since a
-- *         split key is to be used, the size of the split key itself is
-- *         specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
-- *         SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
-+ * @adata: pointer to authentication transform definitions.
-+ *         A split key is required for SEC Era < 6; the size of the split key
-+ *         is specified in this case. Valid algorithm values - one of
-+ *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
-+ *         with OP_ALG_AAI_HMAC_PRECOMP.
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-- *
-- * Note: Requires an MDHA split key.
-+ * @era: SEC Era
-  */
- void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
--                               unsigned int icvsize)
-+                               unsigned int icvsize, int era)
- {
-       u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
-@@ -139,13 +144,18 @@ void cnstr_shdsc_aead_null_decap(u32 * c
-       /* Skip if already shared */
-       key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-                                  JUMP_COND_SHRD);
--      if (adata->key_inline)
--              append_key_as_imm(desc, adata->key_virt, adata->keylen_pad,
--                                adata->keylen, CLASS_2 |
--                                KEY_DEST_MDHA_SPLIT | KEY_ENC);
--      else
--              append_key(desc, adata->key_dma, adata->keylen, CLASS_2 |
--                         KEY_DEST_MDHA_SPLIT | KEY_ENC);
-+      if (era < 6) {
-+              if (adata->key_inline)
-+                      append_key_as_imm(desc, adata->key_virt,
-+                                        adata->keylen_pad, adata->keylen,
-+                                        CLASS_2 | KEY_DEST_MDHA_SPLIT |
-+                                        KEY_ENC);
-+              else
-+                      append_key(desc, adata->key_dma, adata->keylen,
-+                                 CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
-+      } else {
-+              append_proto_dkp(desc, adata);
-+      }
-       set_jump_tgt_here(desc, key_jump_cmd);
-       /* Class 2 operation */
-@@ -204,7 +214,7 @@ EXPORT_SYMBOL(cnstr_shdsc_aead_null_deca
- static void init_sh_desc_key_aead(u32 * const desc,
-                                 struct alginfo * const cdata,
-                                 struct alginfo * const adata,
--                                const bool is_rfc3686, u32 *nonce)
-+                                const bool is_rfc3686, u32 *nonce, int era)
- {
-       u32 *key_jump_cmd;
-       unsigned int enckeylen = cdata->keylen;
-@@ -224,13 +234,18 @@ static void init_sh_desc_key_aead(u32 *
-       if (is_rfc3686)
-               enckeylen -= CTR_RFC3686_NONCE_SIZE;
--      if (adata->key_inline)
--              append_key_as_imm(desc, adata->key_virt, adata->keylen_pad,
--                                adata->keylen, CLASS_2 |
--                                KEY_DEST_MDHA_SPLIT | KEY_ENC);
--      else
--              append_key(desc, adata->key_dma, adata->keylen, CLASS_2 |
--                         KEY_DEST_MDHA_SPLIT | KEY_ENC);
-+      if (era < 6) {
-+              if (adata->key_inline)
-+                      append_key_as_imm(desc, adata->key_virt,
-+                                        adata->keylen_pad, adata->keylen,
-+                                        CLASS_2 | KEY_DEST_MDHA_SPLIT |
-+                                        KEY_ENC);
-+              else
-+                      append_key(desc, adata->key_dma, adata->keylen,
-+                                 CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
-+      } else {
-+              append_proto_dkp(desc, adata);
-+      }
-       if (cdata->key_inline)
-               append_key_as_imm(desc, cdata->key_virt, enckeylen,
-@@ -261,26 +276,27 @@ static void init_sh_desc_key_aead(u32 *
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
-  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
-- * @adata: pointer to authentication transform definitions. Note that since a
-- *         split key is to be used, the size of the split key itself is
-- *         specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
-- *         SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
-+ * @adata: pointer to authentication transform definitions.
-+ *         A split key is required for SEC Era < 6; the size of the split key
-+ *         is specified in this case. Valid algorithm values - one of
-+ *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
-+ *         with OP_ALG_AAI_HMAC_PRECOMP.
-  * @ivsize: initialization vector size
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
-  * @nonce: pointer to rfc3686 nonce
-  * @ctx1_iv_off: IV offset in CONTEXT1 register
-  * @is_qi: true when called from caam/qi
-- *
-- * Note: Requires an MDHA split key.
-+ * @era: SEC Era
-  */
- void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
-                           struct alginfo *adata, unsigned int ivsize,
-                           unsigned int icvsize, const bool is_rfc3686,
--                          u32 *nonce, const u32 ctx1_iv_off, const bool is_qi)
-+                          u32 *nonce, const u32 ctx1_iv_off, const bool is_qi,
-+                          int era)
- {
-       /* Note: Context registers are saved. */
--      init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
-+      init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
-       /* Class 2 operation */
-       append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
-@@ -306,8 +322,13 @@ void cnstr_shdsc_aead_encap(u32 * const
-       }
-       /* Read and write assoclen bytes */
--      append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
--      append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
-+      if (is_qi || era < 3) {
-+              append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
-+              append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
-+      } else {
-+              append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
-+              append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
-+      }
-       /* Skip assoc data */
-       append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
-@@ -350,27 +371,27 @@ EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
-  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
-- * @adata: pointer to authentication transform definitions. Note that since a
-- *         split key is to be used, the size of the split key itself is
-- *         specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
-- *         SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
-+ * @adata: pointer to authentication transform definitions.
-+ *         A split key is required for SEC Era < 6; the size of the split key
-+ *         is specified in this case. Valid algorithm values - one of
-+ *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
-+ *         with OP_ALG_AAI_HMAC_PRECOMP.
-  * @ivsize: initialization vector size
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
-  * @nonce: pointer to rfc3686 nonce
-  * @ctx1_iv_off: IV offset in CONTEXT1 register
-  * @is_qi: true when called from caam/qi
-- *
-- * Note: Requires an MDHA split key.
-+ * @era: SEC Era
-  */
- void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
-                           struct alginfo *adata, unsigned int ivsize,
-                           unsigned int icvsize, const bool geniv,
-                           const bool is_rfc3686, u32 *nonce,
--                          const u32 ctx1_iv_off, const bool is_qi)
-+                          const u32 ctx1_iv_off, const bool is_qi, int era)
- {
-       /* Note: Context registers are saved. */
--      init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
-+      init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
-       /* Class 2 operation */
-       append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
-@@ -397,11 +418,23 @@ void cnstr_shdsc_aead_decap(u32 * const
-       }
-       /* Read and write assoclen bytes */
--      append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
--      if (geniv)
--              append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM, ivsize);
--      else
--              append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
-+      if (is_qi || era < 3) {
-+              append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
-+              if (geniv)
-+                      append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
-+                                              ivsize);
-+              else
-+                      append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
-+                                      CAAM_CMD_SZ);
-+      } else {
-+              append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
-+              if (geniv)
-+                      append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
-+                                              ivsize);
-+              else
-+                      append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
-+                                      CAAM_CMD_SZ);
-+      }
-       /* Skip assoc data */
-       append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
-@@ -456,30 +489,29 @@ EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
-  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
-- * @adata: pointer to authentication transform definitions. Note that since a
-- *         split key is to be used, the size of the split key itself is
-- *         specified. Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1,
-- *         SHA224, SHA256, SHA384, SHA512} ANDed with OP_ALG_AAI_HMAC_PRECOMP.
-- * @ivsize: initialization vector size
-+ * @adata: pointer to authentication transform definitions.
-+ *         A split key is required for SEC Era < 6; the size of the split key
-+ *         is specified in this case. Valid algorithm values - one of
-+ *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
-+ *         with OP_ALG_AAI_HMAC_PRECOMP. * @ivsize: initialization vector size
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
-  * @nonce: pointer to rfc3686 nonce
-  * @ctx1_iv_off: IV offset in CONTEXT1 register
-  * @is_qi: true when called from caam/qi
-- *
-- * Note: Requires an MDHA split key.
-+ * @era: SEC Era
-  */
- void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
-                              struct alginfo *adata, unsigned int ivsize,
-                              unsigned int icvsize, const bool is_rfc3686,
-                              u32 *nonce, const u32 ctx1_iv_off,
--                             const bool is_qi)
-+                             const bool is_qi, int era)
- {
-       u32 geniv, moveiv;
-       u32 *wait_cmd;
-       /* Note: Context registers are saved. */
--      init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce);
-+      init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
-       if (is_qi) {
-               u32 *wait_load_cmd;
-@@ -529,8 +561,13 @@ copy_iv:
-                        OP_ALG_ENCRYPT);
-       /* Read and write assoclen bytes */
--      append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
--      append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
-+      if (is_qi || era < 3) {
-+              append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
-+              append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
-+      } else {
-+              append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
-+              append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
-+      }
-       /* Skip assoc data */
-       append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
-@@ -592,14 +629,431 @@ copy_iv:
- EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
- /**
-+ * cnstr_shdsc_tls_encap - tls encapsulation shared descriptor
-+ * @desc: pointer to buffer used for descriptor construction
-+ * @cdata: pointer to block cipher transform definitions
-+ *         Valid algorithm values - one of OP_ALG_ALGSEL_AES ANDed
-+ *         with OP_ALG_AAI_CBC
-+ * @adata: pointer to authentication transform definitions.
-+ *         A split key is required for SEC Era < 6; the size of the split key
-+ *         is specified in this case. Valid algorithm values OP_ALG_ALGSEL_SHA1
-+ *         ANDed with OP_ALG_AAI_HMAC_PRECOMP.
-+ * @assoclen: associated data length
-+ * @ivsize: initialization vector size
-+ * @authsize: authentication data size
-+ * @blocksize: block cipher size
-+ * @era: SEC Era
-+ */
-+void cnstr_shdsc_tls_encap(u32 * const desc, struct alginfo *cdata,
-+                         struct alginfo *adata, unsigned int assoclen,
-+                         unsigned int ivsize, unsigned int authsize,
-+                         unsigned int blocksize, int era)
-+{
-+      u32 *key_jump_cmd, *zero_payload_jump_cmd;
-+      u32 genpad, idx_ld_datasz, idx_ld_pad, stidx;
-+
-+      /*
-+       * Compute the index (in bytes) for the LOAD with destination of
-+       * Class 1 Data Size Register and for the LOAD that generates padding
-+       */
-+      if (adata->key_inline) {
-+              idx_ld_datasz = DESC_TLS10_ENC_LEN + adata->keylen_pad +
-+                              cdata->keylen - 4 * CAAM_CMD_SZ;
-+              idx_ld_pad = DESC_TLS10_ENC_LEN + adata->keylen_pad +
-+                           cdata->keylen - 2 * CAAM_CMD_SZ;
-+      } else {
-+              idx_ld_datasz = DESC_TLS10_ENC_LEN + 2 * CAAM_PTR_SZ -
-+                              4 * CAAM_CMD_SZ;
-+              idx_ld_pad = DESC_TLS10_ENC_LEN + 2 * CAAM_PTR_SZ -
-+                           2 * CAAM_CMD_SZ;
-+      }
-+
-+      stidx = 1 << HDR_START_IDX_SHIFT;
-+      init_sh_desc(desc, HDR_SHARE_SERIAL | stidx);
-+
-+      /* skip key loading if they are loaded due to sharing */
-+      key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-+                                 JUMP_COND_SHRD);
-+
-+      if (era < 6) {
-+              if (adata->key_inline)
-+                      append_key_as_imm(desc, adata->key_virt,
-+                                        adata->keylen_pad, adata->keylen,
-+                                        CLASS_2 | KEY_DEST_MDHA_SPLIT |
-+                                        KEY_ENC);
-+              else
-+                      append_key(desc, adata->key_dma, adata->keylen,
-+                                 CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
-+      } else {
-+              append_proto_dkp(desc, adata);
-+      }
-+
-+      if (cdata->key_inline)
-+              append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
-+                                cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
-+      else
-+              append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
-+                         KEY_DEST_CLASS_REG);
-+
-+      set_jump_tgt_here(desc, key_jump_cmd);
-+
-+      /* class 2 operation */
-+      append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
-+                       OP_ALG_ENCRYPT);
-+      /* class 1 operation */
-+      append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-+                       OP_ALG_ENCRYPT);
-+
-+      /* payloadlen = input data length - (assoclen + ivlen) */
-+      append_math_sub_imm_u32(desc, REG0, SEQINLEN, IMM, assoclen + ivsize);
-+
-+      /* math1 = payloadlen + icvlen */
-+      append_math_add_imm_u32(desc, REG1, REG0, IMM, authsize);
-+
-+      /* padlen = block_size - math1 % block_size */
-+      append_math_and_imm_u32(desc, REG3, REG1, IMM, blocksize - 1);
-+      append_math_sub_imm_u32(desc, REG2, IMM, REG3, blocksize);
-+
-+      /* cryptlen = payloadlen + icvlen + padlen */
-+      append_math_add(desc, VARSEQOUTLEN, REG1, REG2, 4);
-+
-+      /*
-+       * update immediate data with the padding length value
-+       * for the LOAD in the class 1 data size register.
-+       */
-+      append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH2 |
-+                      (idx_ld_datasz << MOVE_OFFSET_SHIFT) | 7);
-+      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH2 | MOVE_DEST_DESCBUF |
-+                      (idx_ld_datasz << MOVE_OFFSET_SHIFT) | 8);
-+
-+      /* overwrite PL field for the padding iNFO FIFO entry  */
-+      append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH2 |
-+                      (idx_ld_pad << MOVE_OFFSET_SHIFT) | 7);
-+      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH2 | MOVE_DEST_DESCBUF |
-+                      (idx_ld_pad << MOVE_OFFSET_SHIFT) | 8);
-+
-+      /* store encrypted payload, icv and padding */
-+      append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
-+
-+      /* if payload length is zero, jump to zero-payload commands */
-+      append_math_add(desc, VARSEQINLEN, ZERO, REG0, 4);
-+      zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
-+                                          JUMP_COND_MATH_Z);
-+
-+      /* load iv in context1 */
-+      append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_WORD_CLASS_CTX |
-+                 LDST_CLASS_1_CCB | ivsize);
-+
-+      /* read assoc for authentication */
-+      append_seq_fifo_load(desc, assoclen, FIFOLD_CLASS_CLASS2 |
-+                           FIFOLD_TYPE_MSG);
-+      /* insnoop payload */
-+      append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG |
-+                           FIFOLD_TYPE_LAST2 | FIFOLDST_VLF);
-+
-+      /* jump the zero-payload commands */
-+      append_jump(desc, JUMP_TEST_ALL | 3);
-+
-+      /* zero-payload commands */
-+      set_jump_tgt_here(desc, zero_payload_jump_cmd);
-+
-+      /* load iv in context1 */
-+      append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_WORD_CLASS_CTX |
-+                 LDST_CLASS_1_CCB | ivsize);
-+
-+      /* assoc data is the only data for authentication */
-+      append_seq_fifo_load(desc, assoclen, FIFOLD_CLASS_CLASS2 |
-+                           FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2);
-+
-+      /* send icv to encryption */
-+      append_move(desc, MOVE_SRC_CLASS2CTX | MOVE_DEST_CLASS1INFIFO |
-+                  authsize);
-+
-+      /* update class 1 data size register with padding length */
-+      append_load_imm_u32(desc, 0, LDST_CLASS_1_CCB |
-+                          LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
-+
-+      /* generate padding and send it to encryption */
-+      genpad = NFIFOENTRY_DEST_CLASS1 | NFIFOENTRY_LC1 | NFIFOENTRY_FC1 |
-+            NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_PTYPE_N;
-+      append_load_imm_u32(desc, genpad, LDST_CLASS_IND_CCB |
-+                          LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "tls enc shdesc@" __stringify(__LINE__) ": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, desc,
-+                     desc_bytes(desc), 1);
-+#endif
-+}
-+EXPORT_SYMBOL(cnstr_shdsc_tls_encap);
-+
-+/**
-+ * cnstr_shdsc_tls_decap - tls decapsulation shared descriptor
-+ * @desc: pointer to buffer used for descriptor construction
-+ * @cdata: pointer to block cipher transform definitions
-+ *         Valid algorithm values - one of OP_ALG_ALGSEL_AES ANDed
-+ *         with OP_ALG_AAI_CBC
-+ * @adata: pointer to authentication transform definitions.
-+ *         A split key is required for SEC Era < 6; the size of the split key
-+ *         is specified in this case. Valid algorithm values OP_ALG_ALGSEL_SHA1
-+ *         ANDed with OP_ALG_AAI_HMAC_PRECOMP.
-+ * @assoclen: associated data length
-+ * @ivsize: initialization vector size
-+ * @authsize: authentication data size
-+ * @blocksize: block cipher size
-+ * @era: SEC Era
-+ */
-+void cnstr_shdsc_tls_decap(u32 * const desc, struct alginfo *cdata,
-+                         struct alginfo *adata, unsigned int assoclen,
-+                         unsigned int ivsize, unsigned int authsize,
-+                         unsigned int blocksize, int era)
-+{
-+      u32 stidx, jumpback;
-+      u32 *key_jump_cmd, *zero_payload_jump_cmd, *skip_zero_jump_cmd;
-+      /*
-+       * Pointer Size bool determines the size of address pointers.
-+       * false - Pointers fit in one 32-bit word.
-+       * true - Pointers fit in two 32-bit words.
-+       */
-+      static const bool ps = (CAAM_PTR_SZ != CAAM_CMD_SZ);
-+
-+      stidx = 1 << HDR_START_IDX_SHIFT;
-+      init_sh_desc(desc, HDR_SHARE_SERIAL | stidx);
-+
-+      /* skip key loading if they are loaded due to sharing */
-+      key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-+                                 JUMP_COND_SHRD);
-+
-+      if (era < 6)
-+              append_key(desc, adata->key_dma, adata->keylen, CLASS_2 |
-+                         KEY_DEST_MDHA_SPLIT | KEY_ENC);
-+      else
-+              append_proto_dkp(desc, adata);
-+
-+      append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
-+                 KEY_DEST_CLASS_REG);
-+
-+      set_jump_tgt_here(desc, key_jump_cmd);
-+
-+      /* class 2 operation */
-+      append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
-+                       OP_ALG_DECRYPT | OP_ALG_ICV_ON);
-+      /* class 1 operation */
-+      append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-+                       OP_ALG_DECRYPT);
-+
-+      /* VSIL = input data length - 2 * block_size */
-+      append_math_sub_imm_u32(desc, VARSEQINLEN, SEQINLEN, IMM, 2 *
-+                              blocksize);
-+
-+      /*
-+       * payloadlen + icvlen + padlen = input data length - (assoclen +
-+       * ivsize)
-+       */
-+      append_math_sub_imm_u32(desc, REG3, SEQINLEN, IMM, assoclen + ivsize);
-+
-+      /* skip data to the last but one cipher block */
-+      append_seq_fifo_load(desc, 0, FIFOLD_CLASS_SKIP | LDST_VLF);
-+
-+      /* load iv for the last cipher block */
-+      append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_WORD_CLASS_CTX |
-+                 LDST_CLASS_1_CCB | ivsize);
-+
-+      /* read last cipher block */
-+      append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG |
-+                           FIFOLD_TYPE_LAST1 | blocksize);
-+
-+      /* move decrypted block into math0 and math1 */
-+      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO | MOVE_DEST_MATH0 |
-+                  blocksize);
-+
-+      /* reset AES CHA */
-+      append_load_imm_u32(desc, CCTRL_RESET_CHA_AESA, LDST_CLASS_IND_CCB |
-+                          LDST_SRCDST_WORD_CHACTRL | LDST_IMM);
-+
-+      /* rewind input sequence */
-+      append_seq_in_ptr_intlen(desc, 0, 65535, SQIN_RTO);
-+
-+      /* key1 is in decryption form */
-+      append_operation(desc, cdata->algtype | OP_ALG_AAI_DK |
-+                       OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT);
-+
-+      /* load iv in context1 */
-+      append_cmd(desc, CMD_SEQ_LOAD | LDST_CLASS_1_CCB |
-+                 LDST_SRCDST_WORD_CLASS_CTX | ivsize);
-+
-+      /* read sequence number */
-+      append_seq_fifo_load(desc, 8, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG);
-+      /* load Type, Version and Len fields in math0 */
-+      append_cmd(desc, CMD_SEQ_LOAD | LDST_CLASS_DECO |
-+                 LDST_SRCDST_WORD_DECO_MATH0 | (3 << LDST_OFFSET_SHIFT) | 5);
-+
-+      /* compute (padlen - 1) */
-+      append_math_and_imm_u64(desc, REG1, REG1, IMM, 255);
-+
-+      /* math2 = icvlen + (padlen - 1) + 1 */
-+      append_math_add_imm_u32(desc, REG2, REG1, IMM, authsize + 1);
-+
-+      append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 1);
-+
-+      /* VSOL = payloadlen + icvlen + padlen */
-+      append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, 4);
-+
-+      if (caam_little_end)
-+              append_moveb(desc, MOVE_WAITCOMP |
-+                           MOVE_SRC_MATH0 | MOVE_DEST_MATH0 | 8);
-+
-+      /* update Len field */
-+      append_math_sub(desc, REG0, REG0, REG2, 8);
-+
-+      /* store decrypted payload, icv and padding */
-+      append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
-+
-+      /* VSIL = (payloadlen + icvlen + padlen) - (icvlen + padlen)*/
-+      append_math_sub(desc, VARSEQINLEN, REG3, REG2, 4);
-+
-+      zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
-+                                          JUMP_COND_MATH_Z);
-+
-+      /* send Type, Version and Len(pre ICV) fields to authentication */
-+      append_move(desc, MOVE_WAITCOMP |
-+                  MOVE_SRC_MATH0 | MOVE_DEST_CLASS2INFIFO |
-+                  (3 << MOVE_OFFSET_SHIFT) | 5);
-+
-+      /* outsnooping payload */
-+      append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
-+                           FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LAST2 |
-+                           FIFOLDST_VLF);
-+      skip_zero_jump_cmd = append_jump(desc, JUMP_TEST_ALL | 2);
-+
-+      set_jump_tgt_here(desc, zero_payload_jump_cmd);
-+      /* send Type, Version and Len(pre ICV) fields to authentication */
-+      append_move(desc, MOVE_WAITCOMP | MOVE_AUX_LS |
-+                  MOVE_SRC_MATH0 | MOVE_DEST_CLASS2INFIFO |
-+                  (3 << MOVE_OFFSET_SHIFT) | 5);
-+
-+      set_jump_tgt_here(desc, skip_zero_jump_cmd);
-+      append_math_add(desc, VARSEQINLEN, ZERO, REG2, 4);
-+
-+      /* load icvlen and padlen */
-+      append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG |
-+                           FIFOLD_TYPE_LAST1 | FIFOLDST_VLF);
-+
-+      /* VSIL = (payloadlen + icvlen + padlen) - icvlen + padlen */
-+      append_math_sub(desc, VARSEQINLEN, REG3, REG2, 4);
-+
-+      /*
-+       * Start a new input sequence using the SEQ OUT PTR command options,
-+       * pointer and length used when the current output sequence was defined.
-+       */
-+      if (ps) {
-+              /*
-+               * Move the lower 32 bits of Shared Descriptor address, the
-+               * SEQ OUT PTR command, Output Pointer (2 words) and
-+               * Output Length into math registers.
-+               */
-+              if (caam_little_end)
-+                      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_DESCBUF |
-+                                  MOVE_DEST_MATH0 |
-+                                  (55 * 4 << MOVE_OFFSET_SHIFT) | 20);
-+              else
-+                      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_DESCBUF |
-+                                  MOVE_DEST_MATH0 |
-+                                  (54 * 4 << MOVE_OFFSET_SHIFT) | 20);
-+
-+              /* Transform SEQ OUT PTR command in SEQ IN PTR command */
-+              append_math_and_imm_u32(desc, REG0, REG0, IMM,
-+                                      ~(CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR));
-+              /* Append a JUMP command after the copied fields */
-+              jumpback = CMD_JUMP | (char)-9;
-+              append_load_imm_u32(desc, jumpback, LDST_CLASS_DECO | LDST_IMM |
-+                                  LDST_SRCDST_WORD_DECO_MATH2 |
-+                                  (4 << LDST_OFFSET_SHIFT));
-+              append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 1);
-+              /* Move the updated fields back to the Job Descriptor */
-+              if (caam_little_end)
-+                      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH0 |
-+                                  MOVE_DEST_DESCBUF |
-+                                  (55 * 4 << MOVE_OFFSET_SHIFT) | 24);
-+              else
-+                      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH0 |
-+                                  MOVE_DEST_DESCBUF |
-+                                  (54 * 4 << MOVE_OFFSET_SHIFT) | 24);
-+
-+              /*
-+               * Read the new SEQ IN PTR command, Input Pointer, Input Length
-+               * and then jump back to the next command from the
-+               * Shared Descriptor.
-+               */
-+              append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 6);
-+      } else {
-+              /*
-+               * Move the SEQ OUT PTR command, Output Pointer (1 word) and
-+               * Output Length into math registers.
-+               */
-+              if (caam_little_end)
-+                      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_DESCBUF |
-+                                  MOVE_DEST_MATH0 |
-+                                  (54 * 4 << MOVE_OFFSET_SHIFT) | 12);
-+              else
-+                      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_DESCBUF |
-+                                  MOVE_DEST_MATH0 |
-+                                  (53 * 4 << MOVE_OFFSET_SHIFT) | 12);
-+
-+              /* Transform SEQ OUT PTR command in SEQ IN PTR command */
-+              append_math_and_imm_u64(desc, REG0, REG0, IMM,
-+                                      ~(((u64)(CMD_SEQ_IN_PTR ^
-+                                               CMD_SEQ_OUT_PTR)) << 32));
-+              /* Append a JUMP command after the copied fields */
-+              jumpback = CMD_JUMP | (char)-7;
-+              append_load_imm_u32(desc, jumpback, LDST_CLASS_DECO | LDST_IMM |
-+                                  LDST_SRCDST_WORD_DECO_MATH1 |
-+                                  (4 << LDST_OFFSET_SHIFT));
-+              append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 1);
-+              /* Move the updated fields back to the Job Descriptor */
-+              if (caam_little_end)
-+                      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH0 |
-+                                  MOVE_DEST_DESCBUF |
-+                                  (54 * 4 << MOVE_OFFSET_SHIFT) | 16);
-+              else
-+                      append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH0 |
-+                                  MOVE_DEST_DESCBUF |
-+                                  (53 * 4 << MOVE_OFFSET_SHIFT) | 16);
-+
-+              /*
-+               * Read the new SEQ IN PTR command, Input Pointer, Input Length
-+               * and then jump back to the next command from the
-+               * Shared Descriptor.
-+               */
-+               append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 5);
-+      }
-+
-+      /* skip payload */
-+      append_seq_fifo_load(desc, 0, FIFOLD_CLASS_SKIP | FIFOLDST_VLF);
-+      /* check icv */
-+      append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_ICV |
-+                           FIFOLD_TYPE_LAST2 | authsize);
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "tls dec shdesc@" __stringify(__LINE__) ": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, desc,
-+                     desc_bytes(desc), 1);
-+#endif
-+}
-+EXPORT_SYMBOL(cnstr_shdsc_tls_decap);
-+
-+/**
-  * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
-  * @desc: pointer to buffer used for descriptor construction
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
-+ * @ivsize: initialization vector size
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-+ * @is_qi: true when called from caam/qi
-  */
- void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
--                         unsigned int icvsize)
-+                         unsigned int ivsize, unsigned int icvsize,
-+                         const bool is_qi)
- {
-       u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
-           *zero_assoc_jump_cmd2;
-@@ -621,11 +1075,35 @@ void cnstr_shdsc_gcm_encap(u32 * const d
-       append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-                        OP_ALG_ENCRYPT);
-+      if (is_qi) {
-+              u32 *wait_load_cmd;
-+
-+              /* REG3 = assoclen */
-+              append_seq_load(desc, 4, LDST_CLASS_DECO |
-+                              LDST_SRCDST_WORD_DECO_MATH3 |
-+                              (4 << LDST_OFFSET_SHIFT));
-+
-+              wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-+                                          JUMP_COND_CALM | JUMP_COND_NCP |
-+                                          JUMP_COND_NOP | JUMP_COND_NIP |
-+                                          JUMP_COND_NIFP);
-+              set_jump_tgt_here(desc, wait_load_cmd);
-+
-+              append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
-+                                      ivsize);
-+      } else {
-+              append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
-+                              CAAM_CMD_SZ);
-+      }
-+
-       /* if assoclen + cryptlen is ZERO, skip to ICV write */
--      append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
-       zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
-                                                JUMP_COND_MATH_Z);
-+      if (is_qi)
-+              append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
-+                                   FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
-+
-       /* if assoclen is ZERO, skip reading the assoc data */
-       append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
-       zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
-@@ -657,8 +1135,11 @@ void cnstr_shdsc_gcm_encap(u32 * const d
-       append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
-                            FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
--      /* jump the zero-payload commands */
--      append_jump(desc, JUMP_TEST_ALL | 2);
-+      /* jump to ICV writing */
-+      if (is_qi)
-+              append_jump(desc, JUMP_TEST_ALL | 4);
-+      else
-+              append_jump(desc, JUMP_TEST_ALL | 2);
-       /* zero-payload commands */
-       set_jump_tgt_here(desc, zero_payload_jump_cmd);
-@@ -666,10 +1147,18 @@ void cnstr_shdsc_gcm_encap(u32 * const d
-       /* read assoc data */
-       append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
-                            FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
-+      if (is_qi)
-+              /* jump to ICV writing */
-+              append_jump(desc, JUMP_TEST_ALL | 2);
-       /* There is no input data */
-       set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
-+      if (is_qi)
-+              append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
-+                                   FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
-+                                   FIFOLD_TYPE_LAST1);
-+
-       /* write ICV */
-       append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
-                        LDST_SRCDST_BYTE_CONTEXT);
-@@ -686,10 +1175,13 @@ EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
-  * @desc: pointer to buffer used for descriptor construction
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
-+ * @ivsize: initialization vector size
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-+ * @is_qi: true when called from caam/qi
-  */
- void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
--                         unsigned int icvsize)
-+                         unsigned int ivsize, unsigned int icvsize,
-+                         const bool is_qi)
- {
-       u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
-@@ -710,6 +1202,24 @@ void cnstr_shdsc_gcm_decap(u32 * const d
-       append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-                        OP_ALG_DECRYPT | OP_ALG_ICV_ON);
-+      if (is_qi) {
-+              u32 *wait_load_cmd;
-+
-+              /* REG3 = assoclen */
-+              append_seq_load(desc, 4, LDST_CLASS_DECO |
-+                              LDST_SRCDST_WORD_DECO_MATH3 |
-+                              (4 << LDST_OFFSET_SHIFT));
-+
-+              wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-+                                          JUMP_COND_CALM | JUMP_COND_NCP |
-+                                          JUMP_COND_NOP | JUMP_COND_NIP |
-+                                          JUMP_COND_NIFP);
-+              set_jump_tgt_here(desc, wait_load_cmd);
-+
-+              append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
-+                                   FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
-+      }
-+
-       /* if assoclen is ZERO, skip reading the assoc data */
-       append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
-       zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
-@@ -762,10 +1272,13 @@ EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
-  * @desc: pointer to buffer used for descriptor construction
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
-+ * @ivsize: initialization vector size
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-+ * @is_qi: true when called from caam/qi
-  */
- void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
--                             unsigned int icvsize)
-+                             unsigned int ivsize, unsigned int icvsize,
-+                             const bool is_qi)
- {
-       u32 *key_jump_cmd;
-@@ -786,7 +1299,29 @@ void cnstr_shdsc_rfc4106_encap(u32 * con
-       append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-                        OP_ALG_ENCRYPT);
--      append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
-+      if (is_qi) {
-+              u32 *wait_load_cmd;
-+
-+              /* REG3 = assoclen */
-+              append_seq_load(desc, 4, LDST_CLASS_DECO |
-+                              LDST_SRCDST_WORD_DECO_MATH3 |
-+                              (4 << LDST_OFFSET_SHIFT));
-+
-+              wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-+                                          JUMP_COND_CALM | JUMP_COND_NCP |
-+                                          JUMP_COND_NOP | JUMP_COND_NIP |
-+                                          JUMP_COND_NIFP);
-+              set_jump_tgt_here(desc, wait_load_cmd);
-+
-+              /* Read salt and IV */
-+              append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
-+                                      cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
-+                                      FIFOLD_TYPE_IV);
-+              append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
-+                                   FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
-+      }
-+
-+      append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
-       append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
-       /* Read assoc data */
-@@ -794,7 +1329,7 @@ void cnstr_shdsc_rfc4106_encap(u32 * con
-                            FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
-       /* Skip IV */
--      append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
-+      append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
-       /* Will read cryptlen bytes */
-       append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
-@@ -833,10 +1368,13 @@ EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap)
-  * @desc: pointer to buffer used for descriptor construction
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
-+ * @ivsize: initialization vector size
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-+ * @is_qi: true when called from caam/qi
-  */
- void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
--                             unsigned int icvsize)
-+                             unsigned int ivsize, unsigned int icvsize,
-+                             const bool is_qi)
- {
-       u32 *key_jump_cmd;
-@@ -858,7 +1396,29 @@ void cnstr_shdsc_rfc4106_decap(u32 * con
-       append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-                        OP_ALG_DECRYPT | OP_ALG_ICV_ON);
--      append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
-+      if (is_qi) {
-+              u32 *wait_load_cmd;
-+
-+              /* REG3 = assoclen */
-+              append_seq_load(desc, 4, LDST_CLASS_DECO |
-+                              LDST_SRCDST_WORD_DECO_MATH3 |
-+                              (4 << LDST_OFFSET_SHIFT));
-+
-+              wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-+                                          JUMP_COND_CALM | JUMP_COND_NCP |
-+                                          JUMP_COND_NOP | JUMP_COND_NIP |
-+                                          JUMP_COND_NIFP);
-+              set_jump_tgt_here(desc, wait_load_cmd);
-+
-+              /* Read salt and IV */
-+              append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
-+                                      cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
-+                                      FIFOLD_TYPE_IV);
-+              append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
-+                                   FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
-+      }
-+
-+      append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
-       append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
-       /* Read assoc data */
-@@ -866,7 +1426,7 @@ void cnstr_shdsc_rfc4106_decap(u32 * con
-                            FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
-       /* Skip IV */
--      append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
-+      append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
-       /* Will read cryptlen bytes */
-       append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
-@@ -905,10 +1465,13 @@ EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap)
-  * @desc: pointer to buffer used for descriptor construction
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
-+ * @ivsize: initialization vector size
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-+ * @is_qi: true when called from caam/qi
-  */
- void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
--                             unsigned int icvsize)
-+                             unsigned int ivsize, unsigned int icvsize,
-+                             const bool is_qi)
- {
-       u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
-@@ -929,6 +1492,18 @@ void cnstr_shdsc_rfc4543_encap(u32 * con
-       append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-                        OP_ALG_ENCRYPT);
-+      if (is_qi) {
-+              /* assoclen is not needed, skip it */
-+              append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
-+
-+              /* Read salt and IV */
-+              append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
-+                                      cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
-+                                      FIFOLD_TYPE_IV);
-+              append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
-+                                   FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
-+      }
-+
-       /* assoclen + cryptlen = seqinlen */
-       append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
-@@ -940,7 +1515,7 @@ void cnstr_shdsc_rfc4543_encap(u32 * con
-       read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
-                                   (0x6 << MOVE_LEN_SHIFT));
-       write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
--                                   (0x8 << MOVE_LEN_SHIFT));
-+                                   (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
-       /* Will read assoclen + cryptlen bytes */
-       append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
-@@ -975,10 +1550,13 @@ EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap)
-  * @desc: pointer to buffer used for descriptor construction
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
-+ * @ivsize: initialization vector size
-  * @icvsize: integrity check value (ICV) size (truncated or full)
-+ * @is_qi: true when called from caam/qi
-  */
- void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
--                             unsigned int icvsize)
-+                             unsigned int ivsize, unsigned int icvsize,
-+                             const bool is_qi)
- {
-       u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
-@@ -999,6 +1577,18 @@ void cnstr_shdsc_rfc4543_decap(u32 * con
-       append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-                        OP_ALG_DECRYPT | OP_ALG_ICV_ON);
-+      if (is_qi) {
-+              /* assoclen is not needed, skip it */
-+              append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
-+
-+              /* Read salt and IV */
-+              append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
-+                                      cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
-+                                      FIFOLD_TYPE_IV);
-+              append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
-+                                   FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
-+      }
-+
-       /* assoclen + cryptlen = seqoutlen */
-       append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
-@@ -1010,7 +1600,7 @@ void cnstr_shdsc_rfc4543_decap(u32 * con
-       read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
-                                   (0x6 << MOVE_LEN_SHIFT));
-       write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
--                                   (0x8 << MOVE_LEN_SHIFT));
-+                                   (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
-       /* Will read assoclen + cryptlen bytes */
-       append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
-@@ -1044,6 +1634,138 @@ void cnstr_shdsc_rfc4543_decap(u32 * con
- }
- EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
-+/**
-+ * cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and
-+ *                          IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared
-+ *                          descriptor (non-protocol).
-+ * @desc: pointer to buffer used for descriptor construction
-+ * @cdata: pointer to block cipher transform definitions
-+ *         Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with
-+ *         OP_ALG_AAI_AEAD.
-+ * @adata: pointer to authentication transform definitions
-+ *         Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with
-+ *         OP_ALG_AAI_AEAD.
-+ * @ivsize: initialization vector size
-+ * @icvsize: integrity check value (ICV) size (truncated or full)
-+ * @encap: true if encapsulation, false if decapsulation
-+ * @is_qi: true when called from caam/qi
-+ */
-+void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
-+                          struct alginfo *adata, unsigned int ivsize,
-+                          unsigned int icvsize, const bool encap,
-+                          const bool is_qi)
-+{
-+      u32 *key_jump_cmd, *wait_cmd;
-+      u32 nfifo;
-+      const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE);
-+
-+      /* Note: Context registers are saved. */
-+      init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
-+
-+      /* skip key loading if they are loaded due to sharing */
-+      key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-+                                 JUMP_COND_SHRD);
-+
-+      append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen,
-+                        CLASS_1 | KEY_DEST_CLASS_REG);
-+
-+      /* For IPsec load the salt from keymat in the context register */
-+      if (is_ipsec)
-+              append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4,
-+                                 LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT |
-+                                 4 << LDST_OFFSET_SHIFT);
-+
-+      set_jump_tgt_here(desc, key_jump_cmd);
-+
-+      /* Class 2 and 1 operations: Poly & ChaCha */
-+      if (encap) {
-+              append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
-+                               OP_ALG_ENCRYPT);
-+              append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-+                               OP_ALG_ENCRYPT);
-+      } else {
-+              append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
-+                               OP_ALG_DECRYPT | OP_ALG_ICV_ON);
-+              append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
-+                               OP_ALG_DECRYPT);
-+      }
-+
-+      if (is_qi) {
-+              u32 *wait_load_cmd;
-+              u32 ctx1_iv_off = is_ipsec ? 8 : 4;
-+
-+              /* REG3 = assoclen */
-+              append_seq_load(desc, 4, LDST_CLASS_DECO |
-+                              LDST_SRCDST_WORD_DECO_MATH3 |
-+                              4 << LDST_OFFSET_SHIFT);
-+
-+              wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-+                                          JUMP_COND_CALM | JUMP_COND_NCP |
-+                                          JUMP_COND_NOP | JUMP_COND_NIP |
-+                                          JUMP_COND_NIFP);
-+              set_jump_tgt_here(desc, wait_load_cmd);
-+
-+              append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
-+                              LDST_SRCDST_BYTE_CONTEXT |
-+                              ctx1_iv_off << LDST_OFFSET_SHIFT);
-+      }
-+
-+      /*
-+       * MAGIC with NFIFO
-+       * Read associated data from the input and send them to class1 and
-+       * class2 alignment blocks. From class1 send data to output fifo and
-+       * then write it to memory since we don't need to encrypt AD.
-+       */
-+      nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 |
-+              NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND;
-+      append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB |
-+                          LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3);
-+
-+      append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
-+      append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
-+      append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO |
-+                           FIFOLD_CLASS_CLASS1 | LDST_VLF);
-+      append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK |
-+                      MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3);
-+      append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
-+
-+      /* IPsec - copy IV at the output */
-+      if (is_ipsec)
-+              append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA |
-+                                    0x2 << 25);
-+
-+      wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
-+                             JUMP_COND_NOP | JUMP_TEST_ALL);
-+      set_jump_tgt_here(desc, wait_cmd);
-+
-+      if (encap) {
-+              /* Read and write cryptlen bytes */
-+              append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
-+              append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0,
-+                              CAAM_CMD_SZ);
-+              aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
-+
-+              /* Write ICV */
-+              append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
-+                               LDST_SRCDST_BYTE_CONTEXT);
-+      } else {
-+              /* Read and write cryptlen bytes */
-+              append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
-+              append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0,
-+                              CAAM_CMD_SZ);
-+              aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
-+
-+              /* Load ICV for verification */
-+              append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
-+                                   FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
-+      }
-+
-+      print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ",
-+                           DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
-+                           1);
-+}
-+EXPORT_SYMBOL(cnstr_shdsc_chachapoly);
-+
- /*
-  * For ablkcipher encrypt and decrypt, read from req->src and
-  * write to req->dst
-@@ -1062,7 +1784,8 @@ static inline void ablkcipher_append_src
-  * @desc: pointer to buffer used for descriptor construction
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
-- *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
-+ *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
-+ *                                - OP_ALG_ALGSEL_CHACHA20
-  * @ivsize: initialization vector size
-  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
-  * @ctx1_iv_off: IV offset in CONTEXT1 register
-@@ -1084,7 +1807,7 @@ void cnstr_shdsc_ablkcipher_encap(u32 *
-       /* Load nonce into CONTEXT1 reg */
-       if (is_rfc3686) {
--              u8 *nonce = cdata->key_virt + cdata->keylen;
-+              const u8 *nonce = cdata->key_virt + cdata->keylen;
-               append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
-                                  LDST_CLASS_IND_CCB |
-@@ -1127,7 +1850,8 @@ EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_enc
-  * @desc: pointer to buffer used for descriptor construction
-  * @cdata: pointer to block cipher transform definitions
-  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
-- *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
-+ *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
-+ *                                - OP_ALG_ALGSEL_CHACHA20
-  * @ivsize: initialization vector size
-  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
-  * @ctx1_iv_off: IV offset in CONTEXT1 register
-@@ -1149,7 +1873,7 @@ void cnstr_shdsc_ablkcipher_decap(u32 *
-       /* Load nonce into CONTEXT1 reg */
-       if (is_rfc3686) {
--              u8 *nonce = cdata->key_virt + cdata->keylen;
-+              const u8 *nonce = cdata->key_virt + cdata->keylen;
-               append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
-                                  LDST_CLASS_IND_CCB |
-@@ -1218,7 +1942,7 @@ void cnstr_shdsc_ablkcipher_givencap(u32
-       /* Load Nonce into CONTEXT1 reg */
-       if (is_rfc3686) {
--              u8 *nonce = cdata->key_virt + cdata->keylen;
-+              const u8 *nonce = cdata->key_virt + cdata->keylen;
-               append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
-                                  LDST_CLASS_IND_CCB |
---- a/drivers/crypto/caam/caamalg_desc.h
-+++ b/drivers/crypto/caam/caamalg_desc.h
-@@ -17,6 +17,9 @@
- #define DESC_QI_AEAD_DEC_LEN          (DESC_AEAD_DEC_LEN + 3 * CAAM_CMD_SZ)
- #define DESC_QI_AEAD_GIVENC_LEN               (DESC_AEAD_GIVENC_LEN + 3 * CAAM_CMD_SZ)
-+#define DESC_TLS_BASE                 (4 * CAAM_CMD_SZ)
-+#define DESC_TLS10_ENC_LEN            (DESC_TLS_BASE + 29 * CAAM_CMD_SZ)
-+
- /* Note: Nonce is counted in cdata.keylen */
- #define DESC_AEAD_CTR_RFC3686_LEN     (4 * CAAM_CMD_SZ)
-@@ -27,14 +30,20 @@
- #define DESC_GCM_BASE                 (3 * CAAM_CMD_SZ)
- #define DESC_GCM_ENC_LEN              (DESC_GCM_BASE + 16 * CAAM_CMD_SZ)
- #define DESC_GCM_DEC_LEN              (DESC_GCM_BASE + 12 * CAAM_CMD_SZ)
-+#define DESC_QI_GCM_ENC_LEN           (DESC_GCM_ENC_LEN + 6 * CAAM_CMD_SZ)
-+#define DESC_QI_GCM_DEC_LEN           (DESC_GCM_DEC_LEN + 3 * CAAM_CMD_SZ)
- #define DESC_RFC4106_BASE             (3 * CAAM_CMD_SZ)
- #define DESC_RFC4106_ENC_LEN          (DESC_RFC4106_BASE + 13 * CAAM_CMD_SZ)
- #define DESC_RFC4106_DEC_LEN          (DESC_RFC4106_BASE + 13 * CAAM_CMD_SZ)
-+#define DESC_QI_RFC4106_ENC_LEN               (DESC_RFC4106_ENC_LEN + 5 * CAAM_CMD_SZ)
-+#define DESC_QI_RFC4106_DEC_LEN               (DESC_RFC4106_DEC_LEN + 5 * CAAM_CMD_SZ)
- #define DESC_RFC4543_BASE             (3 * CAAM_CMD_SZ)
- #define DESC_RFC4543_ENC_LEN          (DESC_RFC4543_BASE + 11 * CAAM_CMD_SZ)
- #define DESC_RFC4543_DEC_LEN          (DESC_RFC4543_BASE + 12 * CAAM_CMD_SZ)
-+#define DESC_QI_RFC4543_ENC_LEN               (DESC_RFC4543_ENC_LEN + 4 * CAAM_CMD_SZ)
-+#define DESC_QI_RFC4543_DEC_LEN               (DESC_RFC4543_DEC_LEN + 4 * CAAM_CMD_SZ)
- #define DESC_ABLKCIPHER_BASE          (3 * CAAM_CMD_SZ)
- #define DESC_ABLKCIPHER_ENC_LEN               (DESC_ABLKCIPHER_BASE + \
-@@ -43,46 +52,67 @@
-                                        15 * CAAM_CMD_SZ)
- void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
--                               unsigned int icvsize);
-+                               unsigned int icvsize, int era);
- void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
--                               unsigned int icvsize);
-+                               unsigned int icvsize, int era);
- void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
-                           struct alginfo *adata, unsigned int ivsize,
-                           unsigned int icvsize, const bool is_rfc3686,
-                           u32 *nonce, const u32 ctx1_iv_off,
--                          const bool is_qi);
-+                          const bool is_qi, int era);
- void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
-                           struct alginfo *adata, unsigned int ivsize,
-                           unsigned int icvsize, const bool geniv,
-                           const bool is_rfc3686, u32 *nonce,
--                          const u32 ctx1_iv_off, const bool is_qi);
-+                          const u32 ctx1_iv_off, const bool is_qi, int era);
- void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
-                              struct alginfo *adata, unsigned int ivsize,
-                              unsigned int icvsize, const bool is_rfc3686,
-                              u32 *nonce, const u32 ctx1_iv_off,
--                             const bool is_qi);
-+                             const bool is_qi, int era);
-+
-+void cnstr_shdsc_tls_encap(u32 *const desc, struct alginfo *cdata,
-+                         struct alginfo *adata, unsigned int assoclen,
-+                         unsigned int ivsize, unsigned int authsize,
-+                         unsigned int blocksize, int era);
-+
-+void cnstr_shdsc_tls_decap(u32 *const desc, struct alginfo *cdata,
-+                         struct alginfo *adata, unsigned int assoclen,
-+                         unsigned int ivsize, unsigned int authsize,
-+                         unsigned int blocksize, int era);
- void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
--                         unsigned int icvsize);
-+                         unsigned int ivsize, unsigned int icvsize,
-+                         const bool is_qi);
- void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
--                         unsigned int icvsize);
-+                         unsigned int ivsize, unsigned int icvsize,
-+                         const bool is_qi);
- void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
--                             unsigned int icvsize);
-+                             unsigned int ivsize, unsigned int icvsize,
-+                             const bool is_qi);
- void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
--                             unsigned int icvsize);
-+                             unsigned int ivsize, unsigned int icvsize,
-+                             const bool is_qi);
- void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
--                             unsigned int icvsize);
-+                             unsigned int ivsize, unsigned int icvsize,
-+                             const bool is_qi);
- void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
--                             unsigned int icvsize);
-+                             unsigned int ivsize, unsigned int icvsize,
-+                             const bool is_qi);
-+
-+void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
-+                          struct alginfo *adata, unsigned int ivsize,
-+                          unsigned int icvsize, const bool encap,
-+                          const bool is_qi);
- void cnstr_shdsc_ablkcipher_encap(u32 * const desc, struct alginfo *cdata,
-                                 unsigned int ivsize, const bool is_rfc3686,
---- a/drivers/crypto/caam/caamalg_qi.c
-+++ b/drivers/crypto/caam/caamalg_qi.c
-@@ -7,7 +7,7 @@
-  */
- #include "compat.h"
--
-+#include "ctrl.h"
- #include "regs.h"
- #include "intern.h"
- #include "desc_constr.h"
-@@ -53,6 +53,7 @@ struct caam_ctx {
-       u32 sh_desc_givenc[DESC_MAX_USED_LEN];
-       u8 key[CAAM_MAX_KEY_SIZE];
-       dma_addr_t key_dma;
-+      enum dma_data_direction dir;
-       struct alginfo adata;
-       struct alginfo cdata;
-       unsigned int authsize;
-@@ -74,6 +75,7 @@ static int aead_set_sh_desc(struct crypt
-       const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
-                              OP_ALG_AAI_CTR_MOD128);
-       const bool is_rfc3686 = alg->caam.rfc3686;
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
-       if (!ctx->cdata.keylen || !ctx->authsize)
-               return 0;
-@@ -124,7 +126,7 @@ static int aead_set_sh_desc(struct crypt
-       cnstr_shdsc_aead_encap(ctx->sh_desc_enc, &ctx->cdata, &ctx->adata,
-                              ivsize, ctx->authsize, is_rfc3686, nonce,
--                             ctx1_iv_off, true);
-+                             ctx1_iv_off, true, ctrlpriv->era);
- skip_enc:
-       /* aead_decrypt shared descriptor */
-@@ -149,7 +151,8 @@ skip_enc:
-       cnstr_shdsc_aead_decap(ctx->sh_desc_dec, &ctx->cdata, &ctx->adata,
-                              ivsize, ctx->authsize, alg->caam.geniv,
--                             is_rfc3686, nonce, ctx1_iv_off, true);
-+                             is_rfc3686, nonce, ctx1_iv_off, true,
-+                             ctrlpriv->era);
-       if (!alg->caam.geniv)
-               goto skip_givenc;
-@@ -176,7 +179,7 @@ skip_enc:
-       cnstr_shdsc_aead_givencap(ctx->sh_desc_enc, &ctx->cdata, &ctx->adata,
-                                 ivsize, ctx->authsize, is_rfc3686, nonce,
--                                ctx1_iv_off, true);
-+                                ctx1_iv_off, true, ctrlpriv->era);
- skip_givenc:
-       return 0;
-@@ -197,6 +200,7 @@ static int aead_setkey(struct crypto_aea
- {
-       struct caam_ctx *ctx = crypto_aead_ctx(aead);
-       struct device *jrdev = ctx->jrdev;
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
-       struct crypto_authenc_keys keys;
-       int ret = 0;
-@@ -211,6 +215,27 @@ static int aead_setkey(struct crypto_aea
-                      DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
- #endif
-+      /*
-+       * If DKP is supported, use it in the shared descriptor to generate
-+       * the split key.
-+       */
-+      if (ctrlpriv->era >= 6) {
-+              ctx->adata.keylen = keys.authkeylen;
-+              ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
-+                                                    OP_ALG_ALGSEL_MASK);
-+
-+              if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
-+                      goto badkey;
-+
-+              memcpy(ctx->key, keys.authkey, keys.authkeylen);
-+              memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
-+                     keys.enckeylen);
-+              dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
-+                                         ctx->adata.keylen_pad +
-+                                         keys.enckeylen, ctx->dir);
-+              goto skip_split_key;
-+      }
-+
-       ret = gen_split_key(jrdev, ctx->key, &ctx->adata, keys.authkey,
-                           keys.authkeylen, CAAM_MAX_KEY_SIZE -
-                           keys.enckeylen);
-@@ -220,13 +245,14 @@ static int aead_setkey(struct crypto_aea
-       /* postpend encryption key to auth split key */
-       memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
-       dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
--                                 keys.enckeylen, DMA_TO_DEVICE);
-+                                 keys.enckeylen, ctx->dir);
- #ifdef DEBUG
-       print_hex_dump(KERN_ERR, "ctx.key@" __stringify(__LINE__)": ",
-                      DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
-                      ctx->adata.keylen_pad + keys.enckeylen, 1);
- #endif
-+skip_split_key:
-       ctx->cdata.keylen = keys.enckeylen;
-       ret = aead_set_sh_desc(aead);
-@@ -258,6 +284,468 @@ badkey:
-       return -EINVAL;
- }
-+static int tls_set_sh_desc(struct crypto_aead *tls)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+      unsigned int ivsize = crypto_aead_ivsize(tls);
-+      unsigned int blocksize = crypto_aead_blocksize(tls);
-+      unsigned int assoclen = 13; /* always 13 bytes for TLS */
-+      unsigned int data_len[2];
-+      u32 inl_mask;
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      /*
-+       * TLS 1.0 encrypt shared descriptor
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      data_len[0] = ctx->adata.keylen_pad;
-+      data_len[1] = ctx->cdata.keylen;
-+
-+      if (desc_inline_query(DESC_TLS10_ENC_LEN, DESC_JOB_IO_LEN, data_len,
-+                            &inl_mask, ARRAY_SIZE(data_len)) < 0)
-+              return -EINVAL;
-+
-+      if (inl_mask & 1)
-+              ctx->adata.key_virt = ctx->key;
-+      else
-+              ctx->adata.key_dma = ctx->key_dma;
-+
-+      if (inl_mask & 2)
-+              ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
-+      else
-+              ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
-+
-+      ctx->adata.key_inline = !!(inl_mask & 1);
-+      ctx->cdata.key_inline = !!(inl_mask & 2);
-+
-+      cnstr_shdsc_tls_encap(ctx->sh_desc_enc, &ctx->cdata, &ctx->adata,
-+                            assoclen, ivsize, ctx->authsize, blocksize,
-+                            ctrlpriv->era);
-+
-+      /*
-+       * TLS 1.0 decrypt shared descriptor
-+       * Keys do not fit inline, regardless of algorithms used
-+       */
-+      ctx->adata.key_inline = false;
-+      ctx->adata.key_dma = ctx->key_dma;
-+      ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
-+
-+      cnstr_shdsc_tls_decap(ctx->sh_desc_dec, &ctx->cdata, &ctx->adata,
-+                            assoclen, ivsize, ctx->authsize, blocksize,
-+                            ctrlpriv->era);
-+
-+      return 0;
-+}
-+
-+static int tls_setauthsize(struct crypto_aead *tls, unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+
-+      ctx->authsize = authsize;
-+      tls_set_sh_desc(tls);
-+
-+      return 0;
-+}
-+
-+static int tls_setkey(struct crypto_aead *tls, const u8 *key,
-+                    unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+      struct device *jrdev = ctx->jrdev;
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
-+      struct crypto_authenc_keys keys;
-+      int ret = 0;
-+
-+      if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
-+              goto badkey;
-+
-+#ifdef DEBUG
-+      dev_err(jrdev, "keylen %d enckeylen %d authkeylen %d\n",
-+              keys.authkeylen + keys.enckeylen, keys.enckeylen,
-+              keys.authkeylen);
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+
-+      /*
-+       * If DKP is supported, use it in the shared descriptor to generate
-+       * the split key.
-+       */
-+      if (ctrlpriv->era >= 6) {
-+              ctx->adata.keylen = keys.authkeylen;
-+              ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
-+                                                    OP_ALG_ALGSEL_MASK);
-+
-+              if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
-+                      goto badkey;
-+
-+              memcpy(ctx->key, keys.authkey, keys.authkeylen);
-+              memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
-+                     keys.enckeylen);
-+              dma_sync_single_for_device(jrdev, ctx->key_dma,
-+                                         ctx->adata.keylen_pad +
-+                                         keys.enckeylen, ctx->dir);
-+              goto skip_split_key;
-+      }
-+
-+      ret = gen_split_key(jrdev, ctx->key, &ctx->adata, keys.authkey,
-+                          keys.authkeylen, CAAM_MAX_KEY_SIZE -
-+                          keys.enckeylen);
-+      if (ret)
-+              goto badkey;
-+
-+      /* postpend encryption key to auth split key */
-+      memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
-+      dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
-+                                 keys.enckeylen, ctx->dir);
-+
-+#ifdef DEBUG
-+      dev_err(jrdev, "split keylen %d split keylen padded %d\n",
-+              ctx->adata.keylen, ctx->adata.keylen_pad);
-+      print_hex_dump(KERN_ERR, "ctx.key@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
-+                     ctx->adata.keylen_pad + keys.enckeylen, 1);
-+#endif
-+
-+skip_split_key:
-+      ctx->cdata.keylen = keys.enckeylen;
-+
-+      ret = tls_set_sh_desc(tls);
-+      if (ret)
-+              goto badkey;
-+
-+      /* Now update the driver contexts with the new shared descriptor */
-+      if (ctx->drv_ctx[ENCRYPT]) {
-+              ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
-+                                        ctx->sh_desc_enc);
-+              if (ret) {
-+                      dev_err(jrdev, "driver enc context update failed\n");
-+                      goto badkey;
-+              }
-+      }
-+
-+      if (ctx->drv_ctx[DECRYPT]) {
-+              ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
-+                                        ctx->sh_desc_dec);
-+              if (ret) {
-+                      dev_err(jrdev, "driver dec context update failed\n");
-+                      goto badkey;
-+              }
-+      }
-+
-+      return ret;
-+badkey:
-+      crypto_aead_set_flags(tls, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+      return -EINVAL;
-+}
-+
-+static int gcm_set_sh_desc(struct crypto_aead *aead)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
-+                      ctx->cdata.keylen;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      /*
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_GCM_ENC_LEN) {
-+              ctx->cdata.key_inline = true;
-+              ctx->cdata.key_virt = ctx->key;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      cnstr_shdsc_gcm_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize,
-+                            ctx->authsize, true);
-+
-+      /*
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_GCM_DEC_LEN) {
-+              ctx->cdata.key_inline = true;
-+              ctx->cdata.key_virt = ctx->key;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      cnstr_shdsc_gcm_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize,
-+                            ctx->authsize, true);
-+
-+      return 0;
-+}
-+
-+static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(authenc);
-+
-+      ctx->authsize = authsize;
-+      gcm_set_sh_desc(authenc);
-+
-+      return 0;
-+}
-+
-+static int gcm_setkey(struct crypto_aead *aead,
-+                    const u8 *key, unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *jrdev = ctx->jrdev;
-+      int ret;
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+
-+      memcpy(ctx->key, key, keylen);
-+      dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir);
-+      ctx->cdata.keylen = keylen;
-+
-+      ret = gcm_set_sh_desc(aead);
-+      if (ret)
-+              return ret;
-+
-+      /* Now update the driver contexts with the new shared descriptor */
-+      if (ctx->drv_ctx[ENCRYPT]) {
-+              ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
-+                                        ctx->sh_desc_enc);
-+              if (ret) {
-+                      dev_err(jrdev, "driver enc context update failed\n");
-+                      return ret;
-+              }
-+      }
-+
-+      if (ctx->drv_ctx[DECRYPT]) {
-+              ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
-+                                        ctx->sh_desc_dec);
-+              if (ret) {
-+                      dev_err(jrdev, "driver dec context update failed\n");
-+                      return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int rfc4106_set_sh_desc(struct crypto_aead *aead)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
-+                      ctx->cdata.keylen;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      ctx->cdata.key_virt = ctx->key;
-+
-+      /*
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_RFC4106_ENC_LEN) {
-+              ctx->cdata.key_inline = true;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      cnstr_shdsc_rfc4106_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize,
-+                                ctx->authsize, true);
-+
-+      /*
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_RFC4106_DEC_LEN) {
-+              ctx->cdata.key_inline = true;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      cnstr_shdsc_rfc4106_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize,
-+                                ctx->authsize, true);
-+
-+      return 0;
-+}
-+
-+static int rfc4106_setauthsize(struct crypto_aead *authenc,
-+                             unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(authenc);
-+
-+      ctx->authsize = authsize;
-+      rfc4106_set_sh_desc(authenc);
-+
-+      return 0;
-+}
-+
-+static int rfc4106_setkey(struct crypto_aead *aead,
-+                        const u8 *key, unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *jrdev = ctx->jrdev;
-+      int ret;
-+
-+      if (keylen < 4)
-+              return -EINVAL;
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+
-+      memcpy(ctx->key, key, keylen);
-+      /*
-+       * The last four bytes of the key material are used as the salt value
-+       * in the nonce. Update the AES key length.
-+       */
-+      ctx->cdata.keylen = keylen - 4;
-+      dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
-+                                 ctx->dir);
-+
-+      ret = rfc4106_set_sh_desc(aead);
-+      if (ret)
-+              return ret;
-+
-+      /* Now update the driver contexts with the new shared descriptor */
-+      if (ctx->drv_ctx[ENCRYPT]) {
-+              ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
-+                                        ctx->sh_desc_enc);
-+              if (ret) {
-+                      dev_err(jrdev, "driver enc context update failed\n");
-+                      return ret;
-+              }
-+      }
-+
-+      if (ctx->drv_ctx[DECRYPT]) {
-+              ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
-+                                        ctx->sh_desc_dec);
-+              if (ret) {
-+                      dev_err(jrdev, "driver dec context update failed\n");
-+                      return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int rfc4543_set_sh_desc(struct crypto_aead *aead)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
-+                      ctx->cdata.keylen;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      ctx->cdata.key_virt = ctx->key;
-+
-+      /*
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_RFC4543_ENC_LEN) {
-+              ctx->cdata.key_inline = true;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      cnstr_shdsc_rfc4543_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize,
-+                                ctx->authsize, true);
-+
-+      /*
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_RFC4543_DEC_LEN) {
-+              ctx->cdata.key_inline = true;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      cnstr_shdsc_rfc4543_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize,
-+                                ctx->authsize, true);
-+
-+      return 0;
-+}
-+
-+static int rfc4543_setauthsize(struct crypto_aead *authenc,
-+                             unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(authenc);
-+
-+      ctx->authsize = authsize;
-+      rfc4543_set_sh_desc(authenc);
-+
-+      return 0;
-+}
-+
-+static int rfc4543_setkey(struct crypto_aead *aead,
-+                        const u8 *key, unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *jrdev = ctx->jrdev;
-+      int ret;
-+
-+      if (keylen < 4)
-+              return -EINVAL;
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+
-+      memcpy(ctx->key, key, keylen);
-+      /*
-+       * The last four bytes of the key material are used as the salt value
-+       * in the nonce. Update the AES key length.
-+       */
-+      ctx->cdata.keylen = keylen - 4;
-+      dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
-+                                 ctx->dir);
-+
-+      ret = rfc4543_set_sh_desc(aead);
-+      if (ret)
-+              return ret;
-+
-+      /* Now update the driver contexts with the new shared descriptor */
-+      if (ctx->drv_ctx[ENCRYPT]) {
-+              ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT],
-+                                        ctx->sh_desc_enc);
-+              if (ret) {
-+                      dev_err(jrdev, "driver enc context update failed\n");
-+                      return ret;
-+              }
-+      }
-+
-+      if (ctx->drv_ctx[DECRYPT]) {
-+              ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT],
-+                                        ctx->sh_desc_dec);
-+              if (ret) {
-+                      dev_err(jrdev, "driver dec context update failed\n");
-+                      return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
- static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
-                            const u8 *key, unsigned int keylen)
- {
-@@ -414,6 +902,29 @@ struct aead_edesc {
- };
- /*
-+ * tls_edesc - s/w-extended tls descriptor
-+ * @src_nents: number of segments in input scatterlist
-+ * @dst_nents: number of segments in output scatterlist
-+ * @iv_dma: dma address of iv for checking continuity and link table
-+ * @qm_sg_bytes: length of dma mapped h/w link table
-+ * @tmp: array of scatterlists used by 'scatterwalk_ffwd'
-+ * @qm_sg_dma: bus physical mapped address of h/w link table
-+ * @drv_req: driver-specific request structure
-+ * @sgt: the h/w link table, followed by IV
-+ */
-+struct tls_edesc {
-+      int src_nents;
-+      int dst_nents;
-+      dma_addr_t iv_dma;
-+      int qm_sg_bytes;
-+      dma_addr_t qm_sg_dma;
-+      struct scatterlist tmp[2];
-+      struct scatterlist *dst;
-+      struct caam_drv_req drv_req;
-+      struct qm_sg_entry sgt[0];
-+};
-+
-+/*
-  * ablkcipher_edesc - s/w-extended ablkcipher descriptor
-  * @src_nents: number of segments in input scatterlist
-  * @dst_nents: number of segments in output scatterlist
-@@ -508,6 +1019,19 @@ static void aead_unmap(struct device *de
-       dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE);
- }
-+static void tls_unmap(struct device *dev,
-+                    struct tls_edesc *edesc,
-+                    struct aead_request *req)
-+{
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      int ivsize = crypto_aead_ivsize(aead);
-+
-+      caam_unmap(dev, req->src, edesc->dst, edesc->src_nents,
-+                 edesc->dst_nents, edesc->iv_dma, ivsize,
-+                 edesc->drv_req.drv_ctx->op_type, edesc->qm_sg_dma,
-+                 edesc->qm_sg_bytes);
-+}
-+
- static void ablkcipher_unmap(struct device *dev,
-                            struct ablkcipher_edesc *edesc,
-                            struct ablkcipher_request *req)
-@@ -532,8 +1056,18 @@ static void aead_done(struct caam_drv_re
-       qidev = caam_ctx->qidev;
-       if (unlikely(status)) {
-+              u32 ssrc = status & JRSTA_SSRC_MASK;
-+              u8 err_id = status & JRSTA_CCBERR_ERRID_MASK;
-+
-               caam_jr_strstatus(qidev, status);
--              ecode = -EIO;
-+              /*
-+               * verify hw auth check passed else return -EBADMSG
-+               */
-+              if (ssrc == JRSTA_SSRC_CCB_ERROR &&
-+                  err_id == JRSTA_CCBERR_ERRID_ICVCHK)
-+                      ecode = -EBADMSG;
-+              else
-+                      ecode = -EIO;
-       }
-       edesc = container_of(drv_req, typeof(*edesc), drv_req);
-@@ -647,9 +1181,24 @@ static struct aead_edesc *aead_edesc_all
-       /*
-        * Create S/G table: req->assoclen, [IV,] req->src [, req->dst].
-        * Input is not contiguous.
-+       * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
-+       * the end of the table by allocating more S/G entries. Logic:
-+       * if (src != dst && output S/G)
-+       *      pad output S/G, if needed
-+       * else if (src == dst && S/G)
-+       *      overlapping S/Gs; pad one of them
-+       * else if (input S/G) ...
-+       *      pad input S/G, if needed
-        */
--      qm_sg_ents = 1 + !!ivsize + mapped_src_nents +
--                   (mapped_dst_nents > 1 ? mapped_dst_nents : 0);
-+      qm_sg_ents = 1 + !!ivsize + mapped_src_nents;
-+      if (mapped_dst_nents > 1)
-+              qm_sg_ents += ALIGN(mapped_dst_nents, 4);
-+      else if ((req->src == req->dst) && (mapped_src_nents > 1))
-+              qm_sg_ents = max(ALIGN(qm_sg_ents, 4),
-+                               1 + !!ivsize + ALIGN(mapped_src_nents, 4));
-+      else
-+              qm_sg_ents = ALIGN(qm_sg_ents, 4);
-+
-       sg_table = &edesc->sgt[0];
-       qm_sg_bytes = qm_sg_ents * sizeof(*sg_table);
-       if (unlikely(offsetof(struct aead_edesc, sgt) + qm_sg_bytes + ivsize >
-@@ -785,6 +1334,260 @@ static int aead_decrypt(struct aead_requ
-       return aead_crypt(req, false);
- }
-+static int ipsec_gcm_encrypt(struct aead_request *req)
-+{
-+      if (req->assoclen < 8)
-+              return -EINVAL;
-+
-+      return aead_crypt(req, true);
-+}
-+
-+static int ipsec_gcm_decrypt(struct aead_request *req)
-+{
-+      if (req->assoclen < 8)
-+              return -EINVAL;
-+
-+      return aead_crypt(req, false);
-+}
-+
-+static void tls_done(struct caam_drv_req *drv_req, u32 status)
-+{
-+      struct device *qidev;
-+      struct tls_edesc *edesc;
-+      struct aead_request *aead_req = drv_req->app_ctx;
-+      struct crypto_aead *aead = crypto_aead_reqtfm(aead_req);
-+      struct caam_ctx *caam_ctx = crypto_aead_ctx(aead);
-+      int ecode = 0;
-+
-+      qidev = caam_ctx->qidev;
-+
-+      if (unlikely(status)) {
-+              caam_jr_strstatus(qidev, status);
-+              ecode = -EIO;
-+      }
-+
-+      edesc = container_of(drv_req, typeof(*edesc), drv_req);
-+      tls_unmap(qidev, edesc, aead_req);
-+
-+      aead_request_complete(aead_req, ecode);
-+      qi_cache_free(edesc);
-+}
-+
-+/*
-+ * allocate and map the tls extended descriptor
-+ */
-+static struct tls_edesc *tls_edesc_alloc(struct aead_request *req, bool encrypt)
-+{
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      unsigned int blocksize = crypto_aead_blocksize(aead);
-+      unsigned int padsize, authsize;
-+      struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
-+                                               typeof(*alg), aead);
-+      struct device *qidev = ctx->qidev;
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
-+      struct tls_edesc *edesc;
-+      dma_addr_t qm_sg_dma, iv_dma = 0;
-+      int ivsize = 0;
-+      u8 *iv;
-+      int qm_sg_index, qm_sg_ents = 0, qm_sg_bytes;
-+      int in_len, out_len;
-+      struct qm_sg_entry *sg_table, *fd_sgt;
-+      struct caam_drv_ctx *drv_ctx;
-+      enum optype op_type = encrypt ? ENCRYPT : DECRYPT;
-+      struct scatterlist *dst;
-+
-+      if (encrypt) {
-+              padsize = blocksize - ((req->cryptlen + ctx->authsize) %
-+                                      blocksize);
-+              authsize = ctx->authsize + padsize;
-+      } else {
-+              authsize = ctx->authsize;
-+      }
-+
-+      drv_ctx = get_drv_ctx(ctx, op_type);
-+      if (unlikely(IS_ERR_OR_NULL(drv_ctx)))
-+              return (struct tls_edesc *)drv_ctx;
-+
-+      /* allocate space for base edesc, link tables and IV */
-+      edesc = qi_cache_alloc(GFP_DMA | flags);
-+      if (unlikely(!edesc)) {
-+              dev_err(qidev, "could not allocate extended descriptor\n");
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      if (likely(req->src == req->dst)) {
-+              src_nents = sg_nents_for_len(req->src, req->assoclen +
-+                                           req->cryptlen +
-+                                           (encrypt ? authsize : 0));
-+              if (unlikely(src_nents < 0)) {
-+                      dev_err(qidev, "Insufficient bytes (%d) in src S/G\n",
-+                              req->assoclen + req->cryptlen +
-+                              (encrypt ? authsize : 0));
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(src_nents);
-+              }
-+
-+              mapped_src_nents = dma_map_sg(qidev, req->src, src_nents,
-+                                            DMA_BIDIRECTIONAL);
-+              if (unlikely(!mapped_src_nents)) {
-+                      dev_err(qidev, "unable to map source\n");
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+              dst = req->dst;
-+      } else {
-+              src_nents = sg_nents_for_len(req->src, req->assoclen +
-+                                           req->cryptlen);
-+              if (unlikely(src_nents < 0)) {
-+                      dev_err(qidev, "Insufficient bytes (%d) in src S/G\n",
-+                              req->assoclen + req->cryptlen);
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(src_nents);
-+              }
-+
-+              dst = scatterwalk_ffwd(edesc->tmp, req->dst, req->assoclen);
-+              dst_nents = sg_nents_for_len(dst, req->cryptlen +
-+                                           (encrypt ? authsize : 0));
-+              if (unlikely(dst_nents < 0)) {
-+                      dev_err(qidev, "Insufficient bytes (%d) in dst S/G\n",
-+                              req->cryptlen +
-+                              (encrypt ? authsize : 0));
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(dst_nents);
-+              }
-+
-+              if (src_nents) {
-+                      mapped_src_nents = dma_map_sg(qidev, req->src,
-+                                                    src_nents, DMA_TO_DEVICE);
-+                      if (unlikely(!mapped_src_nents)) {
-+                              dev_err(qidev, "unable to map source\n");
-+                              qi_cache_free(edesc);
-+                              return ERR_PTR(-ENOMEM);
-+                      }
-+              } else {
-+                      mapped_src_nents = 0;
-+              }
-+
-+              mapped_dst_nents = dma_map_sg(qidev, dst, dst_nents,
-+                                            DMA_FROM_DEVICE);
-+              if (unlikely(!mapped_dst_nents)) {
-+                      dev_err(qidev, "unable to map destination\n");
-+                      dma_unmap_sg(qidev, req->src, src_nents, DMA_TO_DEVICE);
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+      }
-+
-+      /*
-+       * Create S/G table: IV, src, dst.
-+       * Input is not contiguous.
-+       */
-+      qm_sg_ents = 1 + mapped_src_nents +
-+                   (mapped_dst_nents > 1 ? mapped_dst_nents : 0);
-+      sg_table = &edesc->sgt[0];
-+      qm_sg_bytes = qm_sg_ents * sizeof(*sg_table);
-+
-+      ivsize = crypto_aead_ivsize(aead);
-+      iv = (u8 *)(sg_table + qm_sg_ents);
-+      /* Make sure IV is located in a DMAable area */
-+      memcpy(iv, req->iv, ivsize);
-+      iv_dma = dma_map_single(qidev, iv, ivsize, DMA_TO_DEVICE);
-+      if (dma_mapping_error(qidev, iv_dma)) {
-+              dev_err(qidev, "unable to map IV\n");
-+              caam_unmap(qidev, req->src, dst, src_nents, dst_nents, 0, 0, 0,
-+                         0, 0);
-+              qi_cache_free(edesc);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      edesc->src_nents = src_nents;
-+      edesc->dst_nents = dst_nents;
-+      edesc->dst = dst;
-+      edesc->iv_dma = iv_dma;
-+      edesc->drv_req.app_ctx = req;
-+      edesc->drv_req.cbk = tls_done;
-+      edesc->drv_req.drv_ctx = drv_ctx;
-+
-+      dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0);
-+      qm_sg_index = 1;
-+
-+      sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table + qm_sg_index, 0);
-+      qm_sg_index += mapped_src_nents;
-+
-+      if (mapped_dst_nents > 1)
-+              sg_to_qm_sg_last(dst, mapped_dst_nents, sg_table +
-+                               qm_sg_index, 0);
-+
-+      qm_sg_dma = dma_map_single(qidev, sg_table, qm_sg_bytes, DMA_TO_DEVICE);
-+      if (dma_mapping_error(qidev, qm_sg_dma)) {
-+              dev_err(qidev, "unable to map S/G table\n");
-+              caam_unmap(qidev, req->src, dst, src_nents, dst_nents, iv_dma,
-+                         ivsize, op_type, 0, 0);
-+              qi_cache_free(edesc);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      edesc->qm_sg_dma = qm_sg_dma;
-+      edesc->qm_sg_bytes = qm_sg_bytes;
-+
-+      out_len = req->cryptlen + (encrypt ? authsize : 0);
-+      in_len = ivsize + req->assoclen + req->cryptlen;
-+
-+      fd_sgt = &edesc->drv_req.fd_sgt[0];
-+
-+      dma_to_qm_sg_one_last_ext(&fd_sgt[1], qm_sg_dma, in_len, 0);
-+
-+      if (req->dst == req->src)
-+              dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma +
-+                                  (sg_nents_for_len(req->src, req->assoclen) +
-+                                   1) * sizeof(*sg_table), out_len, 0);
-+      else if (mapped_dst_nents == 1)
-+              dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(dst), out_len, 0);
-+      else
-+              dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + sizeof(*sg_table) *
-+                                   qm_sg_index, out_len, 0);
-+
-+      return edesc;
-+}
-+
-+static int tls_crypt(struct aead_request *req, bool encrypt)
-+{
-+      struct tls_edesc *edesc;
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      int ret;
-+
-+      if (unlikely(caam_congested))
-+              return -EAGAIN;
-+
-+      edesc = tls_edesc_alloc(req, encrypt);
-+      if (IS_ERR_OR_NULL(edesc))
-+              return PTR_ERR(edesc);
-+
-+      ret = caam_qi_enqueue(ctx->qidev, &edesc->drv_req);
-+      if (!ret) {
-+              ret = -EINPROGRESS;
-+      } else {
-+              tls_unmap(ctx->qidev, edesc, req);
-+              qi_cache_free(edesc);
-+      }
-+
-+      return ret;
-+}
-+
-+static int tls_encrypt(struct aead_request *req)
-+{
-+      return tls_crypt(req, true);
-+}
-+
-+static int tls_decrypt(struct aead_request *req)
-+{
-+      return tls_crypt(req, false);
-+}
-+
- static void ablkcipher_done(struct caam_drv_req *drv_req, u32 status)
- {
-       struct ablkcipher_edesc *edesc;
-@@ -900,7 +1703,24 @@ static struct ablkcipher_edesc *ablkciph
-       qm_sg_ents = 1 + mapped_src_nents;
-       dst_sg_idx = qm_sg_ents;
--      qm_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
-+      /*
-+       * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
-+       * the end of the table by allocating more S/G entries. Logic:
-+       * if (src != dst && output S/G)
-+       *      pad output S/G, if needed
-+       * else if (src == dst && S/G)
-+       *      overlapping S/Gs; pad one of them
-+       * else if (input S/G) ...
-+       *      pad input S/G, if needed
-+       */
-+      if (mapped_dst_nents > 1)
-+              qm_sg_ents += ALIGN(mapped_dst_nents, 4);
-+      else if ((req->src == req->dst) && (mapped_src_nents > 1))
-+              qm_sg_ents = max(ALIGN(qm_sg_ents, 4),
-+                               1 + ALIGN(mapped_src_nents, 4));
-+      else
-+              qm_sg_ents = ALIGN(qm_sg_ents, 4);
-+
-       qm_sg_bytes = qm_sg_ents * sizeof(struct qm_sg_entry);
-       if (unlikely(offsetof(struct ablkcipher_edesc, sgt) + qm_sg_bytes +
-                    ivsize > CAAM_QI_MEMCACHE_SIZE)) {
-@@ -1308,6 +2128,61 @@ static struct caam_alg_template driver_a
- };
- static struct caam_aead_alg driver_aeads[] = {
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "rfc4106(gcm(aes))",
-+                              .cra_driver_name = "rfc4106-gcm-aes-caam-qi",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = rfc4106_setkey,
-+                      .setauthsize = rfc4106_setauthsize,
-+                      .encrypt = ipsec_gcm_encrypt,
-+                      .decrypt = ipsec_gcm_decrypt,
-+                      .ivsize = 8,
-+                      .maxauthsize = AES_BLOCK_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "rfc4543(gcm(aes))",
-+                              .cra_driver_name = "rfc4543-gcm-aes-caam-qi",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = rfc4543_setkey,
-+                      .setauthsize = rfc4543_setauthsize,
-+                      .encrypt = ipsec_gcm_encrypt,
-+                      .decrypt = ipsec_gcm_decrypt,
-+                      .ivsize = 8,
-+                      .maxauthsize = AES_BLOCK_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
-+              },
-+      },
-+      /* Galois Counter Mode */
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "gcm(aes)",
-+                              .cra_driver_name = "gcm-aes-caam-qi",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = gcm_setkey,
-+                      .setauthsize = gcm_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = 12,
-+                      .maxauthsize = AES_BLOCK_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
-+              }
-+      },
-       /* single-pass ipsec_esp descriptor */
-       {
-               .aead = {
-@@ -2118,6 +2993,26 @@ static struct caam_aead_alg driver_aeads
-                       .geniv = true,
-               }
-       },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "tls10(hmac(sha1),cbc(aes))",
-+                              .cra_driver_name = "tls10-hmac-sha1-cbc-aes-caam-qi",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = tls_setkey,
-+                      .setauthsize = tls_setauthsize,
-+                      .encrypt = tls_encrypt,
-+                      .decrypt = tls_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              }
-+      }
- };
- struct caam_crypto_alg {
-@@ -2126,9 +3021,21 @@ struct caam_crypto_alg {
-       struct caam_alg_entry caam;
- };
--static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam)
-+static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
-+                         bool uses_dkp)
- {
-       struct caam_drv_private *priv;
-+      struct device *dev;
-+      /* Digest sizes for MD5, SHA1, SHA-224, SHA-256, SHA-384, SHA-512 */
-+      static const u8 digest_size[] = {
-+              MD5_DIGEST_SIZE,
-+              SHA1_DIGEST_SIZE,
-+              SHA224_DIGEST_SIZE,
-+              SHA256_DIGEST_SIZE,
-+              SHA384_DIGEST_SIZE,
-+              SHA512_DIGEST_SIZE
-+      };
-+      u8 op_id;
-       /*
-        * distribute tfms across job rings to ensure in-order
-@@ -2140,10 +3047,19 @@ static int caam_init_common(struct caam_
-               return PTR_ERR(ctx->jrdev);
-       }
--      ctx->key_dma = dma_map_single(ctx->jrdev, ctx->key, sizeof(ctx->key),
--                                    DMA_TO_DEVICE);
--      if (dma_mapping_error(ctx->jrdev, ctx->key_dma)) {
--              dev_err(ctx->jrdev, "unable to map key\n");
-+      priv = dev_get_drvdata(ctx->jrdev->parent);
-+      if (priv->era >= 6 && uses_dkp) {
-+              ctx->dir = DMA_BIDIRECTIONAL;
-+              dev = ctx->jrdev->parent;
-+      } else {
-+              ctx->dir = DMA_TO_DEVICE;
-+              dev = ctx->jrdev;
-+      }
-+
-+      ctx->key_dma = dma_map_single(dev, ctx->key, sizeof(ctx->key),
-+                                    ctx->dir);
-+      if (dma_mapping_error(dev, ctx->key_dma)) {
-+              dev_err(dev, "unable to map key\n");
-               caam_jr_free(ctx->jrdev);
-               return -ENOMEM;
-       }
-@@ -2152,8 +3068,23 @@ static int caam_init_common(struct caam_
-       ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
-       ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
--      priv = dev_get_drvdata(ctx->jrdev->parent);
--      ctx->qidev = priv->qidev;
-+      if (ctx->adata.algtype) {
-+              op_id = (ctx->adata.algtype & OP_ALG_ALGSEL_SUBMASK)
-+                              >> OP_ALG_ALGSEL_SHIFT;
-+              if (op_id < ARRAY_SIZE(digest_size)) {
-+                      ctx->authsize = digest_size[op_id];
-+              } else {
-+                      dev_err(ctx->jrdev,
-+                              "incorrect op_id %d; must be less than %zu\n",
-+                              op_id, ARRAY_SIZE(digest_size));
-+                      caam_jr_free(ctx->jrdev);
-+                      return -EINVAL;
-+              }
-+      } else {
-+              ctx->authsize = 0;
-+      }
-+
-+      ctx->qidev = ctx->jrdev->parent;
-       spin_lock_init(&ctx->lock);
-       ctx->drv_ctx[ENCRYPT] = NULL;
-@@ -2170,7 +3101,7 @@ static int caam_cra_init(struct crypto_t
-                                                       crypto_alg);
-       struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
--      return caam_init_common(ctx, &caam_alg->caam);
-+      return caam_init_common(ctx, &caam_alg->caam, false);
- }
- static int caam_aead_init(struct crypto_aead *tfm)
-@@ -2180,17 +3111,25 @@ static int caam_aead_init(struct crypto_
-                                                     aead);
-       struct caam_ctx *ctx = crypto_aead_ctx(tfm);
--      return caam_init_common(ctx, &caam_alg->caam);
-+      return caam_init_common(ctx, &caam_alg->caam,
-+                              (alg->setkey == aead_setkey) ||
-+                              (alg->setkey == tls_setkey));
- }
- static void caam_exit_common(struct caam_ctx *ctx)
- {
-+      struct device *dev;
-+
-       caam_drv_ctx_rel(ctx->drv_ctx[ENCRYPT]);
-       caam_drv_ctx_rel(ctx->drv_ctx[DECRYPT]);
-       caam_drv_ctx_rel(ctx->drv_ctx[GIVENCRYPT]);
--      dma_unmap_single(ctx->jrdev, ctx->key_dma, sizeof(ctx->key),
--                       DMA_TO_DEVICE);
-+      if (ctx->dir == DMA_BIDIRECTIONAL)
-+              dev = ctx->jrdev->parent;
-+      else
-+              dev = ctx->jrdev;
-+
-+      dma_unmap_single(dev, ctx->key_dma, sizeof(ctx->key), ctx->dir);
-       caam_jr_free(ctx->jrdev);
- }
-@@ -2206,7 +3145,7 @@ static void caam_aead_exit(struct crypto
- }
- static struct list_head alg_list;
--static void __exit caam_qi_algapi_exit(void)
-+void caam_qi_algapi_exit(void)
- {
-       struct caam_crypto_alg *t_alg, *n;
-       int i;
-@@ -2282,53 +3221,48 @@ static void caam_aead_alg_init(struct ca
-       alg->exit = caam_aead_exit;
- }
--static int __init caam_qi_algapi_init(void)
-+int caam_qi_algapi_init(struct device *ctrldev)
- {
--      struct device_node *dev_node;
--      struct platform_device *pdev;
--      struct device *ctrldev;
--      struct caam_drv_private *priv;
-+      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
-       int i = 0, err = 0;
--      u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
-+      u32 aes_vid, aes_inst, des_inst, md_vid, md_inst;
-       unsigned int md_limit = SHA512_DIGEST_SIZE;
-       bool registered = false;
--      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
--      if (!dev_node) {
--              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
--              if (!dev_node)
--                      return -ENODEV;
--      }
--
--      pdev = of_find_device_by_node(dev_node);
--      of_node_put(dev_node);
--      if (!pdev)
--              return -ENODEV;
--
--      ctrldev = &pdev->dev;
--      priv = dev_get_drvdata(ctrldev);
--
--      /*
--       * If priv is NULL, it's probably because the caam driver wasn't
--       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
--       */
--      if (!priv || !priv->qi_present)
--              return -ENODEV;
--
-       INIT_LIST_HEAD(&alg_list);
-       /*
-        * Register crypto algorithms the device supports.
-        * First, detect presence and attributes of DES, AES, and MD blocks.
-        */
--      cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
--      cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
--      des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
--      aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
--      md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
-+      if (priv->era < 10) {
-+              u32 cha_vid, cha_inst;
-+
-+              cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
-+              aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
-+              md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
-+
-+              cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
-+              des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
-+                         CHA_ID_LS_DES_SHIFT;
-+              aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
-+              md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
-+      } else {
-+              u32 aesa, mdha;
-+
-+              aesa = rd_reg32(&priv->ctrl->vreg.aesa);
-+              mdha = rd_reg32(&priv->ctrl->vreg.mdha);
-+
-+              aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
-+              md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
-+
-+              des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
-+              aes_inst = aesa & CHA_VER_NUM_MASK;
-+              md_inst = mdha & CHA_VER_NUM_MASK;
-+      }
-       /* If MD is present, limit digest size based on LP256 */
--      if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
-+      if (md_inst && md_vid  == CHA_VER_VID_MD_LP256)
-               md_limit = SHA256_DIGEST_SIZE;
-       for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
-@@ -2349,14 +3283,14 @@ static int __init caam_qi_algapi_init(vo
-               t_alg = caam_alg_alloc(alg);
-               if (IS_ERR(t_alg)) {
-                       err = PTR_ERR(t_alg);
--                      dev_warn(priv->qidev, "%s alg allocation failed\n",
-+                      dev_warn(ctrldev, "%s alg allocation failed\n",
-                                alg->driver_name);
-                       continue;
-               }
-               err = crypto_register_alg(&t_alg->crypto_alg);
-               if (err) {
--                      dev_warn(priv->qidev, "%s alg registration failed\n",
-+                      dev_warn(ctrldev, "%s alg registration failed\n",
-                                t_alg->crypto_alg.cra_driver_name);
-                       kfree(t_alg);
-                       continue;
-@@ -2388,8 +3322,7 @@ static int __init caam_qi_algapi_init(vo
-                * Check support for AES algorithms not available
-                * on LP devices.
-                */
--              if (((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP) &&
--                  (alg_aai == OP_ALG_AAI_GCM))
-+              if (aes_vid  == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM)
-                       continue;
-               /*
-@@ -2414,14 +3347,7 @@ static int __init caam_qi_algapi_init(vo
-       }
-       if (registered)
--              dev_info(priv->qidev, "algorithms registered in /proc/crypto\n");
-+              dev_info(ctrldev, "algorithms registered in /proc/crypto\n");
-       return err;
- }
--
--module_init(caam_qi_algapi_init);
--module_exit(caam_qi_algapi_exit);
--
--MODULE_LICENSE("GPL");
--MODULE_DESCRIPTION("Support for crypto API using CAAM-QI backend");
--MODULE_AUTHOR("Freescale Semiconductor");
---- /dev/null
-+++ b/drivers/crypto/caam/caamalg_qi2.c
-@@ -0,0 +1,5843 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor Inc.
-+ * Copyright 2017-2018 NXP
-+ */
-+
-+#include <linux/fsl/mc.h>
-+#include "compat.h"
-+#include "regs.h"
-+#include "caamalg_qi2.h"
-+#include "dpseci_cmd.h"
-+#include "desc_constr.h"
-+#include "error.h"
-+#include "sg_sw_sec4.h"
-+#include "sg_sw_qm2.h"
-+#include "key_gen.h"
-+#include "caamalg_desc.h"
-+#include "caamhash_desc.h"
-+#include "../../../drivers/staging/fsl-mc/include/dpaa2-io.h"
-+#include "../../../drivers/staging/fsl-mc/include/dpaa2-fd.h"
-+
-+#define CAAM_CRA_PRIORITY     2000
-+
-+/* max key is sum of AES_MAX_KEY_SIZE, max split key size */
-+#define CAAM_MAX_KEY_SIZE     (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE + \
-+                               SHA512_DIGEST_SIZE * 2)
-+
-+/*
-+ * This is a a cache of buffers, from which the users of CAAM QI driver
-+ * can allocate short buffers. It's speedier than doing kmalloc on the hotpath.
-+ * NOTE: A more elegant solution would be to have some headroom in the frames
-+ *       being processed. This can be added by the dpaa2-eth driver. This would
-+ *       pose a problem for userspace application processing which cannot
-+ *       know of this limitation. So for now, this will work.
-+ * NOTE: The memcache is SMP-safe. No need to handle spinlocks in-here
-+ */
-+static struct kmem_cache *qi_cache;
-+
-+struct caam_alg_entry {
-+      struct device *dev;
-+      int class1_alg_type;
-+      int class2_alg_type;
-+      bool rfc3686;
-+      bool geniv;
-+};
-+
-+struct caam_aead_alg {
-+      struct aead_alg aead;
-+      struct caam_alg_entry caam;
-+      bool registered;
-+};
-+
-+struct caam_skcipher_alg {
-+      struct skcipher_alg skcipher;
-+      struct caam_alg_entry caam;
-+      bool registered;
-+};
-+
-+/**
-+ * caam_ctx - per-session context
-+ * @flc: Flow Contexts array
-+ * @key:  virtual address of the key(s): [authentication key], encryption key
-+ * @flc_dma: I/O virtual addresses of the Flow Contexts
-+ * @key_dma: I/O virtual address of the key
-+ * @dir: DMA direction for mapping key and Flow Contexts
-+ * @dev: dpseci device
-+ * @adata: authentication algorithm details
-+ * @cdata: encryption algorithm details
-+ * @authsize: authentication tag (a.k.a. ICV / MAC) size
-+ */
-+struct caam_ctx {
-+      struct caam_flc flc[NUM_OP];
-+      u8 key[CAAM_MAX_KEY_SIZE];
-+      dma_addr_t flc_dma[NUM_OP];
-+      dma_addr_t key_dma;
-+      enum dma_data_direction dir;
-+      struct device *dev;
-+      struct alginfo adata;
-+      struct alginfo cdata;
-+      unsigned int authsize;
-+};
-+
-+void *dpaa2_caam_iova_to_virt(struct dpaa2_caam_priv *priv,
-+                            dma_addr_t iova_addr)
-+{
-+      phys_addr_t phys_addr;
-+
-+      phys_addr = priv->domain ? iommu_iova_to_phys(priv->domain, iova_addr) :
-+                                 iova_addr;
-+
-+      return phys_to_virt(phys_addr);
-+}
-+
-+/*
-+ * qi_cache_zalloc - Allocate buffers from CAAM-QI cache
-+ *
-+ * Allocate data on the hotpath. Instead of using kzalloc, one can use the
-+ * services of the CAAM QI memory cache (backed by kmem_cache). The buffers
-+ * will have a size of CAAM_QI_MEMCACHE_SIZE, which should be sufficient for
-+ * hosting 16 SG entries.
-+ *
-+ * @flags - flags that would be used for the equivalent kmalloc(..) call
-+ *
-+ * Returns a pointer to a retrieved buffer on success or NULL on failure.
-+ */
-+static inline void *qi_cache_zalloc(gfp_t flags)
-+{
-+      return kmem_cache_zalloc(qi_cache, flags);
-+}
-+
-+/*
-+ * qi_cache_free - Frees buffers allocated from CAAM-QI cache
-+ *
-+ * @obj - buffer previously allocated by qi_cache_zalloc
-+ *
-+ * No checking is being done, the call is a passthrough call to
-+ * kmem_cache_free(...)
-+ */
-+static inline void qi_cache_free(void *obj)
-+{
-+      kmem_cache_free(qi_cache, obj);
-+}
-+
-+static struct caam_request *to_caam_req(struct crypto_async_request *areq)
-+{
-+      switch (crypto_tfm_alg_type(areq->tfm)) {
-+      case CRYPTO_ALG_TYPE_SKCIPHER:
-+              return skcipher_request_ctx(skcipher_request_cast(areq));
-+      case CRYPTO_ALG_TYPE_AEAD:
-+              return aead_request_ctx(container_of(areq, struct aead_request,
-+                                                   base));
-+      case CRYPTO_ALG_TYPE_AHASH:
-+              return ahash_request_ctx(ahash_request_cast(areq));
-+      default:
-+              return ERR_PTR(-EINVAL);
-+      }
-+}
-+
-+static void caam_unmap(struct device *dev, struct scatterlist *src,
-+                     struct scatterlist *dst, int src_nents,
-+                     int dst_nents, dma_addr_t iv_dma, int ivsize,
-+                     dma_addr_t qm_sg_dma, int qm_sg_bytes)
-+{
-+      if (dst != src) {
-+              if (src_nents)
-+                      dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
-+              dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
-+      } else {
-+              dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
-+      }
-+
-+      if (iv_dma)
-+              dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
-+
-+      if (qm_sg_bytes)
-+              dma_unmap_single(dev, qm_sg_dma, qm_sg_bytes, DMA_TO_DEVICE);
-+}
-+
-+static int aead_set_sh_desc(struct crypto_aead *aead)
-+{
-+      struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
-+                                               typeof(*alg), aead);
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      struct device *dev = ctx->dev;
-+      struct dpaa2_caam_priv *priv = dev_get_drvdata(dev);
-+      struct caam_flc *flc;
-+      u32 *desc;
-+      u32 ctx1_iv_off = 0;
-+      u32 *nonce = NULL;
-+      unsigned int data_len[2];
-+      u32 inl_mask;
-+      const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
-+                             OP_ALG_AAI_CTR_MOD128);
-+      const bool is_rfc3686 = alg->caam.rfc3686;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      /*
-+       * AES-CTR needs to load IV in CONTEXT1 reg
-+       * at an offset of 128bits (16bytes)
-+       * CONTEXT1[255:128] = IV
-+       */
-+      if (ctr_mode)
-+              ctx1_iv_off = 16;
-+
-+      /*
-+       * RFC3686 specific:
-+       *      CONTEXT1[255:128] = {NONCE, IV, COUNTER}
-+       */
-+      if (is_rfc3686) {
-+              ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
-+              nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
-+                              ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
-+      }
-+
-+      data_len[0] = ctx->adata.keylen_pad;
-+      data_len[1] = ctx->cdata.keylen;
-+
-+      /* aead_encrypt shared descriptor */
-+      if (desc_inline_query((alg->caam.geniv ? DESC_QI_AEAD_GIVENC_LEN :
-+                                               DESC_QI_AEAD_ENC_LEN) +
-+                            (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
-+                            DESC_JOB_IO_LEN, data_len, &inl_mask,
-+                            ARRAY_SIZE(data_len)) < 0)
-+              return -EINVAL;
-+
-+      if (inl_mask & 1)
-+              ctx->adata.key_virt = ctx->key;
-+      else
-+              ctx->adata.key_dma = ctx->key_dma;
-+
-+      if (inl_mask & 2)
-+              ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
-+      else
-+              ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
-+
-+      ctx->adata.key_inline = !!(inl_mask & 1);
-+      ctx->cdata.key_inline = !!(inl_mask & 2);
-+
-+      flc = &ctx->flc[ENCRYPT];
-+      desc = flc->sh_desc;
-+
-+      if (alg->caam.geniv)
-+              cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata,
-+                                        ivsize, ctx->authsize, is_rfc3686,
-+                                        nonce, ctx1_iv_off, true,
-+                                        priv->sec_attr.era);
-+      else
-+              cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata,
-+                                     ivsize, ctx->authsize, is_rfc3686, nonce,
-+                                     ctx1_iv_off, true, priv->sec_attr.era);
-+
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      /* aead_decrypt shared descriptor */
-+      if (desc_inline_query(DESC_QI_AEAD_DEC_LEN +
-+                            (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
-+                            DESC_JOB_IO_LEN, data_len, &inl_mask,
-+                            ARRAY_SIZE(data_len)) < 0)
-+              return -EINVAL;
-+
-+      if (inl_mask & 1)
-+              ctx->adata.key_virt = ctx->key;
-+      else
-+              ctx->adata.key_dma = ctx->key_dma;
-+
-+      if (inl_mask & 2)
-+              ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
-+      else
-+              ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
-+
-+      ctx->adata.key_inline = !!(inl_mask & 1);
-+      ctx->cdata.key_inline = !!(inl_mask & 2);
-+
-+      flc = &ctx->flc[DECRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata,
-+                             ivsize, ctx->authsize, alg->caam.geniv,
-+                             is_rfc3686, nonce, ctx1_iv_off, true,
-+                             priv->sec_attr.era);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      return 0;
-+}
-+
-+static int aead_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(authenc);
-+
-+      ctx->authsize = authsize;
-+      aead_set_sh_desc(authenc);
-+
-+      return 0;
-+}
-+
-+struct split_key_sh_result {
-+      struct completion completion;
-+      int err;
-+      struct device *dev;
-+};
-+
-+static void split_key_sh_done(void *cbk_ctx, u32 err)
-+{
-+      struct split_key_sh_result *res = cbk_ctx;
-+
-+#ifdef DEBUG
-+      dev_err(res->dev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
-+#endif
-+
-+      if (err)
-+              caam_qi2_strstatus(res->dev, err);
-+
-+      res->err = err;
-+      complete(&res->completion);
-+}
-+
-+static int aead_setkey(struct crypto_aead *aead, const u8 *key,
-+                     unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *dev = ctx->dev;
-+      struct crypto_authenc_keys keys;
-+
-+      if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
-+              goto badkey;
-+
-+#ifdef DEBUG
-+      dev_err(dev, "keylen %d enckeylen %d authkeylen %d\n",
-+              keys.authkeylen + keys.enckeylen, keys.enckeylen,
-+              keys.authkeylen);
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+
-+      ctx->adata.keylen = keys.authkeylen;
-+      ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
-+                                            OP_ALG_ALGSEL_MASK);
-+
-+      if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
-+              goto badkey;
-+
-+      memcpy(ctx->key, keys.authkey, keys.authkeylen);
-+      memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
-+      dma_sync_single_for_device(dev, ctx->key_dma, ctx->adata.keylen_pad +
-+                                 keys.enckeylen, ctx->dir);
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "ctx.key@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
-+                     ctx->adata.keylen_pad + keys.enckeylen, 1);
-+#endif
-+
-+      ctx->cdata.keylen = keys.enckeylen;
-+
-+      return aead_set_sh_desc(aead);
-+badkey:
-+      crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+      return -EINVAL;
-+}
-+
-+static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
-+                                         bool encrypt)
-+{
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      struct caam_request *req_ctx = aead_request_ctx(req);
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
-+                                               typeof(*alg), aead);
-+      struct device *dev = ctx->dev;
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
-+      struct aead_edesc *edesc;
-+      dma_addr_t qm_sg_dma, iv_dma = 0;
-+      int ivsize = 0;
-+      unsigned int authsize = ctx->authsize;
-+      int qm_sg_index = 0, qm_sg_nents = 0, qm_sg_bytes;
-+      int in_len, out_len;
-+      struct dpaa2_sg_entry *sg_table;
-+
-+      /* allocate space for base edesc, link tables and IV */
-+      edesc = qi_cache_zalloc(GFP_DMA | flags);
-+      if (unlikely(!edesc)) {
-+              dev_err(dev, "could not allocate extended descriptor\n");
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      if (unlikely(req->dst != req->src)) {
-+              src_nents = sg_nents_for_len(req->src, req->assoclen +
-+                                           req->cryptlen);
-+              if (unlikely(src_nents < 0)) {
-+                      dev_err(dev, "Insufficient bytes (%d) in src S/G\n",
-+                              req->assoclen + req->cryptlen);
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(src_nents);
-+              }
-+
-+              dst_nents = sg_nents_for_len(req->dst, req->assoclen +
-+                                           req->cryptlen +
-+                                           (encrypt ? authsize :
-+                                                      (-authsize)));
-+              if (unlikely(dst_nents < 0)) {
-+                      dev_err(dev, "Insufficient bytes (%d) in dst S/G\n",
-+                              req->assoclen + req->cryptlen +
-+                              (encrypt ? authsize : (-authsize)));
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(dst_nents);
-+              }
-+
-+              if (src_nents) {
-+                      mapped_src_nents = dma_map_sg(dev, req->src, src_nents,
-+                                                    DMA_TO_DEVICE);
-+                      if (unlikely(!mapped_src_nents)) {
-+                              dev_err(dev, "unable to map source\n");
-+                              qi_cache_free(edesc);
-+                              return ERR_PTR(-ENOMEM);
-+                      }
-+              } else {
-+                      mapped_src_nents = 0;
-+              }
-+
-+              mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents,
-+                                            DMA_FROM_DEVICE);
-+              if (unlikely(!mapped_dst_nents)) {
-+                      dev_err(dev, "unable to map destination\n");
-+                      dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE);
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+      } else {
-+              src_nents = sg_nents_for_len(req->src, req->assoclen +
-+                                           req->cryptlen +
-+                                              (encrypt ? authsize : 0));
-+              if (unlikely(src_nents < 0)) {
-+                      dev_err(dev, "Insufficient bytes (%d) in src S/G\n",
-+                              req->assoclen + req->cryptlen +
-+                              (encrypt ? authsize : 0));
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(src_nents);
-+              }
-+
-+              mapped_src_nents = dma_map_sg(dev, req->src, src_nents,
-+                                            DMA_BIDIRECTIONAL);
-+              if (unlikely(!mapped_src_nents)) {
-+                      dev_err(dev, "unable to map source\n");
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+      }
-+
-+      if ((alg->caam.rfc3686 && encrypt) || !alg->caam.geniv)
-+              ivsize = crypto_aead_ivsize(aead);
-+
-+      /*
-+       * Create S/G table: req->assoclen, [IV,] req->src [, req->dst].
-+       * Input is not contiguous.
-+       */
-+      qm_sg_nents = 1 + !!ivsize + mapped_src_nents +
-+                    (mapped_dst_nents > 1 ? mapped_dst_nents : 0);
-+      sg_table = &edesc->sgt[0];
-+      qm_sg_bytes = qm_sg_nents * sizeof(*sg_table);
-+      if (unlikely(offsetof(struct aead_edesc, sgt) + qm_sg_bytes + ivsize >
-+                   CAAM_QI_MEMCACHE_SIZE)) {
-+              dev_err(dev, "No space for %d S/G entries and/or %dB IV\n",
-+                      qm_sg_nents, ivsize);
-+              caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0,
-+                         0, 0, 0);
-+              qi_cache_free(edesc);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      if (ivsize) {
-+              u8 *iv = (u8 *)(sg_table + qm_sg_nents);
-+
-+              /* Make sure IV is located in a DMAable area */
-+              memcpy(iv, req->iv, ivsize);
-+
-+              iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
-+              if (dma_mapping_error(dev, iv_dma)) {
-+                      dev_err(dev, "unable to map IV\n");
-+                      caam_unmap(dev, req->src, req->dst, src_nents,
-+                                 dst_nents, 0, 0, 0, 0);
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+      }
-+
-+      edesc->src_nents = src_nents;
-+      edesc->dst_nents = dst_nents;
-+      edesc->iv_dma = iv_dma;
-+
-+      if ((alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK) ==
-+          OP_ALG_ALGSEL_CHACHA20 && ivsize != CHACHAPOLY_IV_SIZE)
-+              /*
-+               * The associated data comes already with the IV but we need
-+               * to skip it when we authenticate or encrypt...
-+               */
-+              edesc->assoclen = cpu_to_caam32(req->assoclen - ivsize);
-+      else
-+              edesc->assoclen = cpu_to_caam32(req->assoclen);
-+      edesc->assoclen_dma = dma_map_single(dev, &edesc->assoclen, 4,
-+                                           DMA_TO_DEVICE);
-+      if (dma_mapping_error(dev, edesc->assoclen_dma)) {
-+              dev_err(dev, "unable to map assoclen\n");
-+              caam_unmap(dev, req->src, req->dst, src_nents, dst_nents,
-+                         iv_dma, ivsize, 0, 0);
-+              qi_cache_free(edesc);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      dma_to_qm_sg_one(sg_table, edesc->assoclen_dma, 4, 0);
-+      qm_sg_index++;
-+      if (ivsize) {
-+              dma_to_qm_sg_one(sg_table + qm_sg_index, iv_dma, ivsize, 0);
-+              qm_sg_index++;
-+      }
-+      sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table + qm_sg_index, 0);
-+      qm_sg_index += mapped_src_nents;
-+
-+      if (mapped_dst_nents > 1)
-+              sg_to_qm_sg_last(req->dst, mapped_dst_nents, sg_table +
-+                               qm_sg_index, 0);
-+
-+      qm_sg_dma = dma_map_single(dev, sg_table, qm_sg_bytes, DMA_TO_DEVICE);
-+      if (dma_mapping_error(dev, qm_sg_dma)) {
-+              dev_err(dev, "unable to map S/G table\n");
-+              dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE);
-+              caam_unmap(dev, req->src, req->dst, src_nents, dst_nents,
-+                         iv_dma, ivsize, 0, 0);
-+              qi_cache_free(edesc);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      edesc->qm_sg_dma = qm_sg_dma;
-+      edesc->qm_sg_bytes = qm_sg_bytes;
-+
-+      out_len = req->assoclen + req->cryptlen +
-+                (encrypt ? ctx->authsize : (-ctx->authsize));
-+      in_len = 4 + ivsize + req->assoclen + req->cryptlen;
-+
-+      memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+      dpaa2_fl_set_final(in_fle, true);
-+      dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+      dpaa2_fl_set_addr(in_fle, qm_sg_dma);
-+      dpaa2_fl_set_len(in_fle, in_len);
-+
-+      if (req->dst == req->src) {
-+              if (mapped_src_nents == 1) {
-+                      dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+                      dpaa2_fl_set_addr(out_fle, sg_dma_address(req->src));
-+              } else {
-+                      dpaa2_fl_set_format(out_fle, dpaa2_fl_sg);
-+                      dpaa2_fl_set_addr(out_fle, qm_sg_dma +
-+                                        (1 + !!ivsize) * sizeof(*sg_table));
-+              }
-+      } else if (mapped_dst_nents == 1) {
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+              dpaa2_fl_set_addr(out_fle, sg_dma_address(req->dst));
-+      } else {
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_sg);
-+              dpaa2_fl_set_addr(out_fle, qm_sg_dma + qm_sg_index *
-+                                sizeof(*sg_table));
-+      }
-+
-+      dpaa2_fl_set_len(out_fle, out_len);
-+
-+      return edesc;
-+}
-+
-+static int chachapoly_set_sh_desc(struct crypto_aead *aead)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      struct device *dev = ctx->dev;
-+      struct caam_flc *flc;
-+      u32 *desc;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      flc = &ctx->flc[ENCRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
-+                             ctx->authsize, true, true);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      flc = &ctx->flc[DECRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
-+                             ctx->authsize, false, true);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      return 0;
-+}
-+
-+static int chachapoly_setauthsize(struct crypto_aead *aead,
-+                                unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+
-+      if (authsize != POLY1305_DIGEST_SIZE)
-+              return -EINVAL;
-+
-+      ctx->authsize = authsize;
-+      return chachapoly_set_sh_desc(aead);
-+}
-+
-+static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
-+                           unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
-+
-+      if (keylen != CHACHA20_KEY_SIZE + saltlen) {
-+              crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+              return -EINVAL;
-+      }
-+
-+      ctx->cdata.key_virt = key;
-+      ctx->cdata.keylen = keylen - saltlen;
-+
-+      return chachapoly_set_sh_desc(aead);
-+}
-+
-+static struct tls_edesc *tls_edesc_alloc(struct aead_request *req,
-+                                       bool encrypt)
-+{
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      unsigned int blocksize = crypto_aead_blocksize(tls);
-+      unsigned int padsize, authsize;
-+      struct caam_request *req_ctx = aead_request_ctx(req);
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+      struct caam_aead_alg *alg = container_of(crypto_aead_alg(tls),
-+                                               typeof(*alg), aead);
-+      struct device *dev = ctx->dev;
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
-+      struct tls_edesc *edesc;
-+      dma_addr_t qm_sg_dma, iv_dma = 0;
-+      int ivsize = 0;
-+      u8 *iv;
-+      int qm_sg_index, qm_sg_ents = 0, qm_sg_bytes;
-+      int in_len, out_len;
-+      struct dpaa2_sg_entry *sg_table;
-+      struct scatterlist *dst;
-+
-+      if (encrypt) {
-+              padsize = blocksize - ((req->cryptlen + ctx->authsize) %
-+                                      blocksize);
-+              authsize = ctx->authsize + padsize;
-+      } else {
-+              authsize = ctx->authsize;
-+      }
-+
-+      /* allocate space for base edesc, link tables and IV */
-+      edesc = qi_cache_zalloc(GFP_DMA | flags);
-+      if (unlikely(!edesc)) {
-+              dev_err(dev, "could not allocate extended descriptor\n");
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      if (likely(req->src == req->dst)) {
-+              src_nents = sg_nents_for_len(req->src, req->assoclen +
-+                                           req->cryptlen +
-+                                           (encrypt ? authsize : 0));
-+              if (unlikely(src_nents < 0)) {
-+                      dev_err(dev, "Insufficient bytes (%d) in src S/G\n",
-+                              req->assoclen + req->cryptlen +
-+                              (encrypt ? authsize : 0));
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(src_nents);
-+              }
-+
-+              mapped_src_nents = dma_map_sg(dev, req->src, src_nents,
-+                                            DMA_BIDIRECTIONAL);
-+              if (unlikely(!mapped_src_nents)) {
-+                      dev_err(dev, "unable to map source\n");
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+              dst = req->dst;
-+      } else {
-+              src_nents = sg_nents_for_len(req->src, req->assoclen +
-+                                           req->cryptlen);
-+              if (unlikely(src_nents < 0)) {
-+                      dev_err(dev, "Insufficient bytes (%d) in src S/G\n",
-+                              req->assoclen + req->cryptlen);
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(src_nents);
-+              }
-+
-+              dst = scatterwalk_ffwd(edesc->tmp, req->dst, req->assoclen);
-+              dst_nents = sg_nents_for_len(dst, req->cryptlen +
-+                                           (encrypt ? authsize : 0));
-+              if (unlikely(dst_nents < 0)) {
-+                      dev_err(dev, "Insufficient bytes (%d) in dst S/G\n",
-+                              req->cryptlen +
-+                              (encrypt ? authsize : 0));
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(dst_nents);
-+              }
-+
-+              if (src_nents) {
-+                      mapped_src_nents = dma_map_sg(dev, req->src,
-+                                                    src_nents, DMA_TO_DEVICE);
-+                      if (unlikely(!mapped_src_nents)) {
-+                              dev_err(dev, "unable to map source\n");
-+                              qi_cache_free(edesc);
-+                              return ERR_PTR(-ENOMEM);
-+                      }
-+              } else {
-+                      mapped_src_nents = 0;
-+              }
-+
-+              mapped_dst_nents = dma_map_sg(dev, dst, dst_nents,
-+                                            DMA_FROM_DEVICE);
-+              if (unlikely(!mapped_dst_nents)) {
-+                      dev_err(dev, "unable to map destination\n");
-+                      dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE);
-+                      qi_cache_free(edesc);
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+      }
-+
-+      /*
-+       * Create S/G table: IV, src, dst.
-+       * Input is not contiguous.
-+       */
-+      qm_sg_ents = 1 + mapped_src_nents +
-+                   (mapped_dst_nents > 1 ? mapped_dst_nents : 0);
-+      sg_table = &edesc->sgt[0];
-+      qm_sg_bytes = qm_sg_ents * sizeof(*sg_table);
-+
-+      ivsize = crypto_aead_ivsize(tls);
-+      iv = (u8 *)(sg_table + qm_sg_ents);
-+      /* Make sure IV is located in a DMAable area */
-+      memcpy(iv, req->iv, ivsize);
-+      iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
-+      if (dma_mapping_error(dev, iv_dma)) {
-+              dev_err(dev, "unable to map IV\n");
-+              caam_unmap(dev, req->src, dst, src_nents, dst_nents, 0, 0, 0,
-+                         0);
-+              qi_cache_free(edesc);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      edesc->src_nents = src_nents;
-+      edesc->dst_nents = dst_nents;
-+      edesc->dst = dst;
-+      edesc->iv_dma = iv_dma;
-+
-+      dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0);
-+      qm_sg_index = 1;
-+
-+      sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table + qm_sg_index, 0);
-+      qm_sg_index += mapped_src_nents;
-+
-+      if (mapped_dst_nents > 1)
-+              sg_to_qm_sg_last(dst, mapped_dst_nents, sg_table +
-+                               qm_sg_index, 0);
-+
-+      qm_sg_dma = dma_map_single(dev, sg_table, qm_sg_bytes, DMA_TO_DEVICE);
-+      if (dma_mapping_error(dev, qm_sg_dma)) {
-+              dev_err(dev, "unable to map S/G table\n");
-+              caam_unmap(dev, req->src, dst, src_nents, dst_nents, iv_dma,
-+                         ivsize, 0, 0);
-+              qi_cache_free(edesc);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      edesc->qm_sg_dma = qm_sg_dma;
-+      edesc->qm_sg_bytes = qm_sg_bytes;
-+
-+      out_len = req->cryptlen + (encrypt ? authsize : 0);
-+      in_len = ivsize + req->assoclen + req->cryptlen;
-+
-+      memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+      dpaa2_fl_set_final(in_fle, true);
-+      dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+      dpaa2_fl_set_addr(in_fle, qm_sg_dma);
-+      dpaa2_fl_set_len(in_fle, in_len);
-+
-+      if (req->dst == req->src) {
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_sg);
-+              dpaa2_fl_set_addr(out_fle, qm_sg_dma +
-+                                (sg_nents_for_len(req->src, req->assoclen) +
-+                                 1) * sizeof(*sg_table));
-+      } else if (mapped_dst_nents == 1) {
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+              dpaa2_fl_set_addr(out_fle, sg_dma_address(dst));
-+      } else {
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_sg);
-+              dpaa2_fl_set_addr(out_fle, qm_sg_dma + qm_sg_index *
-+                                sizeof(*sg_table));
-+      }
-+
-+      dpaa2_fl_set_len(out_fle, out_len);
-+
-+      return edesc;
-+}
-+
-+static int tls_set_sh_desc(struct crypto_aead *tls)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+      unsigned int ivsize = crypto_aead_ivsize(tls);
-+      unsigned int blocksize = crypto_aead_blocksize(tls);
-+      struct device *dev = ctx->dev;
-+      struct dpaa2_caam_priv *priv = dev_get_drvdata(dev);
-+      struct caam_flc *flc;
-+      u32 *desc;
-+      unsigned int assoclen = 13; /* always 13 bytes for TLS */
-+      unsigned int data_len[2];
-+      u32 inl_mask;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      /*
-+       * TLS 1.0 encrypt shared descriptor
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      data_len[0] = ctx->adata.keylen_pad;
-+      data_len[1] = ctx->cdata.keylen;
-+
-+      if (desc_inline_query(DESC_TLS10_ENC_LEN, DESC_JOB_IO_LEN, data_len,
-+                            &inl_mask, ARRAY_SIZE(data_len)) < 0)
-+              return -EINVAL;
-+
-+      if (inl_mask & 1)
-+              ctx->adata.key_virt = ctx->key;
-+      else
-+              ctx->adata.key_dma = ctx->key_dma;
-+
-+      if (inl_mask & 2)
-+              ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
-+      else
-+              ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
-+
-+      ctx->adata.key_inline = !!(inl_mask & 1);
-+      ctx->cdata.key_inline = !!(inl_mask & 2);
-+
-+      flc = &ctx->flc[ENCRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_tls_encap(desc, &ctx->cdata, &ctx->adata,
-+                            assoclen, ivsize, ctx->authsize, blocksize,
-+                            priv->sec_attr.era);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc));
-+      dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      /*
-+       * TLS 1.0 decrypt shared descriptor
-+       * Keys do not fit inline, regardless of algorithms used
-+       */
-+      ctx->adata.key_inline = false;
-+      ctx->adata.key_dma = ctx->key_dma;
-+      ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
-+
-+      flc = &ctx->flc[DECRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_tls_decap(desc, &ctx->cdata, &ctx->adata, assoclen, ivsize,
-+                            ctx->authsize, blocksize, priv->sec_attr.era);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      return 0;
-+}
-+
-+static int tls_setkey(struct crypto_aead *tls, const u8 *key,
-+                    unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+      struct device *dev = ctx->dev;
-+      struct crypto_authenc_keys keys;
-+
-+      if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
-+              goto badkey;
-+
-+#ifdef DEBUG
-+      dev_err(dev, "keylen %d enckeylen %d authkeylen %d\n",
-+              keys.authkeylen + keys.enckeylen, keys.enckeylen,
-+              keys.authkeylen);
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+
-+      ctx->adata.keylen = keys.authkeylen;
-+      ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
-+                                            OP_ALG_ALGSEL_MASK);
-+
-+      if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
-+              goto badkey;
-+
-+      memcpy(ctx->key, keys.authkey, keys.authkeylen);
-+      memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
-+      dma_sync_single_for_device(dev, ctx->key_dma, ctx->adata.keylen_pad +
-+                                 keys.enckeylen, ctx->dir);
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "ctx.key@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
-+                     ctx->adata.keylen_pad + keys.enckeylen, 1);
-+#endif
-+
-+      ctx->cdata.keylen = keys.enckeylen;
-+
-+      return tls_set_sh_desc(tls);
-+badkey:
-+      crypto_aead_set_flags(tls, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+      return -EINVAL;
-+}
-+
-+static int tls_setauthsize(struct crypto_aead *tls, unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+
-+      ctx->authsize = authsize;
-+      tls_set_sh_desc(tls);
-+
-+      return 0;
-+}
-+
-+static int gcm_set_sh_desc(struct crypto_aead *aead)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *dev = ctx->dev;
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      struct caam_flc *flc;
-+      u32 *desc;
-+      int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
-+                      ctx->cdata.keylen;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      /*
-+       * AES GCM encrypt shared descriptor
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_GCM_ENC_LEN) {
-+              ctx->cdata.key_inline = true;
-+              ctx->cdata.key_virt = ctx->key;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      flc = &ctx->flc[ENCRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, true);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      /*
-+       * Job Descriptor and Shared Descriptors
-+       * must all fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_GCM_DEC_LEN) {
-+              ctx->cdata.key_inline = true;
-+              ctx->cdata.key_virt = ctx->key;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      flc = &ctx->flc[DECRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, true);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      return 0;
-+}
-+
-+static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(authenc);
-+
-+      ctx->authsize = authsize;
-+      gcm_set_sh_desc(authenc);
-+
-+      return 0;
-+}
-+
-+static int gcm_setkey(struct crypto_aead *aead,
-+                    const u8 *key, unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *dev = ctx->dev;
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+
-+      memcpy(ctx->key, key, keylen);
-+      dma_sync_single_for_device(dev, ctx->key_dma, keylen, ctx->dir);
-+      ctx->cdata.keylen = keylen;
-+
-+      return gcm_set_sh_desc(aead);
-+}
-+
-+static int rfc4106_set_sh_desc(struct crypto_aead *aead)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *dev = ctx->dev;
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      struct caam_flc *flc;
-+      u32 *desc;
-+      int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
-+                      ctx->cdata.keylen;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      ctx->cdata.key_virt = ctx->key;
-+
-+      /*
-+       * RFC4106 encrypt shared descriptor
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_RFC4106_ENC_LEN) {
-+              ctx->cdata.key_inline = true;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      flc = &ctx->flc[ENCRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
-+                                true);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      /*
-+       * Job Descriptor and Shared Descriptors
-+       * must all fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_RFC4106_DEC_LEN) {
-+              ctx->cdata.key_inline = true;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      flc = &ctx->flc[DECRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
-+                                true);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      return 0;
-+}
-+
-+static int rfc4106_setauthsize(struct crypto_aead *authenc,
-+                             unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(authenc);
-+
-+      ctx->authsize = authsize;
-+      rfc4106_set_sh_desc(authenc);
-+
-+      return 0;
-+}
-+
-+static int rfc4106_setkey(struct crypto_aead *aead,
-+                        const u8 *key, unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *dev = ctx->dev;
-+
-+      if (keylen < 4)
-+              return -EINVAL;
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+
-+      memcpy(ctx->key, key, keylen);
-+      /*
-+       * The last four bytes of the key material are used as the salt value
-+       * in the nonce. Update the AES key length.
-+       */
-+      ctx->cdata.keylen = keylen - 4;
-+      dma_sync_single_for_device(dev, ctx->key_dma, ctx->cdata.keylen,
-+                                 ctx->dir);
-+
-+      return rfc4106_set_sh_desc(aead);
-+}
-+
-+static int rfc4543_set_sh_desc(struct crypto_aead *aead)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *dev = ctx->dev;
-+      unsigned int ivsize = crypto_aead_ivsize(aead);
-+      struct caam_flc *flc;
-+      u32 *desc;
-+      int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN -
-+                      ctx->cdata.keylen;
-+
-+      if (!ctx->cdata.keylen || !ctx->authsize)
-+              return 0;
-+
-+      ctx->cdata.key_virt = ctx->key;
-+
-+      /*
-+       * RFC4543 encrypt shared descriptor
-+       * Job Descriptor and Shared Descriptor
-+       * must fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_RFC4543_ENC_LEN) {
-+              ctx->cdata.key_inline = true;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      flc = &ctx->flc[ENCRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
-+                                true);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      /*
-+       * Job Descriptor and Shared Descriptors
-+       * must all fit into the 64-word Descriptor h/w Buffer
-+       */
-+      if (rem_bytes >= DESC_QI_RFC4543_DEC_LEN) {
-+              ctx->cdata.key_inline = true;
-+      } else {
-+              ctx->cdata.key_inline = false;
-+              ctx->cdata.key_dma = ctx->key_dma;
-+      }
-+
-+      flc = &ctx->flc[DECRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
-+                                true);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      return 0;
-+}
-+
-+static int rfc4543_setauthsize(struct crypto_aead *authenc,
-+                             unsigned int authsize)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(authenc);
-+
-+      ctx->authsize = authsize;
-+      rfc4543_set_sh_desc(authenc);
-+
-+      return 0;
-+}
-+
-+static int rfc4543_setkey(struct crypto_aead *aead,
-+                        const u8 *key, unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct device *dev = ctx->dev;
-+
-+      if (keylen < 4)
-+              return -EINVAL;
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+
-+      memcpy(ctx->key, key, keylen);
-+      /*
-+       * The last four bytes of the key material are used as the salt value
-+       * in the nonce. Update the AES key length.
-+       */
-+      ctx->cdata.keylen = keylen - 4;
-+      dma_sync_single_for_device(dev, ctx->key_dma, ctx->cdata.keylen,
-+                                 ctx->dir);
-+
-+      return rfc4543_set_sh_desc(aead);
-+}
-+
-+static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
-+                         unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
-+      struct caam_skcipher_alg *alg =
-+              container_of(crypto_skcipher_alg(skcipher),
-+                           struct caam_skcipher_alg, skcipher);
-+      struct device *dev = ctx->dev;
-+      struct caam_flc *flc;
-+      unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
-+      u32 *desc;
-+      u32 ctx1_iv_off = 0;
-+      const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
-+                             OP_ALG_AAI_CTR_MOD128) &&
-+                             ((ctx->cdata.algtype & OP_ALG_ALGSEL_MASK) !=
-+                             OP_ALG_ALGSEL_CHACHA20);
-+      const bool is_rfc3686 = alg->caam.rfc3686;
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
-+#endif
-+      /*
-+       * AES-CTR needs to load IV in CONTEXT1 reg
-+       * at an offset of 128bits (16bytes)
-+       * CONTEXT1[255:128] = IV
-+       */
-+      if (ctr_mode)
-+              ctx1_iv_off = 16;
-+
-+      /*
-+       * RFC3686 specific:
-+       *      | CONTEXT1[255:128] = {NONCE, IV, COUNTER}
-+       *      | *key = {KEY, NONCE}
-+       */
-+      if (is_rfc3686) {
-+              ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
-+              keylen -= CTR_RFC3686_NONCE_SIZE;
-+      }
-+
-+      ctx->cdata.keylen = keylen;
-+      ctx->cdata.key_virt = key;
-+      ctx->cdata.key_inline = true;
-+
-+      /* skcipher_encrypt shared descriptor */
-+      flc = &ctx->flc[ENCRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_ablkcipher_encap(desc, &ctx->cdata, ivsize,
-+                                   is_rfc3686, ctx1_iv_off);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      /* skcipher_decrypt shared descriptor */
-+      flc = &ctx->flc[DECRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_ablkcipher_decap(desc, &ctx->cdata, ivsize,
-+                                   is_rfc3686, ctx1_iv_off);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      return 0;
-+}
-+
-+static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
-+                             unsigned int keylen)
-+{
-+      struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
-+      struct device *dev = ctx->dev;
-+      struct caam_flc *flc;
-+      u32 *desc;
-+
-+      if (keylen != 2 * AES_MIN_KEY_SIZE  && keylen != 2 * AES_MAX_KEY_SIZE) {
-+              dev_err(dev, "key size mismatch\n");
-+              crypto_skcipher_set_flags(skcipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+              return -EINVAL;
-+      }
-+
-+      ctx->cdata.keylen = keylen;
-+      ctx->cdata.key_virt = key;
-+      ctx->cdata.key_inline = true;
-+
-+      /* xts_skcipher_encrypt shared descriptor */
-+      flc = &ctx->flc[ENCRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_xts_ablkcipher_encap(desc, &ctx->cdata);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      /* xts_skcipher_decrypt shared descriptor */
-+      flc = &ctx->flc[DECRYPT];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_xts_ablkcipher_decap(desc, &ctx->cdata);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
-+                                 sizeof(flc->flc) + desc_bytes(desc),
-+                                 ctx->dir);
-+
-+      return 0;
-+}
-+
-+static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req)
-+{
-+      struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
-+      struct caam_request *req_ctx = skcipher_request_ctx(req);
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
-+      struct device *dev = ctx->dev;
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                     GFP_KERNEL : GFP_ATOMIC;
-+      int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
-+      struct skcipher_edesc *edesc;
-+      dma_addr_t iv_dma;
-+      u8 *iv;
-+      int ivsize = crypto_skcipher_ivsize(skcipher);
-+      int dst_sg_idx, qm_sg_ents, qm_sg_bytes;
-+      struct dpaa2_sg_entry *sg_table;
-+
-+      src_nents = sg_nents_for_len(req->src, req->cryptlen);
-+      if (unlikely(src_nents < 0)) {
-+              dev_err(dev, "Insufficient bytes (%d) in src S/G\n",
-+                      req->cryptlen);
-+              return ERR_PTR(src_nents);
-+      }
-+
-+      if (unlikely(req->dst != req->src)) {
-+              dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
-+              if (unlikely(dst_nents < 0)) {
-+                      dev_err(dev, "Insufficient bytes (%d) in dst S/G\n",
-+                              req->cryptlen);
-+                      return ERR_PTR(dst_nents);
-+              }
-+
-+              mapped_src_nents = dma_map_sg(dev, req->src, src_nents,
-+                                            DMA_TO_DEVICE);
-+              if (unlikely(!mapped_src_nents)) {
-+                      dev_err(dev, "unable to map source\n");
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+
-+              mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents,
-+                                            DMA_FROM_DEVICE);
-+              if (unlikely(!mapped_dst_nents)) {
-+                      dev_err(dev, "unable to map destination\n");
-+                      dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE);
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+      } else {
-+              mapped_src_nents = dma_map_sg(dev, req->src, src_nents,
-+                                            DMA_BIDIRECTIONAL);
-+              if (unlikely(!mapped_src_nents)) {
-+                      dev_err(dev, "unable to map source\n");
-+                      return ERR_PTR(-ENOMEM);
-+              }
-+      }
-+
-+      qm_sg_ents = 1 + mapped_src_nents;
-+      dst_sg_idx = qm_sg_ents;
-+
-+      qm_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
-+      qm_sg_bytes = qm_sg_ents * sizeof(struct dpaa2_sg_entry);
-+      if (unlikely(offsetof(struct skcipher_edesc, sgt) + qm_sg_bytes +
-+                   ivsize > CAAM_QI_MEMCACHE_SIZE)) {
-+              dev_err(dev, "No space for %d S/G entries and/or %dB IV\n",
-+                      qm_sg_ents, ivsize);
-+              caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0,
-+                         0, 0, 0);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      /* allocate space for base edesc, link tables and IV */
-+      edesc = qi_cache_zalloc(GFP_DMA | flags);
-+      if (unlikely(!edesc)) {
-+              dev_err(dev, "could not allocate extended descriptor\n");
-+              caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0,
-+                         0, 0, 0);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      /* Make sure IV is located in a DMAable area */
-+      sg_table = &edesc->sgt[0];
-+      iv = (u8 *)(sg_table + qm_sg_ents);
-+      memcpy(iv, req->iv, ivsize);
-+
-+      iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE);
-+      if (dma_mapping_error(dev, iv_dma)) {
-+              dev_err(dev, "unable to map IV\n");
-+              caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0,
-+                         0, 0, 0);
-+              qi_cache_free(edesc);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      edesc->src_nents = src_nents;
-+      edesc->dst_nents = dst_nents;
-+      edesc->iv_dma = iv_dma;
-+      edesc->qm_sg_bytes = qm_sg_bytes;
-+
-+      dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0);
-+      sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table + 1, 0);
-+
-+      if (mapped_dst_nents > 1)
-+              sg_to_qm_sg_last(req->dst, mapped_dst_nents, sg_table +
-+                               dst_sg_idx, 0);
-+
-+      edesc->qm_sg_dma = dma_map_single(dev, sg_table, edesc->qm_sg_bytes,
-+                                        DMA_TO_DEVICE);
-+      if (dma_mapping_error(dev, edesc->qm_sg_dma)) {
-+              dev_err(dev, "unable to map S/G table\n");
-+              caam_unmap(dev, req->src, req->dst, src_nents, dst_nents,
-+                         iv_dma, ivsize, 0, 0);
-+              qi_cache_free(edesc);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+      dpaa2_fl_set_final(in_fle, true);
-+      dpaa2_fl_set_len(in_fle, req->cryptlen + ivsize);
-+      dpaa2_fl_set_len(out_fle, req->cryptlen);
-+
-+      dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+      dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
-+
-+      if (req->src == req->dst) {
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_sg);
-+              dpaa2_fl_set_addr(out_fle, edesc->qm_sg_dma +
-+                                sizeof(*sg_table));
-+      } else if (mapped_dst_nents > 1) {
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_sg);
-+              dpaa2_fl_set_addr(out_fle, edesc->qm_sg_dma + dst_sg_idx *
-+                                sizeof(*sg_table));
-+      } else {
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+              dpaa2_fl_set_addr(out_fle, sg_dma_address(req->dst));
-+      }
-+
-+      return edesc;
-+}
-+
-+static void aead_unmap(struct device *dev, struct aead_edesc *edesc,
-+                     struct aead_request *req)
-+{
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      int ivsize = crypto_aead_ivsize(aead);
-+
-+      caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents,
-+                 edesc->iv_dma, ivsize, edesc->qm_sg_dma, edesc->qm_sg_bytes);
-+      dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE);
-+}
-+
-+static void tls_unmap(struct device *dev, struct tls_edesc *edesc,
-+                    struct aead_request *req)
-+{
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      int ivsize = crypto_aead_ivsize(tls);
-+
-+      caam_unmap(dev, req->src, edesc->dst, edesc->src_nents,
-+                 edesc->dst_nents, edesc->iv_dma, ivsize, edesc->qm_sg_dma,
-+                 edesc->qm_sg_bytes);
-+}
-+
-+static void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc,
-+                         struct skcipher_request *req)
-+{
-+      struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
-+      int ivsize = crypto_skcipher_ivsize(skcipher);
-+
-+      caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents,
-+                 edesc->iv_dma, ivsize, edesc->qm_sg_dma, edesc->qm_sg_bytes);
-+}
-+
-+static void aead_encrypt_done(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct aead_request *req = container_of(areq, struct aead_request,
-+                                              base);
-+      struct caam_request *req_ctx = to_caam_req(areq);
-+      struct aead_edesc *edesc = req_ctx->edesc;
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      int ecode = 0;
-+
-+#ifdef DEBUG
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              ecode = -EIO;
-+      }
-+
-+      aead_unmap(ctx->dev, edesc, req);
-+      qi_cache_free(edesc);
-+      aead_request_complete(req, ecode);
-+}
-+
-+static void aead_decrypt_done(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct aead_request *req = container_of(areq, struct aead_request,
-+                                              base);
-+      struct caam_request *req_ctx = to_caam_req(areq);
-+      struct aead_edesc *edesc = req_ctx->edesc;
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      int ecode = 0;
-+
-+#ifdef DEBUG
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              /*
-+               * verify hw auth check passed else return -EBADMSG
-+               */
-+              if ((status & JRSTA_CCBERR_ERRID_MASK) ==
-+                   JRSTA_CCBERR_ERRID_ICVCHK)
-+                      ecode = -EBADMSG;
-+              else
-+                      ecode = -EIO;
-+      }
-+
-+      aead_unmap(ctx->dev, edesc, req);
-+      qi_cache_free(edesc);
-+      aead_request_complete(req, ecode);
-+}
-+
-+static int aead_encrypt(struct aead_request *req)
-+{
-+      struct aead_edesc *edesc;
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct caam_request *caam_req = aead_request_ctx(req);
-+      int ret;
-+
-+      /* allocate extended descriptor */
-+      edesc = aead_edesc_alloc(req, true);
-+      if (IS_ERR(edesc))
-+              return PTR_ERR(edesc);
-+
-+      caam_req->flc = &ctx->flc[ENCRYPT];
-+      caam_req->flc_dma = ctx->flc_dma[ENCRYPT];
-+      caam_req->cbk = aead_encrypt_done;
-+      caam_req->ctx = &req->base;
-+      caam_req->edesc = edesc;
-+      ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
-+      if (ret != -EINPROGRESS &&
-+          !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
-+              aead_unmap(ctx->dev, edesc, req);
-+              qi_cache_free(edesc);
-+      }
-+
-+      return ret;
-+}
-+
-+static int aead_decrypt(struct aead_request *req)
-+{
-+      struct aead_edesc *edesc;
-+      struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(aead);
-+      struct caam_request *caam_req = aead_request_ctx(req);
-+      int ret;
-+
-+      /* allocate extended descriptor */
-+      edesc = aead_edesc_alloc(req, false);
-+      if (IS_ERR(edesc))
-+              return PTR_ERR(edesc);
-+
-+      caam_req->flc = &ctx->flc[DECRYPT];
-+      caam_req->flc_dma = ctx->flc_dma[DECRYPT];
-+      caam_req->cbk = aead_decrypt_done;
-+      caam_req->ctx = &req->base;
-+      caam_req->edesc = edesc;
-+      ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
-+      if (ret != -EINPROGRESS &&
-+          !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
-+              aead_unmap(ctx->dev, edesc, req);
-+              qi_cache_free(edesc);
-+      }
-+
-+      return ret;
-+}
-+
-+static void tls_encrypt_done(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct aead_request *req = container_of(areq, struct aead_request,
-+                                              base);
-+      struct caam_request *req_ctx = to_caam_req(areq);
-+      struct tls_edesc *edesc = req_ctx->edesc;
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+      int ecode = 0;
-+
-+#ifdef DEBUG
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              ecode = -EIO;
-+      }
-+
-+      tls_unmap(ctx->dev, edesc, req);
-+      qi_cache_free(edesc);
-+      aead_request_complete(req, ecode);
-+}
-+
-+static void tls_decrypt_done(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct aead_request *req = container_of(areq, struct aead_request,
-+                                              base);
-+      struct caam_request *req_ctx = to_caam_req(areq);
-+      struct tls_edesc *edesc = req_ctx->edesc;
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+      int ecode = 0;
-+
-+#ifdef DEBUG
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              /*
-+               * verify hw auth check passed else return -EBADMSG
-+               */
-+              if ((status & JRSTA_CCBERR_ERRID_MASK) ==
-+                   JRSTA_CCBERR_ERRID_ICVCHK)
-+                      ecode = -EBADMSG;
-+              else
-+                      ecode = -EIO;
-+      }
-+
-+      tls_unmap(ctx->dev, edesc, req);
-+      qi_cache_free(edesc);
-+      aead_request_complete(req, ecode);
-+}
-+
-+static int tls_encrypt(struct aead_request *req)
-+{
-+      struct tls_edesc *edesc;
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+      struct caam_request *caam_req = aead_request_ctx(req);
-+      int ret;
-+
-+      /* allocate extended descriptor */
-+      edesc = tls_edesc_alloc(req, true);
-+      if (IS_ERR(edesc))
-+              return PTR_ERR(edesc);
-+
-+      caam_req->flc = &ctx->flc[ENCRYPT];
-+      caam_req->flc_dma = ctx->flc_dma[ENCRYPT];
-+      caam_req->cbk = tls_encrypt_done;
-+      caam_req->ctx = &req->base;
-+      caam_req->edesc = edesc;
-+      ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
-+      if (ret != -EINPROGRESS &&
-+          !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
-+              tls_unmap(ctx->dev, edesc, req);
-+              qi_cache_free(edesc);
-+      }
-+
-+      return ret;
-+}
-+
-+static int tls_decrypt(struct aead_request *req)
-+{
-+      struct tls_edesc *edesc;
-+      struct crypto_aead *tls = crypto_aead_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_aead_ctx(tls);
-+      struct caam_request *caam_req = aead_request_ctx(req);
-+      int ret;
-+
-+      /* allocate extended descriptor */
-+      edesc = tls_edesc_alloc(req, false);
-+      if (IS_ERR(edesc))
-+              return PTR_ERR(edesc);
-+
-+      caam_req->flc = &ctx->flc[DECRYPT];
-+      caam_req->flc_dma = ctx->flc_dma[DECRYPT];
-+      caam_req->cbk = tls_decrypt_done;
-+      caam_req->ctx = &req->base;
-+      caam_req->edesc = edesc;
-+      ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
-+      if (ret != -EINPROGRESS &&
-+          !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
-+              tls_unmap(ctx->dev, edesc, req);
-+              qi_cache_free(edesc);
-+      }
-+
-+      return ret;
-+}
-+
-+static int ipsec_gcm_encrypt(struct aead_request *req)
-+{
-+      if (req->assoclen < 8)
-+              return -EINVAL;
-+
-+      return aead_encrypt(req);
-+}
-+
-+static int ipsec_gcm_decrypt(struct aead_request *req)
-+{
-+      if (req->assoclen < 8)
-+              return -EINVAL;
-+
-+      return aead_decrypt(req);
-+}
-+
-+static void skcipher_encrypt_done(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct skcipher_request *req = skcipher_request_cast(areq);
-+      struct caam_request *req_ctx = to_caam_req(areq);
-+      struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
-+      struct skcipher_edesc *edesc = req_ctx->edesc;
-+      int ecode = 0;
-+      int ivsize = crypto_skcipher_ivsize(skcipher);
-+
-+#ifdef DEBUG
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              ecode = -EIO;
-+      }
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "dstiv  @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
-+                     edesc->src_nents > 1 ? 100 : ivsize, 1);
-+      caam_dump_sg(KERN_ERR, "dst    @" __stringify(__LINE__)": ",
-+                   DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
-+                   edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
-+#endif
-+
-+      skcipher_unmap(ctx->dev, edesc, req);
-+
-+      /*
-+       * The crypto API expects us to set the IV (req->iv) to the last
-+       * ciphertext block. This is used e.g. by the CTS mode.
-+       */
-+      scatterwalk_map_and_copy(req->iv, req->dst, req->cryptlen - ivsize,
-+                               ivsize, 0);
-+
-+      qi_cache_free(edesc);
-+      skcipher_request_complete(req, ecode);
-+}
-+
-+static void skcipher_decrypt_done(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct skcipher_request *req = skcipher_request_cast(areq);
-+      struct caam_request *req_ctx = to_caam_req(areq);
-+      struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
-+      struct skcipher_edesc *edesc = req_ctx->edesc;
-+      int ecode = 0;
-+#ifdef DEBUG
-+      int ivsize = crypto_skcipher_ivsize(skcipher);
-+
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              ecode = -EIO;
-+      }
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "dstiv  @" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
-+                     edesc->src_nents > 1 ? 100 : ivsize, 1);
-+      caam_dump_sg(KERN_ERR, "dst    @" __stringify(__LINE__)": ",
-+                   DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
-+                   edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
-+#endif
-+
-+      skcipher_unmap(ctx->dev, edesc, req);
-+      qi_cache_free(edesc);
-+      skcipher_request_complete(req, ecode);
-+}
-+
-+static int skcipher_encrypt(struct skcipher_request *req)
-+{
-+      struct skcipher_edesc *edesc;
-+      struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
-+      struct caam_request *caam_req = skcipher_request_ctx(req);
-+      int ret;
-+
-+      /* allocate extended descriptor */
-+      edesc = skcipher_edesc_alloc(req);
-+      if (IS_ERR(edesc))
-+              return PTR_ERR(edesc);
-+
-+      caam_req->flc = &ctx->flc[ENCRYPT];
-+      caam_req->flc_dma = ctx->flc_dma[ENCRYPT];
-+      caam_req->cbk = skcipher_encrypt_done;
-+      caam_req->ctx = &req->base;
-+      caam_req->edesc = edesc;
-+      ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
-+      if (ret != -EINPROGRESS &&
-+          !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
-+              skcipher_unmap(ctx->dev, edesc, req);
-+              qi_cache_free(edesc);
-+      }
-+
-+      return ret;
-+}
-+
-+static int skcipher_decrypt(struct skcipher_request *req)
-+{
-+      struct skcipher_edesc *edesc;
-+      struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
-+      struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
-+      struct caam_request *caam_req = skcipher_request_ctx(req);
-+      int ivsize = crypto_skcipher_ivsize(skcipher);
-+      int ret;
-+
-+      /* allocate extended descriptor */
-+      edesc = skcipher_edesc_alloc(req);
-+      if (IS_ERR(edesc))
-+              return PTR_ERR(edesc);
-+
-+      /*
-+       * The crypto API expects us to set the IV (req->iv) to the last
-+       * ciphertext block.
-+       */
-+      scatterwalk_map_and_copy(req->iv, req->src, req->cryptlen - ivsize,
-+                               ivsize, 0);
-+
-+      caam_req->flc = &ctx->flc[DECRYPT];
-+      caam_req->flc_dma = ctx->flc_dma[DECRYPT];
-+      caam_req->cbk = skcipher_decrypt_done;
-+      caam_req->ctx = &req->base;
-+      caam_req->edesc = edesc;
-+      ret = dpaa2_caam_enqueue(ctx->dev, caam_req);
-+      if (ret != -EINPROGRESS &&
-+          !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
-+              skcipher_unmap(ctx->dev, edesc, req);
-+              qi_cache_free(edesc);
-+      }
-+
-+      return ret;
-+}
-+
-+static int caam_cra_init(struct caam_ctx *ctx, struct caam_alg_entry *caam,
-+                       bool uses_dkp)
-+{
-+      dma_addr_t dma_addr;
-+      int i;
-+
-+      /* copy descriptor header template value */
-+      ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
-+      ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
-+
-+      ctx->dev = caam->dev;
-+      ctx->dir = uses_dkp ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
-+
-+      dma_addr = dma_map_single_attrs(ctx->dev, ctx->flc,
-+                                      offsetof(struct caam_ctx, flc_dma),
-+                                      ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
-+      if (dma_mapping_error(ctx->dev, dma_addr)) {
-+              dev_err(ctx->dev, "unable to map key, shared descriptors\n");
-+              return -ENOMEM;
-+      }
-+
-+      for (i = 0; i < NUM_OP; i++)
-+              ctx->flc_dma[i] = dma_addr + i * sizeof(ctx->flc[i]);
-+      ctx->key_dma = dma_addr + NUM_OP * sizeof(ctx->flc[0]);
-+
-+      return 0;
-+}
-+
-+static int caam_cra_init_skcipher(struct crypto_skcipher *tfm)
-+{
-+      struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
-+      struct caam_skcipher_alg *caam_alg =
-+              container_of(alg, typeof(*caam_alg), skcipher);
-+
-+      crypto_skcipher_set_reqsize(tfm, sizeof(struct caam_request));
-+      return caam_cra_init(crypto_skcipher_ctx(tfm), &caam_alg->caam, false);
-+}
-+
-+static int caam_cra_init_aead(struct crypto_aead *tfm)
-+{
-+      struct aead_alg *alg = crypto_aead_alg(tfm);
-+      struct caam_aead_alg *caam_alg = container_of(alg, typeof(*caam_alg),
-+                                                    aead);
-+
-+      crypto_aead_set_reqsize(tfm, sizeof(struct caam_request));
-+      return caam_cra_init(crypto_aead_ctx(tfm), &caam_alg->caam,
-+                           (alg->setkey == aead_setkey) ||
-+                           (alg->setkey == tls_setkey));
-+}
-+
-+static void caam_exit_common(struct caam_ctx *ctx)
-+{
-+      dma_unmap_single_attrs(ctx->dev, ctx->flc_dma[0],
-+                             offsetof(struct caam_ctx, flc_dma), ctx->dir,
-+                             DMA_ATTR_SKIP_CPU_SYNC);
-+}
-+
-+static void caam_cra_exit(struct crypto_skcipher *tfm)
-+{
-+      caam_exit_common(crypto_skcipher_ctx(tfm));
-+}
-+
-+static void caam_cra_exit_aead(struct crypto_aead *tfm)
-+{
-+      caam_exit_common(crypto_aead_ctx(tfm));
-+}
-+
-+static struct caam_skcipher_alg driver_algs[] = {
-+      {
-+              .skcipher = {
-+                      .base = {
-+                              .cra_name = "cbc(aes)",
-+                              .cra_driver_name = "cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = skcipher_setkey,
-+                      .encrypt = skcipher_encrypt,
-+                      .decrypt = skcipher_decrypt,
-+                      .min_keysize = AES_MIN_KEY_SIZE,
-+                      .max_keysize = AES_MAX_KEY_SIZE,
-+                      .ivsize = AES_BLOCK_SIZE,
-+              },
-+              .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+      },
-+      {
-+              .skcipher = {
-+                      .base = {
-+                              .cra_name = "cbc(des3_ede)",
-+                              .cra_driver_name = "cbc-3des-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = skcipher_setkey,
-+                      .encrypt = skcipher_encrypt,
-+                      .decrypt = skcipher_decrypt,
-+                      .min_keysize = DES3_EDE_KEY_SIZE,
-+                      .max_keysize = DES3_EDE_KEY_SIZE,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+              },
-+              .caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+      },
-+      {
-+              .skcipher = {
-+                      .base = {
-+                              .cra_name = "cbc(des)",
-+                              .cra_driver_name = "cbc-des-caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = skcipher_setkey,
-+                      .encrypt = skcipher_encrypt,
-+                      .decrypt = skcipher_decrypt,
-+                      .min_keysize = DES_KEY_SIZE,
-+                      .max_keysize = DES_KEY_SIZE,
-+                      .ivsize = DES_BLOCK_SIZE,
-+              },
-+              .caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+      },
-+      {
-+              .skcipher = {
-+                      .base = {
-+                              .cra_name = "ctr(aes)",
-+                              .cra_driver_name = "ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = skcipher_setkey,
-+                      .encrypt = skcipher_encrypt,
-+                      .decrypt = skcipher_decrypt,
-+                      .min_keysize = AES_MIN_KEY_SIZE,
-+                      .max_keysize = AES_MAX_KEY_SIZE,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .chunksize = AES_BLOCK_SIZE,
-+              },
-+              .caam.class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                      OP_ALG_AAI_CTR_MOD128,
-+      },
-+      {
-+              .skcipher = {
-+                      .base = {
-+                              .cra_name = "rfc3686(ctr(aes))",
-+                              .cra_driver_name = "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = skcipher_setkey,
-+                      .encrypt = skcipher_encrypt,
-+                      .decrypt = skcipher_decrypt,
-+                      .min_keysize = AES_MIN_KEY_SIZE +
-+                                     CTR_RFC3686_NONCE_SIZE,
-+                      .max_keysize = AES_MAX_KEY_SIZE +
-+                                     CTR_RFC3686_NONCE_SIZE,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .chunksize = AES_BLOCK_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .rfc3686 = true,
-+              },
-+      },
-+      {
-+              .skcipher = {
-+                      .base = {
-+                              .cra_name = "xts(aes)",
-+                              .cra_driver_name = "xts-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = xts_skcipher_setkey,
-+                      .encrypt = skcipher_encrypt,
-+                      .decrypt = skcipher_decrypt,
-+                      .min_keysize = 2 * AES_MIN_KEY_SIZE,
-+                      .max_keysize = 2 * AES_MAX_KEY_SIZE,
-+                      .ivsize = AES_BLOCK_SIZE,
-+              },
-+              .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
-+      },
-+      {
-+              .skcipher = {
-+                      .base = {
-+                              .cra_name = "chacha20",
-+                              .cra_driver_name = "chacha20-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = skcipher_setkey,
-+                      .encrypt = skcipher_encrypt,
-+                      .decrypt = skcipher_decrypt,
-+                      .min_keysize = CHACHA20_KEY_SIZE,
-+                      .max_keysize = CHACHA20_KEY_SIZE,
-+                      .ivsize = CHACHA20_IV_SIZE,
-+              },
-+              .caam.class1_alg_type = OP_ALG_ALGSEL_CHACHA20,
-+      },
-+};
-+
-+static struct caam_aead_alg driver_aeads[] = {
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "rfc4106(gcm(aes))",
-+                              .cra_driver_name = "rfc4106-gcm-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = rfc4106_setkey,
-+                      .setauthsize = rfc4106_setauthsize,
-+                      .encrypt = ipsec_gcm_encrypt,
-+                      .decrypt = ipsec_gcm_decrypt,
-+                      .ivsize = 8,
-+                      .maxauthsize = AES_BLOCK_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "rfc4543(gcm(aes))",
-+                              .cra_driver_name = "rfc4543-gcm-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = rfc4543_setkey,
-+                      .setauthsize = rfc4543_setauthsize,
-+                      .encrypt = ipsec_gcm_encrypt,
-+                      .decrypt = ipsec_gcm_decrypt,
-+                      .ivsize = 8,
-+                      .maxauthsize = AES_BLOCK_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
-+              },
-+      },
-+      /* Galois Counter Mode */
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "gcm(aes)",
-+                              .cra_driver_name = "gcm-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = gcm_setkey,
-+                      .setauthsize = gcm_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = 12,
-+                      .maxauthsize = AES_BLOCK_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
-+              }
-+      },
-+      /* single-pass ipsec_esp descriptor */
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(md5),cbc(aes))",
-+                              .cra_driver_name = "authenc-hmac-md5-"
-+                                                 "cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = MD5_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_MD5 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(md5),"
-+                                          "cbc(aes)))",
-+                              .cra_driver_name = "echainiv-authenc-hmac-md5-"
-+                                                 "cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = MD5_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_MD5 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha1),cbc(aes))",
-+                              .cra_driver_name = "authenc-hmac-sha1-"
-+                                                 "cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha1),"
-+                                          "cbc(aes)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha1-cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha224),cbc(aes))",
-+                              .cra_driver_name = "authenc-hmac-sha224-"
-+                                                 "cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA224_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha224),"
-+                                          "cbc(aes)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha224-cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA224_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha256),cbc(aes))",
-+                              .cra_driver_name = "authenc-hmac-sha256-"
-+                                                 "cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA256_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha256),"
-+                                          "cbc(aes)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha256-cbc-aes-"
-+                                                 "caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA256_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha384),cbc(aes))",
-+                              .cra_driver_name = "authenc-hmac-sha384-"
-+                                                 "cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA384_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha384),"
-+                                          "cbc(aes)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha384-cbc-aes-"
-+                                                 "caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA384_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha512),cbc(aes))",
-+                              .cra_driver_name = "authenc-hmac-sha512-"
-+                                                 "cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA512_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha512),"
-+                                          "cbc(aes)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha512-cbc-aes-"
-+                                                 "caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA512_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
-+                              .cra_driver_name = "authenc-hmac-md5-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = MD5_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_MD5 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(md5),"
-+                                          "cbc(des3_ede)))",
-+                              .cra_driver_name = "echainiv-authenc-hmac-md5-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = MD5_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_MD5 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha1),"
-+                                          "cbc(des3_ede))",
-+                              .cra_driver_name = "authenc-hmac-sha1-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha1),"
-+                                          "cbc(des3_ede)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha1-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha224),"
-+                                          "cbc(des3_ede))",
-+                              .cra_driver_name = "authenc-hmac-sha224-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA224_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha224),"
-+                                          "cbc(des3_ede)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha224-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA224_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha256),"
-+                                          "cbc(des3_ede))",
-+                              .cra_driver_name = "authenc-hmac-sha256-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA256_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha256),"
-+                                          "cbc(des3_ede)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha256-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA256_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha384),"
-+                                          "cbc(des3_ede))",
-+                              .cra_driver_name = "authenc-hmac-sha384-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA384_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha384),"
-+                                          "cbc(des3_ede)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha384-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA384_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha512),"
-+                                          "cbc(des3_ede))",
-+                              .cra_driver_name = "authenc-hmac-sha512-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA512_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha512),"
-+                                          "cbc(des3_ede)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha512-"
-+                                                 "cbc-des3_ede-caam-qi2",
-+                              .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES3_EDE_BLOCK_SIZE,
-+                      .maxauthsize = SHA512_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(md5),cbc(des))",
-+                              .cra_driver_name = "authenc-hmac-md5-"
-+                                                 "cbc-des-caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = MD5_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_MD5 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(md5),"
-+                                          "cbc(des)))",
-+                              .cra_driver_name = "echainiv-authenc-hmac-md5-"
-+                                                 "cbc-des-caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = MD5_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_MD5 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha1),cbc(des))",
-+                              .cra_driver_name = "authenc-hmac-sha1-"
-+                                                 "cbc-des-caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha1),"
-+                                          "cbc(des)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha1-cbc-des-caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha224),cbc(des))",
-+                              .cra_driver_name = "authenc-hmac-sha224-"
-+                                                 "cbc-des-caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA224_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha224),"
-+                                          "cbc(des)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha224-cbc-des-"
-+                                                 "caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA224_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha256),cbc(des))",
-+                              .cra_driver_name = "authenc-hmac-sha256-"
-+                                                 "cbc-des-caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA256_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha256),"
-+                                          "cbc(des)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha256-cbc-desi-"
-+                                                 "caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA256_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha384),cbc(des))",
-+                              .cra_driver_name = "authenc-hmac-sha384-"
-+                                                 "cbc-des-caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA384_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha384),"
-+                                          "cbc(des)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha384-cbc-des-"
-+                                                 "caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA384_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha512),cbc(des))",
-+                              .cra_driver_name = "authenc-hmac-sha512-"
-+                                                 "cbc-des-caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA512_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "echainiv(authenc(hmac(sha512),"
-+                                          "cbc(des)))",
-+                              .cra_driver_name = "echainiv-authenc-"
-+                                                 "hmac-sha512-cbc-des-"
-+                                                 "caam-qi2",
-+                              .cra_blocksize = DES_BLOCK_SIZE,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = DES_BLOCK_SIZE,
-+                      .maxauthsize = SHA512_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .geniv = true,
-+              }
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(md5),"
-+                                          "rfc3686(ctr(aes)))",
-+                              .cra_driver_name = "authenc-hmac-md5-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = MD5_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_MD5 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "seqiv(authenc("
-+                                          "hmac(md5),rfc3686(ctr(aes))))",
-+                              .cra_driver_name = "seqiv-authenc-hmac-md5-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = MD5_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_MD5 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+                      .geniv = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha1),"
-+                                          "rfc3686(ctr(aes)))",
-+                              .cra_driver_name = "authenc-hmac-sha1-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "seqiv(authenc("
-+                                          "hmac(sha1),rfc3686(ctr(aes))))",
-+                              .cra_driver_name = "seqiv-authenc-hmac-sha1-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+                      .geniv = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha224),"
-+                                          "rfc3686(ctr(aes)))",
-+                              .cra_driver_name = "authenc-hmac-sha224-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA224_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "seqiv(authenc("
-+                                          "hmac(sha224),rfc3686(ctr(aes))))",
-+                              .cra_driver_name = "seqiv-authenc-hmac-sha224-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA224_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA224 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+                      .geniv = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha256),"
-+                                          "rfc3686(ctr(aes)))",
-+                              .cra_driver_name = "authenc-hmac-sha256-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA256_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "seqiv(authenc(hmac(sha256),"
-+                                          "rfc3686(ctr(aes))))",
-+                              .cra_driver_name = "seqiv-authenc-hmac-sha256-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA256_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA256 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+                      .geniv = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha384),"
-+                                          "rfc3686(ctr(aes)))",
-+                              .cra_driver_name = "authenc-hmac-sha384-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA384_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "seqiv(authenc(hmac(sha384),"
-+                                          "rfc3686(ctr(aes))))",
-+                              .cra_driver_name = "seqiv-authenc-hmac-sha384-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA384_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA384 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+                      .geniv = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "rfc7539(chacha20,poly1305)",
-+                              .cra_driver_name = "rfc7539-chacha20-poly1305-"
-+                                                 "caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = chachapoly_setkey,
-+                      .setauthsize = chachapoly_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CHACHAPOLY_IV_SIZE,
-+                      .maxauthsize = POLY1305_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
-+                                         OP_ALG_AAI_AEAD,
-+                      .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
-+                                         OP_ALG_AAI_AEAD,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "rfc7539esp(chacha20,poly1305)",
-+                              .cra_driver_name = "rfc7539esp-chacha20-"
-+                                                 "poly1305-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = chachapoly_setkey,
-+                      .setauthsize = chachapoly_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = 8,
-+                      .maxauthsize = POLY1305_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
-+                                         OP_ALG_AAI_AEAD,
-+                      .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
-+                                         OP_ALG_AAI_AEAD,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "authenc(hmac(sha512),"
-+                                          "rfc3686(ctr(aes)))",
-+                              .cra_driver_name = "authenc-hmac-sha512-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA512_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "seqiv(authenc(hmac(sha512),"
-+                                          "rfc3686(ctr(aes))))",
-+                              .cra_driver_name = "seqiv-authenc-hmac-sha512-"
-+                                                 "rfc3686-ctr-aes-caam-qi2",
-+                              .cra_blocksize = 1,
-+                      },
-+                      .setkey = aead_setkey,
-+                      .setauthsize = aead_setauthsize,
-+                      .encrypt = aead_encrypt,
-+                      .decrypt = aead_decrypt,
-+                      .ivsize = CTR_RFC3686_IV_SIZE,
-+                      .maxauthsize = SHA512_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES |
-+                                         OP_ALG_AAI_CTR_MOD128,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA512 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+                      .rfc3686 = true,
-+                      .geniv = true,
-+              },
-+      },
-+      {
-+              .aead = {
-+                      .base = {
-+                              .cra_name = "tls10(hmac(sha1),cbc(aes))",
-+                              .cra_driver_name = "tls10-hmac-sha1-cbc-aes-caam-qi2",
-+                              .cra_blocksize = AES_BLOCK_SIZE,
-+                      },
-+                      .setkey = tls_setkey,
-+                      .setauthsize = tls_setauthsize,
-+                      .encrypt = tls_encrypt,
-+                      .decrypt = tls_decrypt,
-+                      .ivsize = AES_BLOCK_SIZE,
-+                      .maxauthsize = SHA1_DIGEST_SIZE,
-+              },
-+              .caam = {
-+                      .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
-+                      .class2_alg_type = OP_ALG_ALGSEL_SHA1 |
-+                                         OP_ALG_AAI_HMAC_PRECOMP,
-+              },
-+      },
-+};
-+
-+static void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg)
-+{
-+      struct skcipher_alg *alg = &t_alg->skcipher;
-+
-+      alg->base.cra_module = THIS_MODULE;
-+      alg->base.cra_priority = CAAM_CRA_PRIORITY;
-+      alg->base.cra_ctxsize = sizeof(struct caam_ctx);
-+      alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
-+
-+      alg->init = caam_cra_init_skcipher;
-+      alg->exit = caam_cra_exit;
-+}
-+
-+static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
-+{
-+      struct aead_alg *alg = &t_alg->aead;
-+
-+      alg->base.cra_module = THIS_MODULE;
-+      alg->base.cra_priority = CAAM_CRA_PRIORITY;
-+      alg->base.cra_ctxsize = sizeof(struct caam_ctx);
-+      alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
-+
-+      alg->init = caam_cra_init_aead;
-+      alg->exit = caam_cra_exit_aead;
-+}
-+
-+/* max hash key is max split key size */
-+#define CAAM_MAX_HASH_KEY_SIZE                (SHA512_DIGEST_SIZE * 2)
-+
-+#define CAAM_MAX_HASH_BLOCK_SIZE      SHA512_BLOCK_SIZE
-+#define CAAM_MAX_HASH_DIGEST_SIZE     SHA512_DIGEST_SIZE
-+
-+#define DESC_HASH_MAX_USED_BYTES      (DESC_AHASH_FINAL_LEN + \
-+                                       CAAM_MAX_HASH_KEY_SIZE)
-+#define DESC_HASH_MAX_USED_LEN                (DESC_HASH_MAX_USED_BYTES / CAAM_CMD_SZ)
-+
-+/* caam context sizes for hashes: running digest + 8 */
-+#define HASH_MSG_LEN                  8
-+#define MAX_CTX_LEN                   (HASH_MSG_LEN + SHA512_DIGEST_SIZE)
-+
-+enum hash_optype {
-+      UPDATE = 0,
-+      UPDATE_FIRST,
-+      FINALIZE,
-+      DIGEST,
-+      HASH_NUM_OP
-+};
-+
-+/**
-+ * caam_hash_ctx - ahash per-session context
-+ * @flc: Flow Contexts array
-+ * @flc_dma: I/O virtual addresses of the Flow Contexts
-+ * @key:  virtual address of the authentication key
-+ * @dev: dpseci device
-+ * @ctx_len: size of Context Register
-+ * @adata: hashing algorithm details
-+ */
-+struct caam_hash_ctx {
-+      struct caam_flc flc[HASH_NUM_OP];
-+      dma_addr_t flc_dma[HASH_NUM_OP];
-+      u8 key[CAAM_MAX_HASH_KEY_SIZE];
-+      struct device *dev;
-+      int ctx_len;
-+      struct alginfo adata;
-+};
-+
-+/* ahash state */
-+struct caam_hash_state {
-+      struct caam_request caam_req;
-+      dma_addr_t buf_dma;
-+      dma_addr_t ctx_dma;
-+      u8 buf_0[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned;
-+      int buflen_0;
-+      u8 buf_1[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned;
-+      int buflen_1;
-+      u8 caam_ctx[MAX_CTX_LEN] ____cacheline_aligned;
-+      int (*update)(struct ahash_request *req);
-+      int (*final)(struct ahash_request *req);
-+      int (*finup)(struct ahash_request *req);
-+      int current_buf;
-+};
-+
-+struct caam_export_state {
-+      u8 buf[CAAM_MAX_HASH_BLOCK_SIZE];
-+      u8 caam_ctx[MAX_CTX_LEN];
-+      int buflen;
-+      int (*update)(struct ahash_request *req);
-+      int (*final)(struct ahash_request *req);
-+      int (*finup)(struct ahash_request *req);
-+};
-+
-+static inline void switch_buf(struct caam_hash_state *state)
-+{
-+      state->current_buf ^= 1;
-+}
-+
-+static inline u8 *current_buf(struct caam_hash_state *state)
-+{
-+      return state->current_buf ? state->buf_1 : state->buf_0;
-+}
-+
-+static inline u8 *alt_buf(struct caam_hash_state *state)
-+{
-+      return state->current_buf ? state->buf_0 : state->buf_1;
-+}
-+
-+static inline int *current_buflen(struct caam_hash_state *state)
-+{
-+      return state->current_buf ? &state->buflen_1 : &state->buflen_0;
-+}
-+
-+static inline int *alt_buflen(struct caam_hash_state *state)
-+{
-+      return state->current_buf ? &state->buflen_0 : &state->buflen_1;
-+}
-+
-+/* Map current buffer in state (if length > 0) and put it in link table */
-+static inline int buf_map_to_qm_sg(struct device *dev,
-+                                 struct dpaa2_sg_entry *qm_sg,
-+                                 struct caam_hash_state *state)
-+{
-+      int buflen = *current_buflen(state);
-+
-+      if (!buflen)
-+              return 0;
-+
-+      state->buf_dma = dma_map_single(dev, current_buf(state), buflen,
-+                                      DMA_TO_DEVICE);
-+      if (dma_mapping_error(dev, state->buf_dma)) {
-+              dev_err(dev, "unable to map buf\n");
-+              state->buf_dma = 0;
-+              return -ENOMEM;
-+      }
-+
-+      dma_to_qm_sg_one(qm_sg, state->buf_dma, buflen, 0);
-+
-+      return 0;
-+}
-+
-+/* Map state->caam_ctx, and add it to link table */
-+static inline int ctx_map_to_qm_sg(struct device *dev,
-+                                 struct caam_hash_state *state, int ctx_len,
-+                                 struct dpaa2_sg_entry *qm_sg, u32 flag)
-+{
-+      state->ctx_dma = dma_map_single(dev, state->caam_ctx, ctx_len, flag);
-+      if (dma_mapping_error(dev, state->ctx_dma)) {
-+              dev_err(dev, "unable to map ctx\n");
-+              state->ctx_dma = 0;
-+              return -ENOMEM;
-+      }
-+
-+      dma_to_qm_sg_one(qm_sg, state->ctx_dma, ctx_len, 0);
-+
-+      return 0;
-+}
-+
-+static int ahash_set_sh_desc(struct crypto_ahash *ahash)
-+{
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+      struct dpaa2_caam_priv *priv = dev_get_drvdata(ctx->dev);
-+      struct caam_flc *flc;
-+      u32 *desc;
-+
-+      ctx->adata.key_virt = ctx->key;
-+      ctx->adata.key_inline = true;
-+
-+      /* ahash_update shared descriptor */
-+      flc = &ctx->flc[UPDATE];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_UPDATE, ctx->ctx_len,
-+                        ctx->ctx_len, true, priv->sec_attr.era);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(ctx->dev, ctx->flc_dma[UPDATE],
-+                                 desc_bytes(desc), DMA_BIDIRECTIONAL);
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR,
-+                     "ahash update shdesc@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
-+#endif
-+
-+      /* ahash_update_first shared descriptor */
-+      flc = &ctx->flc[UPDATE_FIRST];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_INIT, ctx->ctx_len,
-+                        ctx->ctx_len, false, priv->sec_attr.era);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(ctx->dev, ctx->flc_dma[UPDATE_FIRST],
-+                                 desc_bytes(desc), DMA_BIDIRECTIONAL);
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR,
-+                     "ahash update first shdesc@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
-+#endif
-+
-+      /* ahash_final shared descriptor */
-+      flc = &ctx->flc[FINALIZE];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_FINALIZE, digestsize,
-+                        ctx->ctx_len, true, priv->sec_attr.era);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(ctx->dev, ctx->flc_dma[FINALIZE],
-+                                 desc_bytes(desc), DMA_BIDIRECTIONAL);
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR,
-+                     "ahash final shdesc@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
-+#endif
-+
-+      /* ahash_digest shared descriptor */
-+      flc = &ctx->flc[DIGEST];
-+      desc = flc->sh_desc;
-+      cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_INITFINAL, digestsize,
-+                        ctx->ctx_len, false, priv->sec_attr.era);
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      dma_sync_single_for_device(ctx->dev, ctx->flc_dma[DIGEST],
-+                                 desc_bytes(desc), DMA_BIDIRECTIONAL);
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR,
-+                     "ahash digest shdesc@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
-+#endif
-+
-+      return 0;
-+}
-+
-+/* Digest hash size if it is too large */
-+static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
-+                         u32 *keylen, u8 *key_out, u32 digestsize)
-+{
-+      struct caam_request *req_ctx;
-+      u32 *desc;
-+      struct split_key_sh_result result;
-+      dma_addr_t src_dma, dst_dma;
-+      struct caam_flc *flc;
-+      dma_addr_t flc_dma;
-+      int ret = -ENOMEM;
-+      struct dpaa2_fl_entry *in_fle, *out_fle;
-+
-+      req_ctx = kzalloc(sizeof(*req_ctx), GFP_KERNEL | GFP_DMA);
-+      if (!req_ctx)
-+              return -ENOMEM;
-+
-+      in_fle = &req_ctx->fd_flt[1];
-+      out_fle = &req_ctx->fd_flt[0];
-+
-+      flc = kzalloc(sizeof(*flc), GFP_KERNEL | GFP_DMA);
-+      if (!flc)
-+              goto err_flc;
-+
-+      src_dma = dma_map_single(ctx->dev, (void *)key_in, *keylen,
-+                               DMA_TO_DEVICE);
-+      if (dma_mapping_error(ctx->dev, src_dma)) {
-+              dev_err(ctx->dev, "unable to map key input memory\n");
-+              goto err_src_dma;
-+      }
-+      dst_dma = dma_map_single(ctx->dev, (void *)key_out, digestsize,
-+                               DMA_FROM_DEVICE);
-+      if (dma_mapping_error(ctx->dev, dst_dma)) {
-+              dev_err(ctx->dev, "unable to map key output memory\n");
-+              goto err_dst_dma;
-+      }
-+
-+      desc = flc->sh_desc;
-+
-+      init_sh_desc(desc, 0);
-+
-+      /* descriptor to perform unkeyed hash on key_in */
-+      append_operation(desc, ctx->adata.algtype | OP_ALG_ENCRYPT |
-+                       OP_ALG_AS_INITFINAL);
-+      append_seq_fifo_load(desc, *keylen, FIFOLD_CLASS_CLASS2 |
-+                           FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_MSG);
-+      append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
-+                       LDST_SRCDST_BYTE_CONTEXT);
-+
-+      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
-+      flc_dma = dma_map_single(ctx->dev, flc, sizeof(flc->flc) +
-+                               desc_bytes(desc), DMA_TO_DEVICE);
-+      if (dma_mapping_error(ctx->dev, flc_dma)) {
-+              dev_err(ctx->dev, "unable to map shared descriptor\n");
-+              goto err_flc_dma;
-+      }
-+
-+      dpaa2_fl_set_final(in_fle, true);
-+      dpaa2_fl_set_format(in_fle, dpaa2_fl_single);
-+      dpaa2_fl_set_addr(in_fle, src_dma);
-+      dpaa2_fl_set_len(in_fle, *keylen);
-+      dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+      dpaa2_fl_set_addr(out_fle, dst_dma);
-+      dpaa2_fl_set_len(out_fle, digestsize);
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "key_in@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, key_in, *keylen, 1);
-+      print_hex_dump(KERN_ERR, "shdesc@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
-+#endif
-+
-+      result.err = 0;
-+      init_completion(&result.completion);
-+      result.dev = ctx->dev;
-+
-+      req_ctx->flc = flc;
-+      req_ctx->flc_dma = flc_dma;
-+      req_ctx->cbk = split_key_sh_done;
-+      req_ctx->ctx = &result;
-+
-+      ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
-+      if (ret == -EINPROGRESS) {
-+              /* in progress */
-+              wait_for_completion(&result.completion);
-+              ret = result.err;
-+#ifdef DEBUG
-+              print_hex_dump(KERN_ERR,
-+                             "digested key@" __stringify(__LINE__)": ",
-+                             DUMP_PREFIX_ADDRESS, 16, 4, key_in, digestsize,
-+                             1);
-+#endif
-+      }
-+
-+      dma_unmap_single(ctx->dev, flc_dma, sizeof(flc->flc) + desc_bytes(desc),
-+                       DMA_TO_DEVICE);
-+err_flc_dma:
-+      dma_unmap_single(ctx->dev, dst_dma, digestsize, DMA_FROM_DEVICE);
-+err_dst_dma:
-+      dma_unmap_single(ctx->dev, src_dma, *keylen, DMA_TO_DEVICE);
-+err_src_dma:
-+      kfree(flc);
-+err_flc:
-+      kfree(req_ctx);
-+
-+      *keylen = digestsize;
-+
-+      return ret;
-+}
-+
-+static int ahash_setkey(struct crypto_ahash *ahash, const u8 *key,
-+                      unsigned int keylen)
-+{
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      unsigned int blocksize = crypto_tfm_alg_blocksize(&ahash->base);
-+      unsigned int digestsize = crypto_ahash_digestsize(ahash);
-+      int ret;
-+      u8 *hashed_key = NULL;
-+
-+#ifdef DEBUG
-+      dev_err(ctx->dev, "keylen %d blocksize %d\n", keylen, blocksize);
-+#endif
-+
-+      if (keylen > blocksize) {
-+              hashed_key = kmalloc_array(digestsize, sizeof(*hashed_key),
-+                                         GFP_KERNEL | GFP_DMA);
-+              if (!hashed_key)
-+                      return -ENOMEM;
-+              ret = hash_digest_key(ctx, key, &keylen, hashed_key,
-+                                    digestsize);
-+              if (ret)
-+                      goto bad_free_key;
-+              key = hashed_key;
-+      }
-+
-+      ctx->adata.keylen = keylen;
-+      ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
-+                                            OP_ALG_ALGSEL_MASK);
-+      if (ctx->adata.keylen_pad > CAAM_MAX_HASH_KEY_SIZE)
-+              goto bad_free_key;
-+
-+      memcpy(ctx->key, key, keylen);
-+
-+      kfree(hashed_key);
-+      return ahash_set_sh_desc(ahash);
-+bad_free_key:
-+      kfree(hashed_key);
-+      crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+      return -EINVAL;
-+}
-+
-+static inline void ahash_unmap(struct device *dev, struct ahash_edesc *edesc,
-+                             struct ahash_request *req, int dst_len)
-+{
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+
-+      if (edesc->src_nents)
-+              dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE);
-+      if (edesc->dst_dma)
-+              dma_unmap_single(dev, edesc->dst_dma, dst_len, DMA_FROM_DEVICE);
-+
-+      if (edesc->qm_sg_bytes)
-+              dma_unmap_single(dev, edesc->qm_sg_dma, edesc->qm_sg_bytes,
-+                               DMA_TO_DEVICE);
-+
-+      if (state->buf_dma) {
-+              dma_unmap_single(dev, state->buf_dma, *current_buflen(state),
-+                               DMA_TO_DEVICE);
-+              state->buf_dma = 0;
-+      }
-+}
-+
-+static inline void ahash_unmap_ctx(struct device *dev,
-+                                 struct ahash_edesc *edesc,
-+                                 struct ahash_request *req, int dst_len,
-+                                 u32 flag)
-+{
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+
-+      if (state->ctx_dma) {
-+              dma_unmap_single(dev, state->ctx_dma, ctx->ctx_len, flag);
-+              state->ctx_dma = 0;
-+      }
-+      ahash_unmap(dev, edesc, req, dst_len);
-+}
-+
-+static void ahash_done(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct ahash_request *req = ahash_request_cast(areq);
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct ahash_edesc *edesc = state->caam_req.edesc;
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+      int ecode = 0;
-+
-+#ifdef DEBUG
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              ecode = -EIO;
-+      }
-+
-+      ahash_unmap(ctx->dev, edesc, req, digestsize);
-+      qi_cache_free(edesc);
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "ctx@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
-+                     ctx->ctx_len, 1);
-+      if (req->result)
-+              print_hex_dump(KERN_ERR, "result@" __stringify(__LINE__)": ",
-+                             DUMP_PREFIX_ADDRESS, 16, 4, req->result,
-+                             digestsize, 1);
-+#endif
-+
-+      req->base.complete(&req->base, ecode);
-+}
-+
-+static void ahash_done_bi(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct ahash_request *req = ahash_request_cast(areq);
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct ahash_edesc *edesc = state->caam_req.edesc;
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      int ecode = 0;
-+#ifdef DEBUG
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              ecode = -EIO;
-+      }
-+
-+      ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_BIDIRECTIONAL);
-+      switch_buf(state);
-+      qi_cache_free(edesc);
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "ctx@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
-+                     ctx->ctx_len, 1);
-+      if (req->result)
-+              print_hex_dump(KERN_ERR, "result@" __stringify(__LINE__)": ",
-+                             DUMP_PREFIX_ADDRESS, 16, 4, req->result,
-+                             digestsize, 1);
-+#endif
-+
-+      req->base.complete(&req->base, ecode);
-+}
-+
-+static void ahash_done_ctx_src(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct ahash_request *req = ahash_request_cast(areq);
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct ahash_edesc *edesc = state->caam_req.edesc;
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+      int ecode = 0;
-+
-+#ifdef DEBUG
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              ecode = -EIO;
-+      }
-+
-+      ahash_unmap_ctx(ctx->dev, edesc, req, digestsize, DMA_TO_DEVICE);
-+      qi_cache_free(edesc);
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "ctx@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
-+                     ctx->ctx_len, 1);
-+      if (req->result)
-+              print_hex_dump(KERN_ERR, "result@" __stringify(__LINE__)": ",
-+                             DUMP_PREFIX_ADDRESS, 16, 4, req->result,
-+                             digestsize, 1);
-+#endif
-+
-+      req->base.complete(&req->base, ecode);
-+}
-+
-+static void ahash_done_ctx_dst(void *cbk_ctx, u32 status)
-+{
-+      struct crypto_async_request *areq = cbk_ctx;
-+      struct ahash_request *req = ahash_request_cast(areq);
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct ahash_edesc *edesc = state->caam_req.edesc;
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      int ecode = 0;
-+#ifdef DEBUG
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+
-+      dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status);
-+#endif
-+
-+      if (unlikely(status)) {
-+              caam_qi2_strstatus(ctx->dev, status);
-+              ecode = -EIO;
-+      }
-+
-+      ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_FROM_DEVICE);
-+      switch_buf(state);
-+      qi_cache_free(edesc);
-+
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "ctx@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx,
-+                     ctx->ctx_len, 1);
-+      if (req->result)
-+              print_hex_dump(KERN_ERR, "result@" __stringify(__LINE__)": ",
-+                             DUMP_PREFIX_ADDRESS, 16, 4, req->result,
-+                             digestsize, 1);
-+#endif
-+
-+      req->base.complete(&req->base, ecode);
-+}
-+
-+static int ahash_update_ctx(struct ahash_request *req)
-+{
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct caam_request *req_ctx = &state->caam_req;
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      u8 *buf = current_buf(state);
-+      int *buflen = current_buflen(state);
-+      u8 *next_buf = alt_buf(state);
-+      int *next_buflen = alt_buflen(state), last_buflen;
-+      int in_len = *buflen + req->nbytes, to_hash;
-+      int src_nents, mapped_nents, qm_sg_bytes, qm_sg_src_index;
-+      struct ahash_edesc *edesc;
-+      int ret = 0;
-+
-+      last_buflen = *next_buflen;
-+      *next_buflen = in_len & (crypto_tfm_alg_blocksize(&ahash->base) - 1);
-+      to_hash = in_len - *next_buflen;
-+
-+      if (to_hash) {
-+              struct dpaa2_sg_entry *sg_table;
-+
-+              src_nents = sg_nents_for_len(req->src,
-+                                           req->nbytes - (*next_buflen));
-+              if (src_nents < 0) {
-+                      dev_err(ctx->dev, "Invalid number of src SG.\n");
-+                      return src_nents;
-+              }
-+
-+              if (src_nents) {
-+                      mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
-+                                                DMA_TO_DEVICE);
-+                      if (!mapped_nents) {
-+                              dev_err(ctx->dev, "unable to DMA map source\n");
-+                              return -ENOMEM;
-+                      }
-+              } else {
-+                      mapped_nents = 0;
-+              }
-+
-+              /* allocate space for base edesc and link tables */
-+              edesc = qi_cache_zalloc(GFP_DMA | flags);
-+              if (!edesc) {
-+                      dma_unmap_sg(ctx->dev, req->src, src_nents,
-+                                   DMA_TO_DEVICE);
-+                      return -ENOMEM;
-+              }
-+
-+              edesc->src_nents = src_nents;
-+              qm_sg_src_index = 1 + (*buflen ? 1 : 0);
-+              qm_sg_bytes = (qm_sg_src_index + mapped_nents) *
-+                            sizeof(*sg_table);
-+              sg_table = &edesc->sgt[0];
-+
-+              ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table,
-+                                     DMA_BIDIRECTIONAL);
-+              if (ret)
-+                      goto unmap_ctx;
-+
-+              ret = buf_map_to_qm_sg(ctx->dev, sg_table + 1, state);
-+              if (ret)
-+                      goto unmap_ctx;
-+
-+              if (mapped_nents) {
-+                      sg_to_qm_sg_last(req->src, mapped_nents,
-+                                       sg_table + qm_sg_src_index, 0);
-+                      if (*next_buflen)
-+                              scatterwalk_map_and_copy(next_buf, req->src,
-+                                                       to_hash - *buflen,
-+                                                       *next_buflen, 0);
-+              } else {
-+                      dpaa2_sg_set_final(sg_table + qm_sg_src_index - 1,
-+                                         true);
-+              }
-+
-+              edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table,
-+                                                qm_sg_bytes, DMA_TO_DEVICE);
-+              if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
-+                      dev_err(ctx->dev, "unable to map S/G table\n");
-+                      ret = -ENOMEM;
-+                      goto unmap_ctx;
-+              }
-+              edesc->qm_sg_bytes = qm_sg_bytes;
-+
-+              memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+              dpaa2_fl_set_final(in_fle, true);
-+              dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+              dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
-+              dpaa2_fl_set_len(in_fle, ctx->ctx_len + to_hash);
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+              dpaa2_fl_set_addr(out_fle, state->ctx_dma);
-+              dpaa2_fl_set_len(out_fle, ctx->ctx_len);
-+
-+              req_ctx->flc = &ctx->flc[UPDATE];
-+              req_ctx->flc_dma = ctx->flc_dma[UPDATE];
-+              req_ctx->cbk = ahash_done_bi;
-+              req_ctx->ctx = &req->base;
-+              req_ctx->edesc = edesc;
-+
-+              ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
-+              if (ret != -EINPROGRESS &&
-+                  !(ret == -EBUSY &&
-+                    req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
-+                      goto unmap_ctx;
-+      } else if (*next_buflen) {
-+              scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
-+                                       req->nbytes, 0);
-+              *buflen = *next_buflen;
-+              *next_buflen = last_buflen;
-+      }
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "buf@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, buf, *buflen, 1);
-+      print_hex_dump(KERN_ERR, "next buf@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, next_buf,
-+                     *next_buflen, 1);
-+#endif
-+
-+      return ret;
-+unmap_ctx:
-+      ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_BIDIRECTIONAL);
-+      qi_cache_free(edesc);
-+      return ret;
-+}
-+
-+static int ahash_final_ctx(struct ahash_request *req)
-+{
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct caam_request *req_ctx = &state->caam_req;
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      int buflen = *current_buflen(state);
-+      int qm_sg_bytes, qm_sg_src_index;
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+      struct ahash_edesc *edesc;
-+      struct dpaa2_sg_entry *sg_table;
-+      int ret;
-+
-+      /* allocate space for base edesc and link tables */
-+      edesc = qi_cache_zalloc(GFP_DMA | flags);
-+      if (!edesc)
-+              return -ENOMEM;
-+
-+      qm_sg_src_index = 1 + (buflen ? 1 : 0);
-+      qm_sg_bytes = qm_sg_src_index * sizeof(*sg_table);
-+      sg_table = &edesc->sgt[0];
-+
-+      ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table,
-+                             DMA_TO_DEVICE);
-+      if (ret)
-+              goto unmap_ctx;
-+
-+      ret = buf_map_to_qm_sg(ctx->dev, sg_table + 1, state);
-+      if (ret)
-+              goto unmap_ctx;
-+
-+      dpaa2_sg_set_final(sg_table + qm_sg_src_index - 1, true);
-+
-+      edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, qm_sg_bytes,
-+                                        DMA_TO_DEVICE);
-+      if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
-+              dev_err(ctx->dev, "unable to map S/G table\n");
-+              ret = -ENOMEM;
-+              goto unmap_ctx;
-+      }
-+      edesc->qm_sg_bytes = qm_sg_bytes;
-+
-+      edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize,
-+                                      DMA_FROM_DEVICE);
-+      if (dma_mapping_error(ctx->dev, edesc->dst_dma)) {
-+              dev_err(ctx->dev, "unable to map dst\n");
-+              edesc->dst_dma = 0;
-+              ret = -ENOMEM;
-+              goto unmap_ctx;
-+      }
-+
-+      memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+      dpaa2_fl_set_final(in_fle, true);
-+      dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+      dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
-+      dpaa2_fl_set_len(in_fle, ctx->ctx_len + buflen);
-+      dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+      dpaa2_fl_set_addr(out_fle, edesc->dst_dma);
-+      dpaa2_fl_set_len(out_fle, digestsize);
-+
-+      req_ctx->flc = &ctx->flc[FINALIZE];
-+      req_ctx->flc_dma = ctx->flc_dma[FINALIZE];
-+      req_ctx->cbk = ahash_done_ctx_src;
-+      req_ctx->ctx = &req->base;
-+      req_ctx->edesc = edesc;
-+
-+      ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
-+      if (ret == -EINPROGRESS ||
-+          (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
-+              return ret;
-+
-+unmap_ctx:
-+      ahash_unmap_ctx(ctx->dev, edesc, req, digestsize, DMA_FROM_DEVICE);
-+      qi_cache_free(edesc);
-+      return ret;
-+}
-+
-+static int ahash_finup_ctx(struct ahash_request *req)
-+{
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct caam_request *req_ctx = &state->caam_req;
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      int buflen = *current_buflen(state);
-+      int qm_sg_bytes, qm_sg_src_index;
-+      int src_nents, mapped_nents;
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+      struct ahash_edesc *edesc;
-+      struct dpaa2_sg_entry *sg_table;
-+      int ret;
-+
-+      src_nents = sg_nents_for_len(req->src, req->nbytes);
-+      if (src_nents < 0) {
-+              dev_err(ctx->dev, "Invalid number of src SG.\n");
-+              return src_nents;
-+      }
-+
-+      if (src_nents) {
-+              mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
-+                                        DMA_TO_DEVICE);
-+              if (!mapped_nents) {
-+                      dev_err(ctx->dev, "unable to DMA map source\n");
-+                      return -ENOMEM;
-+              }
-+      } else {
-+              mapped_nents = 0;
-+      }
-+
-+      /* allocate space for base edesc and link tables */
-+      edesc = qi_cache_zalloc(GFP_DMA | flags);
-+      if (!edesc) {
-+              dma_unmap_sg(ctx->dev, req->src, src_nents, DMA_TO_DEVICE);
-+              return -ENOMEM;
-+      }
-+
-+      edesc->src_nents = src_nents;
-+      qm_sg_src_index = 1 + (buflen ? 1 : 0);
-+      qm_sg_bytes = (qm_sg_src_index + mapped_nents) * sizeof(*sg_table);
-+      sg_table = &edesc->sgt[0];
-+
-+      ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table,
-+                             DMA_TO_DEVICE);
-+      if (ret)
-+              goto unmap_ctx;
-+
-+      ret = buf_map_to_qm_sg(ctx->dev, sg_table + 1, state);
-+      if (ret)
-+              goto unmap_ctx;
-+
-+      sg_to_qm_sg_last(req->src, mapped_nents, sg_table + qm_sg_src_index, 0);
-+
-+      edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, qm_sg_bytes,
-+                                        DMA_TO_DEVICE);
-+      if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
-+              dev_err(ctx->dev, "unable to map S/G table\n");
-+              ret = -ENOMEM;
-+              goto unmap_ctx;
-+      }
-+      edesc->qm_sg_bytes = qm_sg_bytes;
-+
-+      edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize,
-+                                      DMA_FROM_DEVICE);
-+      if (dma_mapping_error(ctx->dev, edesc->dst_dma)) {
-+              dev_err(ctx->dev, "unable to map dst\n");
-+              edesc->dst_dma = 0;
-+              ret = -ENOMEM;
-+              goto unmap_ctx;
-+      }
-+
-+      memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+      dpaa2_fl_set_final(in_fle, true);
-+      dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+      dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
-+      dpaa2_fl_set_len(in_fle, ctx->ctx_len + buflen + req->nbytes);
-+      dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+      dpaa2_fl_set_addr(out_fle, edesc->dst_dma);
-+      dpaa2_fl_set_len(out_fle, digestsize);
-+
-+      req_ctx->flc = &ctx->flc[FINALIZE];
-+      req_ctx->flc_dma = ctx->flc_dma[FINALIZE];
-+      req_ctx->cbk = ahash_done_ctx_src;
-+      req_ctx->ctx = &req->base;
-+      req_ctx->edesc = edesc;
-+
-+      ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
-+      if (ret == -EINPROGRESS ||
-+          (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
-+              return ret;
-+
-+unmap_ctx:
-+      ahash_unmap_ctx(ctx->dev, edesc, req, digestsize, DMA_FROM_DEVICE);
-+      qi_cache_free(edesc);
-+      return ret;
-+}
-+
-+static int ahash_digest(struct ahash_request *req)
-+{
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct caam_request *req_ctx = &state->caam_req;
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+      int src_nents, mapped_nents;
-+      struct ahash_edesc *edesc;
-+      int ret = -ENOMEM;
-+
-+      state->buf_dma = 0;
-+
-+      src_nents = sg_nents_for_len(req->src, req->nbytes);
-+      if (src_nents < 0) {
-+              dev_err(ctx->dev, "Invalid number of src SG.\n");
-+              return src_nents;
-+      }
-+
-+      if (src_nents) {
-+              mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
-+                                        DMA_TO_DEVICE);
-+              if (!mapped_nents) {
-+                      dev_err(ctx->dev, "unable to map source for DMA\n");
-+                      return ret;
-+              }
-+      } else {
-+              mapped_nents = 0;
-+      }
-+
-+      /* allocate space for base edesc and link tables */
-+      edesc = qi_cache_zalloc(GFP_DMA | flags);
-+      if (!edesc) {
-+              dma_unmap_sg(ctx->dev, req->src, src_nents, DMA_TO_DEVICE);
-+              return ret;
-+      }
-+
-+      edesc->src_nents = src_nents;
-+      memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+
-+      if (mapped_nents > 1) {
-+              int qm_sg_bytes;
-+              struct dpaa2_sg_entry *sg_table = &edesc->sgt[0];
-+
-+              qm_sg_bytes = mapped_nents * sizeof(*sg_table);
-+              sg_to_qm_sg_last(req->src, mapped_nents, sg_table, 0);
-+              edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table,
-+                                                qm_sg_bytes, DMA_TO_DEVICE);
-+              if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
-+                      dev_err(ctx->dev, "unable to map S/G table\n");
-+                      goto unmap;
-+              }
-+              edesc->qm_sg_bytes = qm_sg_bytes;
-+              dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+              dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
-+      } else {
-+              dpaa2_fl_set_format(in_fle, dpaa2_fl_single);
-+              dpaa2_fl_set_addr(in_fle, sg_dma_address(req->src));
-+      }
-+
-+      edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize,
-+                                      DMA_FROM_DEVICE);
-+      if (dma_mapping_error(ctx->dev, edesc->dst_dma)) {
-+              dev_err(ctx->dev, "unable to map dst\n");
-+              edesc->dst_dma = 0;
-+              goto unmap;
-+      }
-+
-+      dpaa2_fl_set_final(in_fle, true);
-+      dpaa2_fl_set_len(in_fle, req->nbytes);
-+      dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+      dpaa2_fl_set_addr(out_fle, edesc->dst_dma);
-+      dpaa2_fl_set_len(out_fle, digestsize);
-+
-+      req_ctx->flc = &ctx->flc[DIGEST];
-+      req_ctx->flc_dma = ctx->flc_dma[DIGEST];
-+      req_ctx->cbk = ahash_done;
-+      req_ctx->ctx = &req->base;
-+      req_ctx->edesc = edesc;
-+      ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
-+      if (ret == -EINPROGRESS ||
-+          (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
-+              return ret;
-+
-+unmap:
-+      ahash_unmap(ctx->dev, edesc, req, digestsize);
-+      qi_cache_free(edesc);
-+      return ret;
-+}
-+
-+static int ahash_final_no_ctx(struct ahash_request *req)
-+{
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct caam_request *req_ctx = &state->caam_req;
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      u8 *buf = current_buf(state);
-+      int buflen = *current_buflen(state);
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+      struct ahash_edesc *edesc;
-+      int ret = -ENOMEM;
-+
-+      /* allocate space for base edesc and link tables */
-+      edesc = qi_cache_zalloc(GFP_DMA | flags);
-+      if (!edesc)
-+              return ret;
-+
-+      state->buf_dma = dma_map_single(ctx->dev, buf, buflen, DMA_TO_DEVICE);
-+      if (dma_mapping_error(ctx->dev, state->buf_dma)) {
-+              dev_err(ctx->dev, "unable to map src\n");
-+              goto unmap;
-+      }
-+
-+      edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize,
-+                                      DMA_FROM_DEVICE);
-+      if (dma_mapping_error(ctx->dev, edesc->dst_dma)) {
-+              dev_err(ctx->dev, "unable to map dst\n");
-+              edesc->dst_dma = 0;
-+              goto unmap;
-+      }
-+
-+      memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+      dpaa2_fl_set_final(in_fle, true);
-+      dpaa2_fl_set_format(in_fle, dpaa2_fl_single);
-+      dpaa2_fl_set_addr(in_fle, state->buf_dma);
-+      dpaa2_fl_set_len(in_fle, buflen);
-+      dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+      dpaa2_fl_set_addr(out_fle, edesc->dst_dma);
-+      dpaa2_fl_set_len(out_fle, digestsize);
-+
-+      req_ctx->flc = &ctx->flc[DIGEST];
-+      req_ctx->flc_dma = ctx->flc_dma[DIGEST];
-+      req_ctx->cbk = ahash_done;
-+      req_ctx->ctx = &req->base;
-+      req_ctx->edesc = edesc;
-+
-+      ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
-+      if (ret == -EINPROGRESS ||
-+          (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
-+              return ret;
-+
-+unmap:
-+      ahash_unmap(ctx->dev, edesc, req, digestsize);
-+      qi_cache_free(edesc);
-+      return ret;
-+}
-+
-+static int ahash_update_no_ctx(struct ahash_request *req)
-+{
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct caam_request *req_ctx = &state->caam_req;
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      u8 *buf = current_buf(state);
-+      int *buflen = current_buflen(state);
-+      u8 *next_buf = alt_buf(state);
-+      int *next_buflen = alt_buflen(state);
-+      int in_len = *buflen + req->nbytes, to_hash;
-+      int qm_sg_bytes, src_nents, mapped_nents;
-+      struct ahash_edesc *edesc;
-+      int ret = 0;
-+
-+      *next_buflen = in_len & (crypto_tfm_alg_blocksize(&ahash->base) - 1);
-+      to_hash = in_len - *next_buflen;
-+
-+      if (to_hash) {
-+              struct dpaa2_sg_entry *sg_table;
-+
-+              src_nents = sg_nents_for_len(req->src,
-+                                           req->nbytes - *next_buflen);
-+              if (src_nents < 0) {
-+                      dev_err(ctx->dev, "Invalid number of src SG.\n");
-+                      return src_nents;
-+              }
-+
-+              if (src_nents) {
-+                      mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
-+                                                DMA_TO_DEVICE);
-+                      if (!mapped_nents) {
-+                              dev_err(ctx->dev, "unable to DMA map source\n");
-+                              return -ENOMEM;
-+                      }
-+              } else {
-+                      mapped_nents = 0;
-+              }
-+
-+              /* allocate space for base edesc and link tables */
-+              edesc = qi_cache_zalloc(GFP_DMA | flags);
-+              if (!edesc) {
-+                      dma_unmap_sg(ctx->dev, req->src, src_nents,
-+                                   DMA_TO_DEVICE);
-+                      return -ENOMEM;
-+              }
-+
-+              edesc->src_nents = src_nents;
-+              qm_sg_bytes = (1 + mapped_nents) * sizeof(*sg_table);
-+              sg_table = &edesc->sgt[0];
-+
-+              ret = buf_map_to_qm_sg(ctx->dev, sg_table, state);
-+              if (ret)
-+                      goto unmap_ctx;
-+
-+              sg_to_qm_sg_last(req->src, mapped_nents, sg_table + 1, 0);
-+
-+              if (*next_buflen)
-+                      scatterwalk_map_and_copy(next_buf, req->src,
-+                                               to_hash - *buflen,
-+                                               *next_buflen, 0);
-+
-+              edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table,
-+                                                qm_sg_bytes, DMA_TO_DEVICE);
-+              if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
-+                      dev_err(ctx->dev, "unable to map S/G table\n");
-+                      ret = -ENOMEM;
-+                      goto unmap_ctx;
-+              }
-+              edesc->qm_sg_bytes = qm_sg_bytes;
-+
-+              state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx,
-+                                              ctx->ctx_len, DMA_FROM_DEVICE);
-+              if (dma_mapping_error(ctx->dev, state->ctx_dma)) {
-+                      dev_err(ctx->dev, "unable to map ctx\n");
-+                      state->ctx_dma = 0;
-+                      ret = -ENOMEM;
-+                      goto unmap_ctx;
-+              }
-+
-+              memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+              dpaa2_fl_set_final(in_fle, true);
-+              dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+              dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
-+              dpaa2_fl_set_len(in_fle, to_hash);
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+              dpaa2_fl_set_addr(out_fle, state->ctx_dma);
-+              dpaa2_fl_set_len(out_fle, ctx->ctx_len);
-+
-+              req_ctx->flc = &ctx->flc[UPDATE_FIRST];
-+              req_ctx->flc_dma = ctx->flc_dma[UPDATE_FIRST];
-+              req_ctx->cbk = ahash_done_ctx_dst;
-+              req_ctx->ctx = &req->base;
-+              req_ctx->edesc = edesc;
-+
-+              ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
-+              if (ret != -EINPROGRESS &&
-+                  !(ret == -EBUSY &&
-+                    req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
-+                      goto unmap_ctx;
-+
-+              state->update = ahash_update_ctx;
-+              state->finup = ahash_finup_ctx;
-+              state->final = ahash_final_ctx;
-+      } else if (*next_buflen) {
-+              scatterwalk_map_and_copy(buf + *buflen, req->src, 0,
-+                                       req->nbytes, 0);
-+              *buflen = *next_buflen;
-+              *next_buflen = 0;
-+      }
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "buf@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, buf, *buflen, 1);
-+      print_hex_dump(KERN_ERR, "next buf@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, next_buf,
-+                     *next_buflen, 1);
-+#endif
-+
-+      return ret;
-+unmap_ctx:
-+      ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_TO_DEVICE);
-+      qi_cache_free(edesc);
-+      return ret;
-+}
-+
-+static int ahash_finup_no_ctx(struct ahash_request *req)
-+{
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct caam_request *req_ctx = &state->caam_req;
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      int buflen = *current_buflen(state);
-+      int qm_sg_bytes, src_nents, mapped_nents;
-+      int digestsize = crypto_ahash_digestsize(ahash);
-+      struct ahash_edesc *edesc;
-+      struct dpaa2_sg_entry *sg_table;
-+      int ret;
-+
-+      src_nents = sg_nents_for_len(req->src, req->nbytes);
-+      if (src_nents < 0) {
-+              dev_err(ctx->dev, "Invalid number of src SG.\n");
-+              return src_nents;
-+      }
-+
-+      if (src_nents) {
-+              mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
-+                                        DMA_TO_DEVICE);
-+              if (!mapped_nents) {
-+                      dev_err(ctx->dev, "unable to DMA map source\n");
-+                      return -ENOMEM;
-+              }
-+      } else {
-+              mapped_nents = 0;
-+      }
-+
-+      /* allocate space for base edesc and link tables */
-+      edesc = qi_cache_zalloc(GFP_DMA | flags);
-+      if (!edesc) {
-+              dma_unmap_sg(ctx->dev, req->src, src_nents, DMA_TO_DEVICE);
-+              return -ENOMEM;
-+      }
-+
-+      edesc->src_nents = src_nents;
-+      qm_sg_bytes = (2 + mapped_nents) * sizeof(*sg_table);
-+      sg_table = &edesc->sgt[0];
-+
-+      ret = buf_map_to_qm_sg(ctx->dev, sg_table, state);
-+      if (ret)
-+              goto unmap;
-+
-+      sg_to_qm_sg_last(req->src, mapped_nents, sg_table + 1, 0);
-+
-+      edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, qm_sg_bytes,
-+                                        DMA_TO_DEVICE);
-+      if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
-+              dev_err(ctx->dev, "unable to map S/G table\n");
-+              ret = -ENOMEM;
-+              goto unmap;
-+      }
-+      edesc->qm_sg_bytes = qm_sg_bytes;
-+
-+      edesc->dst_dma = dma_map_single(ctx->dev, req->result, digestsize,
-+                                      DMA_FROM_DEVICE);
-+      if (dma_mapping_error(ctx->dev, edesc->dst_dma)) {
-+              dev_err(ctx->dev, "unable to map dst\n");
-+              edesc->dst_dma = 0;
-+              ret = -ENOMEM;
-+              goto unmap;
-+      }
-+
-+      memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+      dpaa2_fl_set_final(in_fle, true);
-+      dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+      dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
-+      dpaa2_fl_set_len(in_fle, buflen + req->nbytes);
-+      dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+      dpaa2_fl_set_addr(out_fle, edesc->dst_dma);
-+      dpaa2_fl_set_len(out_fle, digestsize);
-+
-+      req_ctx->flc = &ctx->flc[DIGEST];
-+      req_ctx->flc_dma = ctx->flc_dma[DIGEST];
-+      req_ctx->cbk = ahash_done;
-+      req_ctx->ctx = &req->base;
-+      req_ctx->edesc = edesc;
-+      ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
-+      if (ret != -EINPROGRESS &&
-+          !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
-+              goto unmap;
-+
-+      return ret;
-+unmap:
-+      ahash_unmap(ctx->dev, edesc, req, digestsize);
-+      qi_cache_free(edesc);
-+      return -ENOMEM;
-+}
-+
-+static int ahash_update_first(struct ahash_request *req)
-+{
-+      struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
-+      struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct caam_request *req_ctx = &state->caam_req;
-+      struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1];
-+      struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0];
-+      gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
-+                    GFP_KERNEL : GFP_ATOMIC;
-+      u8 *next_buf = alt_buf(state);
-+      int *next_buflen = alt_buflen(state);
-+      int to_hash;
-+      int src_nents, mapped_nents;
-+      struct ahash_edesc *edesc;
-+      int ret = 0;
-+
-+      *next_buflen = req->nbytes & (crypto_tfm_alg_blocksize(&ahash->base) -
-+                                    1);
-+      to_hash = req->nbytes - *next_buflen;
-+
-+      if (to_hash) {
-+              struct dpaa2_sg_entry *sg_table;
-+
-+              src_nents = sg_nents_for_len(req->src,
-+                                           req->nbytes - (*next_buflen));
-+              if (src_nents < 0) {
-+                      dev_err(ctx->dev, "Invalid number of src SG.\n");
-+                      return src_nents;
-+              }
-+
-+              if (src_nents) {
-+                      mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents,
-+                                                DMA_TO_DEVICE);
-+                      if (!mapped_nents) {
-+                              dev_err(ctx->dev, "unable to map source for DMA\n");
-+                              return -ENOMEM;
-+                      }
-+              } else {
-+                      mapped_nents = 0;
-+              }
-+
-+              /* allocate space for base edesc and link tables */
-+              edesc = qi_cache_zalloc(GFP_DMA | flags);
-+              if (!edesc) {
-+                      dma_unmap_sg(ctx->dev, req->src, src_nents,
-+                                   DMA_TO_DEVICE);
-+                      return -ENOMEM;
-+              }
-+
-+              edesc->src_nents = src_nents;
-+              sg_table = &edesc->sgt[0];
-+
-+              memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt));
-+              dpaa2_fl_set_final(in_fle, true);
-+              dpaa2_fl_set_len(in_fle, to_hash);
-+
-+              if (mapped_nents > 1) {
-+                      int qm_sg_bytes;
-+
-+                      sg_to_qm_sg_last(req->src, mapped_nents, sg_table, 0);
-+                      qm_sg_bytes = mapped_nents * sizeof(*sg_table);
-+                      edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table,
-+                                                        qm_sg_bytes,
-+                                                        DMA_TO_DEVICE);
-+                      if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) {
-+                              dev_err(ctx->dev, "unable to map S/G table\n");
-+                              ret = -ENOMEM;
-+                              goto unmap_ctx;
-+                      }
-+                      edesc->qm_sg_bytes = qm_sg_bytes;
-+                      dpaa2_fl_set_format(in_fle, dpaa2_fl_sg);
-+                      dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma);
-+              } else {
-+                      dpaa2_fl_set_format(in_fle, dpaa2_fl_single);
-+                      dpaa2_fl_set_addr(in_fle, sg_dma_address(req->src));
-+              }
-+
-+              if (*next_buflen)
-+                      scatterwalk_map_and_copy(next_buf, req->src, to_hash,
-+                                               *next_buflen, 0);
-+
-+              state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx,
-+                                              ctx->ctx_len, DMA_FROM_DEVICE);
-+              if (dma_mapping_error(ctx->dev, state->ctx_dma)) {
-+                      dev_err(ctx->dev, "unable to map ctx\n");
-+                      state->ctx_dma = 0;
-+                      ret = -ENOMEM;
-+                      goto unmap_ctx;
-+              }
-+
-+              dpaa2_fl_set_format(out_fle, dpaa2_fl_single);
-+              dpaa2_fl_set_addr(out_fle, state->ctx_dma);
-+              dpaa2_fl_set_len(out_fle, ctx->ctx_len);
-+
-+              req_ctx->flc = &ctx->flc[UPDATE_FIRST];
-+              req_ctx->flc_dma = ctx->flc_dma[UPDATE_FIRST];
-+              req_ctx->cbk = ahash_done_ctx_dst;
-+              req_ctx->ctx = &req->base;
-+              req_ctx->edesc = edesc;
-+
-+              ret = dpaa2_caam_enqueue(ctx->dev, req_ctx);
-+              if (ret != -EINPROGRESS &&
-+                  !(ret == -EBUSY && req->base.flags &
-+                    CRYPTO_TFM_REQ_MAY_BACKLOG))
-+                      goto unmap_ctx;
-+
-+              state->update = ahash_update_ctx;
-+              state->finup = ahash_finup_ctx;
-+              state->final = ahash_final_ctx;
-+      } else if (*next_buflen) {
-+              state->update = ahash_update_no_ctx;
-+              state->finup = ahash_finup_no_ctx;
-+              state->final = ahash_final_no_ctx;
-+              scatterwalk_map_and_copy(next_buf, req->src, 0,
-+                                       req->nbytes, 0);
-+              switch_buf(state);
-+      }
-+#ifdef DEBUG
-+      print_hex_dump(KERN_ERR, "next buf@" __stringify(__LINE__)": ",
-+                     DUMP_PREFIX_ADDRESS, 16, 4, next_buf, *next_buflen, 1);
-+#endif
-+
-+      return ret;
-+unmap_ctx:
-+      ahash_unmap_ctx(ctx->dev, edesc, req, ctx->ctx_len, DMA_TO_DEVICE);
-+      qi_cache_free(edesc);
-+      return ret;
-+}
-+
-+static int ahash_finup_first(struct ahash_request *req)
-+{
-+      return ahash_digest(req);
-+}
-+
-+static int ahash_init(struct ahash_request *req)
-+{
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+
-+      state->update = ahash_update_first;
-+      state->finup = ahash_finup_first;
-+      state->final = ahash_final_no_ctx;
-+
-+      state->ctx_dma = 0;
-+      state->current_buf = 0;
-+      state->buf_dma = 0;
-+      state->buflen_0 = 0;
-+      state->buflen_1 = 0;
-+
-+      return 0;
-+}
-+
-+static int ahash_update(struct ahash_request *req)
-+{
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+
-+      return state->update(req);
-+}
-+
-+static int ahash_finup(struct ahash_request *req)
-+{
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+
-+      return state->finup(req);
-+}
-+
-+static int ahash_final(struct ahash_request *req)
-+{
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+
-+      return state->final(req);
-+}
-+
-+static int ahash_export(struct ahash_request *req, void *out)
-+{
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      struct caam_export_state *export = out;
-+      int len;
-+      u8 *buf;
-+
-+      if (state->current_buf) {
-+              buf = state->buf_1;
-+              len = state->buflen_1;
-+      } else {
-+              buf = state->buf_0;
-+              len = state->buflen_0;
-+      }
-+
-+      memcpy(export->buf, buf, len);
-+      memcpy(export->caam_ctx, state->caam_ctx, sizeof(export->caam_ctx));
-+      export->buflen = len;
-+      export->update = state->update;
-+      export->final = state->final;
-+      export->finup = state->finup;
-+
-+      return 0;
-+}
-+
-+static int ahash_import(struct ahash_request *req, const void *in)
-+{
-+      struct caam_hash_state *state = ahash_request_ctx(req);
-+      const struct caam_export_state *export = in;
-+
-+      memset(state, 0, sizeof(*state));
-+      memcpy(state->buf_0, export->buf, export->buflen);
-+      memcpy(state->caam_ctx, export->caam_ctx, sizeof(state->caam_ctx));
-+      state->buflen_0 = export->buflen;
-+      state->update = export->update;
-+      state->final = export->final;
-+      state->finup = export->finup;
-+
-+      return 0;
-+}
-+
-+struct caam_hash_template {
-+      char name[CRYPTO_MAX_ALG_NAME];
-+      char driver_name[CRYPTO_MAX_ALG_NAME];
-+      char hmac_name[CRYPTO_MAX_ALG_NAME];
-+      char hmac_driver_name[CRYPTO_MAX_ALG_NAME];
-+      unsigned int blocksize;
-+      struct ahash_alg template_ahash;
-+      u32 alg_type;
-+};
-+
-+/* ahash descriptors */
-+static struct caam_hash_template driver_hash[] = {
-+      {
-+              .name = "sha1",
-+              .driver_name = "sha1-caam-qi2",
-+              .hmac_name = "hmac(sha1)",
-+              .hmac_driver_name = "hmac-sha1-caam-qi2",
-+              .blocksize = SHA1_BLOCK_SIZE,
-+              .template_ahash = {
-+                      .init = ahash_init,
-+                      .update = ahash_update,
-+                      .final = ahash_final,
-+                      .finup = ahash_finup,
-+                      .digest = ahash_digest,
-+                      .export = ahash_export,
-+                      .import = ahash_import,
-+                      .setkey = ahash_setkey,
-+                      .halg = {
-+                              .digestsize = SHA1_DIGEST_SIZE,
-+                              .statesize = sizeof(struct caam_export_state),
-+                      },
-+              },
-+              .alg_type = OP_ALG_ALGSEL_SHA1,
-+      }, {
-+              .name = "sha224",
-+              .driver_name = "sha224-caam-qi2",
-+              .hmac_name = "hmac(sha224)",
-+              .hmac_driver_name = "hmac-sha224-caam-qi2",
-+              .blocksize = SHA224_BLOCK_SIZE,
-+              .template_ahash = {
-+                      .init = ahash_init,
-+                      .update = ahash_update,
-+                      .final = ahash_final,
-+                      .finup = ahash_finup,
-+                      .digest = ahash_digest,
-+                      .export = ahash_export,
-+                      .import = ahash_import,
-+                      .setkey = ahash_setkey,
-+                      .halg = {
-+                              .digestsize = SHA224_DIGEST_SIZE,
-+                              .statesize = sizeof(struct caam_export_state),
-+                      },
-+              },
-+              .alg_type = OP_ALG_ALGSEL_SHA224,
-+      }, {
-+              .name = "sha256",
-+              .driver_name = "sha256-caam-qi2",
-+              .hmac_name = "hmac(sha256)",
-+              .hmac_driver_name = "hmac-sha256-caam-qi2",
-+              .blocksize = SHA256_BLOCK_SIZE,
-+              .template_ahash = {
-+                      .init = ahash_init,
-+                      .update = ahash_update,
-+                      .final = ahash_final,
-+                      .finup = ahash_finup,
-+                      .digest = ahash_digest,
-+                      .export = ahash_export,
-+                      .import = ahash_import,
-+                      .setkey = ahash_setkey,
-+                      .halg = {
-+                              .digestsize = SHA256_DIGEST_SIZE,
-+                              .statesize = sizeof(struct caam_export_state),
-+                      },
-+              },
-+              .alg_type = OP_ALG_ALGSEL_SHA256,
-+      }, {
-+              .name = "sha384",
-+              .driver_name = "sha384-caam-qi2",
-+              .hmac_name = "hmac(sha384)",
-+              .hmac_driver_name = "hmac-sha384-caam-qi2",
-+              .blocksize = SHA384_BLOCK_SIZE,
-+              .template_ahash = {
-+                      .init = ahash_init,
-+                      .update = ahash_update,
-+                      .final = ahash_final,
-+                      .finup = ahash_finup,
-+                      .digest = ahash_digest,
-+                      .export = ahash_export,
-+                      .import = ahash_import,
-+                      .setkey = ahash_setkey,
-+                      .halg = {
-+                              .digestsize = SHA384_DIGEST_SIZE,
-+                              .statesize = sizeof(struct caam_export_state),
-+                      },
-+              },
-+              .alg_type = OP_ALG_ALGSEL_SHA384,
-+      }, {
-+              .name = "sha512",
-+              .driver_name = "sha512-caam-qi2",
-+              .hmac_name = "hmac(sha512)",
-+              .hmac_driver_name = "hmac-sha512-caam-qi2",
-+              .blocksize = SHA512_BLOCK_SIZE,
-+              .template_ahash = {
-+                      .init = ahash_init,
-+                      .update = ahash_update,
-+                      .final = ahash_final,
-+                      .finup = ahash_finup,
-+                      .digest = ahash_digest,
-+                      .export = ahash_export,
-+                      .import = ahash_import,
-+                      .setkey = ahash_setkey,
-+                      .halg = {
-+                              .digestsize = SHA512_DIGEST_SIZE,
-+                              .statesize = sizeof(struct caam_export_state),
-+                      },
-+              },
-+              .alg_type = OP_ALG_ALGSEL_SHA512,
-+      }, {
-+              .name = "md5",
-+              .driver_name = "md5-caam-qi2",
-+              .hmac_name = "hmac(md5)",
-+              .hmac_driver_name = "hmac-md5-caam-qi2",
-+              .blocksize = MD5_BLOCK_WORDS * 4,
-+              .template_ahash = {
-+                      .init = ahash_init,
-+                      .update = ahash_update,
-+                      .final = ahash_final,
-+                      .finup = ahash_finup,
-+                      .digest = ahash_digest,
-+                      .export = ahash_export,
-+                      .import = ahash_import,
-+                      .setkey = ahash_setkey,
-+                      .halg = {
-+                              .digestsize = MD5_DIGEST_SIZE,
-+                              .statesize = sizeof(struct caam_export_state),
-+                      },
-+              },
-+              .alg_type = OP_ALG_ALGSEL_MD5,
-+      }
-+};
-+
-+struct caam_hash_alg {
-+      struct list_head entry;
-+      struct device *dev;
-+      int alg_type;
-+      struct ahash_alg ahash_alg;
-+};
-+
-+static int caam_hash_cra_init(struct crypto_tfm *tfm)
-+{
-+      struct crypto_ahash *ahash = __crypto_ahash_cast(tfm);
-+      struct crypto_alg *base = tfm->__crt_alg;
-+      struct hash_alg_common *halg =
-+               container_of(base, struct hash_alg_common, base);
-+      struct ahash_alg *alg =
-+               container_of(halg, struct ahash_alg, halg);
-+      struct caam_hash_alg *caam_hash =
-+               container_of(alg, struct caam_hash_alg, ahash_alg);
-+      struct caam_hash_ctx *ctx = crypto_tfm_ctx(tfm);
-+      /* Sizes for MDHA running digests: MD5, SHA1, 224, 256, 384, 512 */
-+      static const u8 runninglen[] = { HASH_MSG_LEN + MD5_DIGEST_SIZE,
-+                                       HASH_MSG_LEN + SHA1_DIGEST_SIZE,
-+                                       HASH_MSG_LEN + 32,
-+                                       HASH_MSG_LEN + SHA256_DIGEST_SIZE,
-+                                       HASH_MSG_LEN + 64,
-+                                       HASH_MSG_LEN + SHA512_DIGEST_SIZE };
-+      dma_addr_t dma_addr;
-+      int i;
-+
-+      ctx->dev = caam_hash->dev;
-+
-+      dma_addr = dma_map_single_attrs(ctx->dev, ctx->flc, sizeof(ctx->flc),
-+                                      DMA_BIDIRECTIONAL,
-+                                      DMA_ATTR_SKIP_CPU_SYNC);
-+      if (dma_mapping_error(ctx->dev, dma_addr)) {
-+              dev_err(ctx->dev, "unable to map shared descriptors\n");
-+              return -ENOMEM;
-+      }
-+
-+      for (i = 0; i < HASH_NUM_OP; i++)
-+              ctx->flc_dma[i] = dma_addr + i * sizeof(ctx->flc[i]);
-+
-+      /* copy descriptor header template value */
-+      ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam_hash->alg_type;
-+
-+      ctx->ctx_len = runninglen[(ctx->adata.algtype &
-+                                 OP_ALG_ALGSEL_SUBMASK) >>
-+                                OP_ALG_ALGSEL_SHIFT];
-+
-+      crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
-+                               sizeof(struct caam_hash_state));
-+
-+      return ahash_set_sh_desc(ahash);
-+}
-+
-+static void caam_hash_cra_exit(struct crypto_tfm *tfm)
-+{
-+      struct caam_hash_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+      dma_unmap_single_attrs(ctx->dev, ctx->flc_dma[0], sizeof(ctx->flc),
-+                             DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC);
-+}
-+
-+static struct caam_hash_alg *caam_hash_alloc(struct device *dev,
-+      struct caam_hash_template *template, bool keyed)
-+{
-+      struct caam_hash_alg *t_alg;
-+      struct ahash_alg *halg;
-+      struct crypto_alg *alg;
-+
-+      t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL);
-+      if (!t_alg)
-+              return ERR_PTR(-ENOMEM);
-+
-+      t_alg->ahash_alg = template->template_ahash;
-+      halg = &t_alg->ahash_alg;
-+      alg = &halg->halg.base;
-+
-+      if (keyed) {
-+              snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s",
-+                       template->hmac_name);
-+              snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
-+                       template->hmac_driver_name);
-+      } else {
-+              snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s",
-+                       template->name);
-+              snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
-+                       template->driver_name);
-+              t_alg->ahash_alg.setkey = NULL;
-+      }
-+      alg->cra_module = THIS_MODULE;
-+      alg->cra_init = caam_hash_cra_init;
-+      alg->cra_exit = caam_hash_cra_exit;
-+      alg->cra_ctxsize = sizeof(struct caam_hash_ctx);
-+      alg->cra_priority = CAAM_CRA_PRIORITY;
-+      alg->cra_blocksize = template->blocksize;
-+      alg->cra_alignmask = 0;
-+      alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_TYPE_AHASH;
-+      alg->cra_type = &crypto_ahash_type;
-+
-+      t_alg->alg_type = template->alg_type;
-+      t_alg->dev = dev;
-+
-+      return t_alg;
-+}
-+
-+static void dpaa2_caam_fqdan_cb(struct dpaa2_io_notification_ctx *nctx)
-+{
-+      struct dpaa2_caam_priv_per_cpu *ppriv;
-+
-+      ppriv = container_of(nctx, struct dpaa2_caam_priv_per_cpu, nctx);
-+      napi_schedule_irqoff(&ppriv->napi);
-+}
-+
-+static int __cold dpaa2_dpseci_dpio_setup(struct dpaa2_caam_priv *priv)
-+{
-+      struct device *dev = priv->dev;
-+      struct dpaa2_io_notification_ctx *nctx;
-+      struct dpaa2_caam_priv_per_cpu *ppriv;
-+      int err, i = 0, cpu;
-+
-+      for_each_online_cpu(cpu) {
-+              ppriv = per_cpu_ptr(priv->ppriv, cpu);
-+              ppriv->priv = priv;
-+              nctx = &ppriv->nctx;
-+              nctx->is_cdan = 0;
-+              nctx->id = ppriv->rsp_fqid;
-+              nctx->desired_cpu = cpu;
-+              nctx->cb = dpaa2_caam_fqdan_cb;
-+
-+              /* Register notification callbacks */
-+              ppriv->dpio = dpaa2_io_service_select(cpu);
-+              err = dpaa2_io_service_register(ppriv->dpio, nctx, dev);
-+              if (unlikely(err)) {
-+                      dev_dbg(dev, "No affine DPIO for cpu %d\n", cpu);
-+                      nctx->cb = NULL;
-+                      /*
-+                       * If no affine DPIO for this core, there's probably
-+                       * none available for next cores either. Signal we want
-+                       * to retry later, in case the DPIO devices weren't
-+                       * probed yet.
-+                       */
-+                      err = -EPROBE_DEFER;
-+                      goto err;
-+              }
-+
-+              ppriv->store = dpaa2_io_store_create(DPAA2_CAAM_STORE_SIZE,
-+                                                   dev);
-+              if (unlikely(!ppriv->store)) {
-+                      dev_err(dev, "dpaa2_io_store_create() failed\n");
-+                      err = -ENOMEM;
-+                      goto err;
-+              }
-+
-+              if (++i == priv->num_pairs)
-+                      break;
-+      }
-+
-+      return 0;
-+
-+err:
-+      for_each_online_cpu(cpu) {
-+              ppriv = per_cpu_ptr(priv->ppriv, cpu);
-+              if (!ppriv->nctx.cb)
-+                      break;
-+              dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx, dev);
-+      }
-+
-+      for_each_online_cpu(cpu) {
-+              ppriv = per_cpu_ptr(priv->ppriv, cpu);
-+              if (!ppriv->store)
-+                      break;
-+              dpaa2_io_store_destroy(ppriv->store);
-+      }
-+
-+      return err;
-+}
-+
-+static void __cold dpaa2_dpseci_dpio_free(struct dpaa2_caam_priv *priv)
-+{
-+      struct dpaa2_caam_priv_per_cpu *ppriv;
-+      struct device *dev = priv->dev;
-+      int i = 0, cpu;
-+
-+      for_each_online_cpu(cpu) {
-+              ppriv = per_cpu_ptr(priv->ppriv, cpu);
-+              dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx, dev);
-+              dpaa2_io_store_destroy(ppriv->store);
-+
-+              if (++i == priv->num_pairs)
-+                      return;
-+      }
-+}
-+
-+static int dpaa2_dpseci_bind(struct dpaa2_caam_priv *priv)
-+{
-+      struct dpseci_rx_queue_cfg rx_queue_cfg;
-+      struct device *dev = priv->dev;
-+      struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev);
-+      struct dpaa2_caam_priv_per_cpu *ppriv;
-+      int err = 0, i = 0, cpu;
-+
-+      /* Configure Rx queues */
-+      for_each_online_cpu(cpu) {
-+              ppriv = per_cpu_ptr(priv->ppriv, cpu);
-+
-+              rx_queue_cfg.options = DPSECI_QUEUE_OPT_DEST |
-+                                     DPSECI_QUEUE_OPT_USER_CTX;
-+              rx_queue_cfg.order_preservation_en = 0;
-+              rx_queue_cfg.dest_cfg.dest_type = DPSECI_DEST_DPIO;
-+              rx_queue_cfg.dest_cfg.dest_id = ppriv->nctx.dpio_id;
-+              /*
-+               * Rx priority (WQ) doesn't really matter, since we use
-+               * pull mode, i.e. volatile dequeues from specific FQs
-+               */
-+              rx_queue_cfg.dest_cfg.priority = 0;
-+              rx_queue_cfg.user_ctx = ppriv->nctx.qman64;
-+
-+              err = dpseci_set_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
-+                                        &rx_queue_cfg);
-+              if (err) {
-+                      dev_err(dev, "dpseci_set_rx_queue() failed with err %d\n",
-+                              err);
-+                      return err;
-+              }
-+
-+              if (++i == priv->num_pairs)
-+                      break;
-+      }
-+
-+      return err;
-+}
-+
-+static void dpaa2_dpseci_congestion_free(struct dpaa2_caam_priv *priv)
-+{
-+      struct device *dev = priv->dev;
-+
-+      if (!priv->cscn_mem)
-+              return;
-+
-+      dma_unmap_single(dev, priv->cscn_dma, DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
-+      kfree(priv->cscn_mem);
-+}
-+
-+static void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv)
-+{
-+      struct device *dev = priv->dev;
-+      struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev);
-+
-+      dpaa2_dpseci_congestion_free(priv);
-+      dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
-+}
-+
-+static void dpaa2_caam_process_fd(struct dpaa2_caam_priv *priv,
-+                                const struct dpaa2_fd *fd)
-+{
-+      struct caam_request *req;
-+      u32 fd_err;
-+
-+      if (dpaa2_fd_get_format(fd) != dpaa2_fd_list) {
-+              dev_err(priv->dev, "Only Frame List FD format is supported!\n");
-+              return;
-+      }
-+
-+      fd_err = dpaa2_fd_get_ctrl(fd) & FD_CTRL_ERR_MASK;
-+      if (unlikely(fd_err))
-+              dev_err(priv->dev, "FD error: %08x\n", fd_err);
-+
-+      /*
-+       * FD[ADDR] is guaranteed to be valid, irrespective of errors reported
-+       * in FD[ERR] or FD[FRC].
-+       */
-+      req = dpaa2_caam_iova_to_virt(priv, dpaa2_fd_get_addr(fd));
-+      dma_unmap_single(priv->dev, req->fd_flt_dma, sizeof(req->fd_flt),
-+                       DMA_BIDIRECTIONAL);
-+      req->cbk(req->ctx, dpaa2_fd_get_frc(fd));
-+}
-+
-+static int dpaa2_caam_pull_fq(struct dpaa2_caam_priv_per_cpu *ppriv)
-+{
-+      int err;
-+
-+      /* Retry while portal is busy */
-+      do {
-+              err = dpaa2_io_service_pull_fq(ppriv->dpio, ppriv->rsp_fqid,
-+                                             ppriv->store);
-+      } while (err == -EBUSY);
-+
-+      if (unlikely(err))
-+              dev_err(ppriv->priv->dev, "dpaa2_io_service_pull err %d", err);
-+
-+      return err;
-+}
-+
-+static int dpaa2_caam_store_consume(struct dpaa2_caam_priv_per_cpu *ppriv)
-+{
-+      struct dpaa2_dq *dq;
-+      int cleaned = 0, is_last;
-+
-+      do {
-+              dq = dpaa2_io_store_next(ppriv->store, &is_last);
-+              if (unlikely(!dq)) {
-+                      if (unlikely(!is_last)) {
-+                              dev_dbg(ppriv->priv->dev,
-+                                      "FQ %d returned no valid frames\n",
-+                                      ppriv->rsp_fqid);
-+                              /*
-+                               * MUST retry until we get some sort of
-+                               * valid response token (be it "empty dequeue"
-+                               * or a valid frame).
-+                               */
-+                              continue;
-+                      }
-+                      break;
-+              }
-+
-+              /* Process FD */
-+              dpaa2_caam_process_fd(ppriv->priv, dpaa2_dq_fd(dq));
-+              cleaned++;
-+      } while (!is_last);
-+
-+      return cleaned;
-+}
-+
-+static int dpaa2_dpseci_poll(struct napi_struct *napi, int budget)
-+{
-+      struct dpaa2_caam_priv_per_cpu *ppriv;
-+      struct dpaa2_caam_priv *priv;
-+      int err, cleaned = 0, store_cleaned;
-+
-+      ppriv = container_of(napi, struct dpaa2_caam_priv_per_cpu, napi);
-+      priv = ppriv->priv;
-+
-+      if (unlikely(dpaa2_caam_pull_fq(ppriv)))
-+              return 0;
-+
-+      do {
-+              store_cleaned = dpaa2_caam_store_consume(ppriv);
-+              cleaned += store_cleaned;
-+
-+              if (store_cleaned == 0 ||
-+                  cleaned > budget - DPAA2_CAAM_STORE_SIZE)
-+                      break;
-+
-+              /* Try to dequeue some more */
-+              err = dpaa2_caam_pull_fq(ppriv);
-+              if (unlikely(err))
-+                      break;
-+      } while (1);
-+
-+      if (cleaned < budget) {
-+              napi_complete_done(napi, cleaned);
-+              err = dpaa2_io_service_rearm(ppriv->dpio, &ppriv->nctx);
-+              if (unlikely(err))
-+                      dev_err(priv->dev, "Notification rearm failed: %d\n",
-+                              err);
-+      }
-+
-+      return cleaned;
-+}
-+
-+static int dpaa2_dpseci_congestion_setup(struct dpaa2_caam_priv *priv,
-+                                       u16 token)
-+{
-+      struct dpseci_congestion_notification_cfg cong_notif_cfg = { 0 };
-+      struct device *dev = priv->dev;
-+      int err;
-+
-+      /*
-+       * Congestion group feature supported starting with DPSECI API v5.1
-+       * and only when object has been created with this capability.
-+       */
-+      if ((DPSECI_VER(priv->major_ver, priv->minor_ver) < DPSECI_VER(5, 1)) ||
-+          !(priv->dpseci_attr.options & DPSECI_OPT_HAS_CG))
-+              return 0;
-+
-+      priv->cscn_mem = kzalloc(DPAA2_CSCN_SIZE + DPAA2_CSCN_ALIGN,
-+                               GFP_KERNEL | GFP_DMA);
-+      if (!priv->cscn_mem)
-+              return -ENOMEM;
-+
-+      priv->cscn_mem_aligned = PTR_ALIGN(priv->cscn_mem, DPAA2_CSCN_ALIGN);
-+      priv->cscn_dma = dma_map_single(dev, priv->cscn_mem_aligned,
-+                                      DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
-+      if (dma_mapping_error(dev, priv->cscn_dma)) {
-+              dev_err(dev, "Error mapping CSCN memory area\n");
-+              err = -ENOMEM;
-+              goto err_dma_map;
-+      }
-+
-+      cong_notif_cfg.units = DPSECI_CONGESTION_UNIT_BYTES;
-+      cong_notif_cfg.threshold_entry = DPAA2_SEC_CONG_ENTRY_THRESH;
-+      cong_notif_cfg.threshold_exit = DPAA2_SEC_CONG_EXIT_THRESH;
-+      cong_notif_cfg.message_ctx = (u64)priv;
-+      cong_notif_cfg.message_iova = priv->cscn_dma;
-+      cong_notif_cfg.notification_mode = DPSECI_CGN_MODE_WRITE_MEM_ON_ENTER |
-+                                      DPSECI_CGN_MODE_WRITE_MEM_ON_EXIT |
-+                                      DPSECI_CGN_MODE_COHERENT_WRITE;
-+
-+      err = dpseci_set_congestion_notification(priv->mc_io, 0, token,
-+                                               &cong_notif_cfg);
-+      if (err) {
-+              dev_err(dev, "dpseci_set_congestion_notification failed\n");
-+              goto err_set_cong;
-+      }
-+
-+      return 0;
-+
-+err_set_cong:
-+      dma_unmap_single(dev, priv->cscn_dma, DPAA2_CSCN_SIZE, DMA_FROM_DEVICE);
-+err_dma_map:
-+      kfree(priv->cscn_mem);
-+
-+      return err;
-+}
-+
-+static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)
-+{
-+      struct device *dev = &ls_dev->dev;
-+      struct dpaa2_caam_priv *priv;
-+      struct dpaa2_caam_priv_per_cpu *ppriv;
-+      int err, cpu;
-+      u8 i;
-+
-+      priv = dev_get_drvdata(dev);
-+
-+      priv->dev = dev;
-+      priv->dpsec_id = ls_dev->obj_desc.id;
-+
-+      /* Get a handle for the DPSECI this interface is associate with */
-+      err = dpseci_open(priv->mc_io, 0, priv->dpsec_id, &ls_dev->mc_handle);
-+      if (err) {
-+              dev_err(dev, "dpsec_open() failed: %d\n", err);
-+              goto err_open;
-+      }
-+
-+      dev_info(dev, "Opened dpseci object successfully\n");
-+
-+      err = dpseci_get_api_version(priv->mc_io, 0, &priv->major_ver,
-+                                   &priv->minor_ver);
-+      if (err) {
-+              dev_err(dev, "dpseci_get_api_version() failed\n");
-+              goto err_get_vers;
-+      }
-+
-+      err = dpseci_get_attributes(priv->mc_io, 0, ls_dev->mc_handle,
-+                                  &priv->dpseci_attr);
-+      if (err) {
-+              dev_err(dev, "dpseci_get_attributes() failed\n");
-+              goto err_get_vers;
-+      }
-+
-+      err = dpseci_get_sec_attr(priv->mc_io, 0, ls_dev->mc_handle,
-+                                &priv->sec_attr);
-+      if (err) {
-+              dev_err(dev, "dpseci_get_sec_attr() failed\n");
-+              goto err_get_vers;
-+      }
-+
-+      err = dpaa2_dpseci_congestion_setup(priv, ls_dev->mc_handle);
-+      if (err) {
-+              dev_err(dev, "setup_congestion() failed\n");
-+              goto err_get_vers;
-+      }
-+
-+      priv->num_pairs = min(priv->dpseci_attr.num_rx_queues,
-+                            priv->dpseci_attr.num_tx_queues);
-+      if (priv->num_pairs > num_online_cpus()) {
-+              dev_warn(dev, "%d queues won't be used\n",
-+                       priv->num_pairs - num_online_cpus());
-+              priv->num_pairs = num_online_cpus();
-+      }
-+
-+      for (i = 0; i < priv->dpseci_attr.num_rx_queues; i++) {
-+              err = dpseci_get_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
-+                                        &priv->rx_queue_attr[i]);
-+              if (err) {
-+                      dev_err(dev, "dpseci_get_rx_queue() failed\n");
-+                      goto err_get_rx_queue;
-+              }
-+      }
-+
-+      for (i = 0; i < priv->dpseci_attr.num_tx_queues; i++) {
-+              err = dpseci_get_tx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
-+                                        &priv->tx_queue_attr[i]);
-+              if (err) {
-+                      dev_err(dev, "dpseci_get_tx_queue() failed\n");
-+                      goto err_get_rx_queue;
-+              }
-+      }
-+
-+      i = 0;
-+      for_each_online_cpu(cpu) {
-+              u8 j;
-+
-+              j = i % priv->num_pairs;
-+
-+              ppriv = per_cpu_ptr(priv->ppriv, cpu);
-+              ppriv->req_fqid = priv->tx_queue_attr[j].fqid;
-+
-+              /*
-+               * Allow all cores to enqueue, while only some of them
-+               * will take part in dequeuing.
-+               */
-+              if (++i > priv->num_pairs)
-+                      continue;
-+
-+              ppriv->rsp_fqid = priv->rx_queue_attr[j].fqid;
-+              ppriv->prio = j;
-+
-+              dev_info(dev, "pair %d: rx queue %d, tx queue %d\n", j,
-+                       priv->rx_queue_attr[j].fqid,
-+                       priv->tx_queue_attr[j].fqid);
-+
-+              ppriv->net_dev.dev = *dev;
-+              INIT_LIST_HEAD(&ppriv->net_dev.napi_list);
-+              netif_napi_add(&ppriv->net_dev, &ppriv->napi, dpaa2_dpseci_poll,
-+                             DPAA2_CAAM_NAPI_WEIGHT);
-+      }
-+
-+      return 0;
-+
-+err_get_rx_queue:
-+      dpaa2_dpseci_congestion_free(priv);
-+err_get_vers:
-+      dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
-+err_open:
-+      return err;
-+}
-+
-+static int dpaa2_dpseci_enable(struct dpaa2_caam_priv *priv)
-+{
-+      struct device *dev = priv->dev;
-+      struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev);
-+      struct dpaa2_caam_priv_per_cpu *ppriv;
-+      int err, i;
-+
-+      for (i = 0; i < priv->num_pairs; i++) {
-+              ppriv = per_cpu_ptr(priv->ppriv, i);
-+              napi_enable(&ppriv->napi);
-+      }
-+
-+      err = dpseci_enable(priv->mc_io, 0, ls_dev->mc_handle);
-+      if (err) {
-+              dev_err(dev, "dpseci_enable() failed\n");
-+              return err;
-+      }
-+
-+      dev_info(dev, "DPSECI version %d.%d\n",
-+               priv->major_ver,
-+               priv->minor_ver);
-+
-+      return 0;
-+}
-+
-+static int __cold dpaa2_dpseci_disable(struct dpaa2_caam_priv *priv)
-+{
-+      struct device *dev = priv->dev;
-+      struct dpaa2_caam_priv_per_cpu *ppriv;
-+      struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev);
-+      int i, err = 0, enabled;
-+
-+      err = dpseci_disable(priv->mc_io, 0, ls_dev->mc_handle);
-+      if (err) {
-+              dev_err(dev, "dpseci_disable() failed\n");
-+              return err;
-+      }
-+
-+      err = dpseci_is_enabled(priv->mc_io, 0, ls_dev->mc_handle, &enabled);
-+      if (err) {
-+              dev_err(dev, "dpseci_is_enabled() failed\n");
-+              return err;
-+      }
-+
-+      dev_dbg(dev, "disable: %s\n", enabled ? "false" : "true");
-+
-+      for (i = 0; i < priv->num_pairs; i++) {
-+              ppriv = per_cpu_ptr(priv->ppriv, i);
-+              napi_disable(&ppriv->napi);
-+              netif_napi_del(&ppriv->napi);
-+      }
-+
-+      return 0;
-+}
-+
-+static struct list_head hash_list;
-+
-+static int dpaa2_caam_probe(struct fsl_mc_device *dpseci_dev)
-+{
-+      struct device *dev;
-+      struct dpaa2_caam_priv *priv;
-+      int i, err = 0;
-+      bool registered = false;
-+
-+      /*
-+       * There is no way to get CAAM endianness - there is no direct register
-+       * space access and MC f/w does not provide this attribute.
-+       * All DPAA2-based SoCs have little endian CAAM, thus hard-code this
-+       * property.
-+       */
-+      caam_little_end = true;
-+
-+      caam_imx = false;
-+
-+      dev = &dpseci_dev->dev;
-+
-+      priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+
-+      dev_set_drvdata(dev, priv);
-+
-+      priv->domain = iommu_get_domain_for_dev(dev);
-+
-+      qi_cache = kmem_cache_create("dpaa2_caamqicache", CAAM_QI_MEMCACHE_SIZE,
-+                                   0, SLAB_CACHE_DMA, NULL);
-+      if (!qi_cache) {
-+              dev_err(dev, "Can't allocate SEC cache\n");
-+              err = -ENOMEM;
-+              goto err_qicache;
-+      }
-+
-+      err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(49));
-+      if (err) {
-+              dev_err(dev, "dma_set_mask_and_coherent() failed\n");
-+              goto err_dma_mask;
-+      }
-+
-+      /* Obtain a MC portal */
-+      err = fsl_mc_portal_allocate(dpseci_dev, 0, &priv->mc_io);
-+      if (err) {
-+              if (err == -ENXIO)
-+                      err = -EPROBE_DEFER;
-+              else
-+                      dev_err(dev, "MC portal allocation failed\n");
-+
-+              goto err_dma_mask;
-+      }
-+
-+      priv->ppriv = alloc_percpu(*priv->ppriv);
-+      if (!priv->ppriv) {
-+              dev_err(dev, "alloc_percpu() failed\n");
-+              err = -ENOMEM;
-+              goto err_alloc_ppriv;
-+      }
-+
-+      /* DPSECI initialization */
-+      err = dpaa2_dpseci_setup(dpseci_dev);
-+      if (err) {
-+              dev_err(dev, "dpaa2_dpseci_setup() failed\n");
-+              goto err_dpseci_setup;
-+      }
-+
-+      /* DPIO */
-+      err = dpaa2_dpseci_dpio_setup(priv);
-+      if (err) {
-+              if (err != -EPROBE_DEFER)
-+                      dev_err(dev, "dpaa2_dpseci_dpio_setup() failed\n");
-+              goto err_dpio_setup;
-+      }
-+
-+      /* DPSECI binding to DPIO */
-+      err = dpaa2_dpseci_bind(priv);
-+      if (err) {
-+              dev_err(dev, "dpaa2_dpseci_bind() failed\n");
-+              goto err_bind;
-+      }
-+
-+      /* DPSECI enable */
-+      err = dpaa2_dpseci_enable(priv);
-+      if (err) {
-+              dev_err(dev, "dpaa2_dpseci_enable() failed");
-+              goto err_bind;
-+      }
-+
-+      /* register crypto algorithms the device supports */
-+      for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
-+              struct caam_skcipher_alg *t_alg = driver_algs + i;
-+              u32 alg_sel = t_alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK;
-+
-+              /* Skip DES algorithms if not supported by device */
-+              if (!priv->sec_attr.des_acc_num &&
-+                  ((alg_sel == OP_ALG_ALGSEL_3DES) ||
-+                   (alg_sel == OP_ALG_ALGSEL_DES)))
-+                      continue;
-+
-+              /* Skip AES algorithms if not supported by device */
-+              if (!priv->sec_attr.aes_acc_num &&
-+                  (alg_sel == OP_ALG_ALGSEL_AES))
-+                      continue;
-+
-+              /* Skip CHACHA20 algorithms if not supported by device */
-+              if (alg_sel == OP_ALG_ALGSEL_CHACHA20 &&
-+                  !priv->sec_attr.ccha_acc_num)
-+                      continue;
-+
-+              t_alg->caam.dev = dev;
-+              caam_skcipher_alg_init(t_alg);
-+
-+              err = crypto_register_skcipher(&t_alg->skcipher);
-+              if (err) {
-+                      dev_warn(dev, "%s alg registration failed: %d\n",
-+                               t_alg->skcipher.base.cra_driver_name, err);
-+                      continue;
-+              }
-+
-+              t_alg->registered = true;
-+              registered = true;
-+      }
-+
-+      for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
-+              struct caam_aead_alg *t_alg = driver_aeads + i;
-+              u32 c1_alg_sel = t_alg->caam.class1_alg_type &
-+                               OP_ALG_ALGSEL_MASK;
-+              u32 c2_alg_sel = t_alg->caam.class2_alg_type &
-+                               OP_ALG_ALGSEL_MASK;
-+
-+              /* Skip DES algorithms if not supported by device */
-+              if (!priv->sec_attr.des_acc_num &&
-+                  ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
-+                   (c1_alg_sel == OP_ALG_ALGSEL_DES)))
-+                      continue;
-+
-+              /* Skip AES algorithms if not supported by device */
-+              if (!priv->sec_attr.aes_acc_num &&
-+                  (c1_alg_sel == OP_ALG_ALGSEL_AES))
-+                      continue;
-+
-+              /* Skip CHACHA20 algorithms if not supported by device */
-+              if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 &&
-+                  !priv->sec_attr.ccha_acc_num)
-+                      continue;
-+
-+              /* Skip POLY1305 algorithms if not supported by device */
-+              if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 &&
-+                  !priv->sec_attr.ptha_acc_num)
-+                      continue;
-+
-+              /*
-+               * Skip algorithms requiring message digests
-+               * if MD not supported by device.
-+               */
-+              if ((c2_alg_sel & ~OP_ALG_ALGSEL_SUBMASK) == 0x40 &&
-+                  !priv->sec_attr.md_acc_num)
-+                      continue;
-+
-+              t_alg->caam.dev = dev;
-+              caam_aead_alg_init(t_alg);
-+
-+              err = crypto_register_aead(&t_alg->aead);
-+              if (err) {
-+                      dev_warn(dev, "%s alg registration failed: %d\n",
-+                               t_alg->aead.base.cra_driver_name, err);
-+                      continue;
-+              }
-+
-+              t_alg->registered = true;
-+              registered = true;
-+      }
-+      if (registered)
-+              dev_info(dev, "algorithms registered in /proc/crypto\n");
-+
-+      /* register hash algorithms the device supports */
-+      INIT_LIST_HEAD(&hash_list);
-+
-+      /*
-+       * Skip registration of any hashing algorithms if MD block
-+       * is not present.
-+       */
-+      if (!priv->sec_attr.md_acc_num)
-+              return 0;
-+
-+      for (i = 0; i < ARRAY_SIZE(driver_hash); i++) {
-+              struct caam_hash_alg *t_alg;
-+              struct caam_hash_template *alg = driver_hash + i;
-+
-+              /* register hmac version */
-+              t_alg = caam_hash_alloc(dev, alg, true);
-+              if (IS_ERR(t_alg)) {
-+                      err = PTR_ERR(t_alg);
-+                      dev_warn(dev, "%s hash alg allocation failed: %d\n",
-+                               alg->driver_name, err);
-+                      continue;
-+              }
-+
-+              err = crypto_register_ahash(&t_alg->ahash_alg);
-+              if (err) {
-+                      dev_warn(dev, "%s alg registration failed: %d\n",
-+                               t_alg->ahash_alg.halg.base.cra_driver_name,
-+                               err);
-+                      kfree(t_alg);
-+              } else {
-+                      list_add_tail(&t_alg->entry, &hash_list);
-+              }
-+
-+              /* register unkeyed version */
-+              t_alg = caam_hash_alloc(dev, alg, false);
-+              if (IS_ERR(t_alg)) {
-+                      err = PTR_ERR(t_alg);
-+                      dev_warn(dev, "%s alg allocation failed: %d\n",
-+                               alg->driver_name, err);
-+                      continue;
-+              }
-+
-+              err = crypto_register_ahash(&t_alg->ahash_alg);
-+              if (err) {
-+                      dev_warn(dev, "%s alg registration failed: %d\n",
-+                               t_alg->ahash_alg.halg.base.cra_driver_name,
-+                               err);
-+                      kfree(t_alg);
-+              } else {
-+                      list_add_tail(&t_alg->entry, &hash_list);
-+              }
-+      }
-+      if (!list_empty(&hash_list))
-+              dev_info(dev, "hash algorithms registered in /proc/crypto\n");
-+
-+      return err;
-+
-+err_bind:
-+      dpaa2_dpseci_dpio_free(priv);
-+err_dpio_setup:
-+      dpaa2_dpseci_free(priv);
-+err_dpseci_setup:
-+      free_percpu(priv->ppriv);
-+err_alloc_ppriv:
-+      fsl_mc_portal_free(priv->mc_io);
-+err_dma_mask:
-+      kmem_cache_destroy(qi_cache);
-+err_qicache:
-+      dev_set_drvdata(dev, NULL);
-+
-+      return err;
-+}
-+
-+static int __cold dpaa2_caam_remove(struct fsl_mc_device *ls_dev)
-+{
-+      struct device *dev;
-+      struct dpaa2_caam_priv *priv;
-+      int i;
-+
-+      dev = &ls_dev->dev;
-+      priv = dev_get_drvdata(dev);
-+
-+      for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
-+              struct caam_aead_alg *t_alg = driver_aeads + i;
-+
-+              if (t_alg->registered)
-+                      crypto_unregister_aead(&t_alg->aead);
-+      }
-+
-+      for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
-+              struct caam_skcipher_alg *t_alg = driver_algs + i;
-+
-+              if (t_alg->registered)
-+                      crypto_unregister_skcipher(&t_alg->skcipher);
-+      }
-+
-+      if (hash_list.next) {
-+              struct caam_hash_alg *t_hash_alg, *p;
-+
-+              list_for_each_entry_safe(t_hash_alg, p, &hash_list, entry) {
-+                      crypto_unregister_ahash(&t_hash_alg->ahash_alg);
-+                      list_del(&t_hash_alg->entry);
-+                      kfree(t_hash_alg);
-+              }
-+      }
-+
-+      dpaa2_dpseci_disable(priv);
-+      dpaa2_dpseci_dpio_free(priv);
-+      dpaa2_dpseci_free(priv);
-+      free_percpu(priv->ppriv);
-+      fsl_mc_portal_free(priv->mc_io);
-+      dev_set_drvdata(dev, NULL);
-+      kmem_cache_destroy(qi_cache);
-+
-+      return 0;
-+}
-+
-+int dpaa2_caam_enqueue(struct device *dev, struct caam_request *req)
-+{
-+      struct dpaa2_fd fd;
-+      struct dpaa2_caam_priv *priv = dev_get_drvdata(dev);
-+      struct dpaa2_caam_priv_per_cpu *ppriv;
-+      int err = 0, i;
-+
-+      if (IS_ERR(req))
-+              return PTR_ERR(req);
-+
-+      if (priv->cscn_mem) {
-+              dma_sync_single_for_cpu(priv->dev, priv->cscn_dma,
-+                                      DPAA2_CSCN_SIZE,
-+                                      DMA_FROM_DEVICE);
-+              if (unlikely(dpaa2_cscn_state_congested(priv->cscn_mem_aligned))) {
-+                      dev_dbg_ratelimited(dev, "Dropping request\n");
-+                      return -EBUSY;
-+              }
-+      }
-+
-+      dpaa2_fl_set_flc(&req->fd_flt[1], req->flc_dma);
-+
-+      req->fd_flt_dma = dma_map_single(dev, req->fd_flt, sizeof(req->fd_flt),
-+                                       DMA_BIDIRECTIONAL);
-+      if (dma_mapping_error(dev, req->fd_flt_dma)) {
-+              dev_err(dev, "DMA mapping error for QI enqueue request\n");
-+              goto err_out;
-+      }
-+
-+      memset(&fd, 0, sizeof(fd));
-+      dpaa2_fd_set_format(&fd, dpaa2_fd_list);
-+      dpaa2_fd_set_addr(&fd, req->fd_flt_dma);
-+      dpaa2_fd_set_len(&fd, dpaa2_fl_get_len(&req->fd_flt[1]));
-+      dpaa2_fd_set_flc(&fd, req->flc_dma);
-+
-+      ppriv = this_cpu_ptr(priv->ppriv);
-+      for (i = 0; i < (priv->dpseci_attr.num_tx_queues << 1); i++) {
-+              err = dpaa2_io_service_enqueue_fq(ppriv->dpio, ppriv->req_fqid,
-+                                                &fd);
-+              if (err != -EBUSY)
-+                      break;
-+
-+              cpu_relax();
-+      }
-+
-+      if (unlikely(err)) {
-+              dev_err_ratelimited(dev, "Error enqueuing frame: %d\n", err);
-+              goto err_out;
-+      }
-+
-+      return -EINPROGRESS;
-+
-+err_out:
-+      dma_unmap_single(dev, req->fd_flt_dma, sizeof(req->fd_flt),
-+                       DMA_BIDIRECTIONAL);
-+      return -EIO;
-+}
-+EXPORT_SYMBOL(dpaa2_caam_enqueue);
-+
-+const struct fsl_mc_device_id dpaa2_caam_match_id_table[] = {
-+      {
-+              .vendor = FSL_MC_VENDOR_FREESCALE,
-+              .obj_type = "dpseci",
-+      },
-+      { .vendor = 0x0 }
-+};
-+
-+static struct fsl_mc_driver dpaa2_caam_driver = {
-+      .driver = {
-+              .name           = KBUILD_MODNAME,
-+              .owner          = THIS_MODULE,
-+      },
-+      .probe          = dpaa2_caam_probe,
-+      .remove         = dpaa2_caam_remove,
-+      .match_id_table = dpaa2_caam_match_id_table
-+};
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-+MODULE_AUTHOR("Freescale Semiconductor, Inc");
-+MODULE_DESCRIPTION("Freescale DPAA2 CAAM Driver");
-+
-+module_fsl_mc_driver(dpaa2_caam_driver);
---- /dev/null
-+++ b/drivers/crypto/caam/caamalg_qi2.h
-@@ -0,0 +1,276 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *     * Redistributions of source code must retain the above copyright
-+ *     notice, this list of conditions and the following disclaimer.
-+ *     * Redistributions in binary form must reproduce the above copyright
-+ *     notice, this list of conditions and the following disclaimer in the
-+ *     documentation and/or other materials provided with the distribution.
-+ *     * Neither the names of the above-listed copyright holders nor the
-+ *     names of any contributors may be used to endorse or promote products
-+ *     derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#ifndef _CAAMALG_QI2_H_
-+#define _CAAMALG_QI2_H_
-+
-+#include "../../../drivers/staging/fsl-mc/include/dpaa2-io.h"
-+#include "../../../drivers/staging/fsl-mc/include/dpaa2-fd.h"
-+#include <linux/threads.h>
-+#include "dpseci.h"
-+#include "desc_constr.h"
-+
-+#define DPAA2_CAAM_STORE_SIZE 16
-+/* NAPI weight *must* be a multiple of the store size. */
-+#define DPAA2_CAAM_NAPI_WEIGHT        64
-+
-+/* The congestion entrance threshold was chosen so that on LS2088
-+ * we support the maximum throughput for the available memory
-+ */
-+#define DPAA2_SEC_CONG_ENTRY_THRESH   (128 * 1024 * 1024)
-+#define DPAA2_SEC_CONG_EXIT_THRESH    (DPAA2_SEC_CONG_ENTRY_THRESH * 9 / 10)
-+
-+/**
-+ * dpaa2_caam_priv - driver private data
-+ * @dpseci_id: DPSECI object unique ID
-+ * @major_ver: DPSECI major version
-+ * @minor_ver: DPSECI minor version
-+ * @dpseci_attr: DPSECI attributes
-+ * @sec_attr: SEC engine attributes
-+ * @rx_queue_attr: array of Rx queue attributes
-+ * @tx_queue_attr: array of Tx queue attributes
-+ * @cscn_mem: pointer to memory region containing the
-+ *    dpaa2_cscn struct; it's size is larger than
-+ *    sizeof(struct dpaa2_cscn) to accommodate alignment
-+ * @cscn_mem_aligned: pointer to struct dpaa2_cscn; it is computed
-+ *    as PTR_ALIGN(cscn_mem, DPAA2_CSCN_ALIGN)
-+ * @cscn_dma: dma address used by the QMAN to write CSCN messages
-+ * @dev: device associated with the DPSECI object
-+ * @mc_io: pointer to MC portal's I/O object
-+ * @domain: IOMMU domain
-+ * @ppriv: per CPU pointers to privata data
-+ */
-+struct dpaa2_caam_priv {
-+      int dpsec_id;
-+
-+      u16 major_ver;
-+      u16 minor_ver;
-+
-+      struct dpseci_attr dpseci_attr;
-+      struct dpseci_sec_attr sec_attr;
-+      struct dpseci_rx_queue_attr rx_queue_attr[DPSECI_MAX_QUEUE_NUM];
-+      struct dpseci_tx_queue_attr tx_queue_attr[DPSECI_MAX_QUEUE_NUM];
-+      int num_pairs;
-+
-+      /* congestion */
-+      void *cscn_mem;
-+      void *cscn_mem_aligned;
-+      dma_addr_t cscn_dma;
-+
-+      struct device *dev;
-+      struct fsl_mc_io *mc_io;
-+      struct iommu_domain *domain;
-+
-+      struct dpaa2_caam_priv_per_cpu __percpu *ppriv;
-+};
-+
-+/**
-+ * dpaa2_caam_priv_per_cpu - per CPU private data
-+ * @napi: napi structure
-+ * @net_dev: netdev used by napi
-+ * @req_fqid: (virtual) request (Tx / enqueue) FQID
-+ * @rsp_fqid: (virtual) response (Rx / dequeue) FQID
-+ * @prio: internal queue number - index for dpaa2_caam_priv.*_queue_attr
-+ * @nctx: notification context of response FQ
-+ * @store: where dequeued frames are stored
-+ * @priv: backpointer to dpaa2_caam_priv
-+ * @dpio: portal used for data path operations
-+ */
-+struct dpaa2_caam_priv_per_cpu {
-+      struct napi_struct napi;
-+      struct net_device net_dev;
-+      int req_fqid;
-+      int rsp_fqid;
-+      int prio;
-+      struct dpaa2_io_notification_ctx nctx;
-+      struct dpaa2_io_store *store;
-+      struct dpaa2_caam_priv *priv;
-+      struct dpaa2_io *dpio;
-+};
-+
-+/*
-+ * The CAAM QI hardware constructs a job descriptor which points
-+ * to shared descriptor (as pointed by context_a of FQ to CAAM).
-+ * When the job descriptor is executed by deco, the whole job
-+ * descriptor together with shared descriptor gets loaded in
-+ * deco buffer which is 64 words long (each 32-bit).
-+ *
-+ * The job descriptor constructed by QI hardware has layout:
-+ *
-+ *    HEADER          (1 word)
-+ *    Shdesc ptr      (1 or 2 words)
-+ *    SEQ_OUT_PTR     (1 word)
-+ *    Out ptr         (1 or 2 words)
-+ *    Out length      (1 word)
-+ *    SEQ_IN_PTR      (1 word)
-+ *    In ptr          (1 or 2 words)
-+ *    In length       (1 word)
-+ *
-+ * The shdesc ptr is used to fetch shared descriptor contents
-+ * into deco buffer.
-+ *
-+ * Apart from shdesc contents, the total number of words that
-+ * get loaded in deco buffer are '8' or '11'. The remaining words
-+ * in deco buffer can be used for storing shared descriptor.
-+ */
-+#define MAX_SDLEN     ((CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN) / CAAM_CMD_SZ)
-+
-+/* Length of a single buffer in the QI driver memory cache */
-+#define CAAM_QI_MEMCACHE_SIZE 512
-+
-+/*
-+ * aead_edesc - s/w-extended aead descriptor
-+ * @src_nents: number of segments in input scatterlist
-+ * @dst_nents: number of segments in output scatterlist
-+ * @iv_dma: dma address of iv for checking continuity and link table
-+ * @qm_sg_bytes: length of dma mapped h/w link table
-+ * @qm_sg_dma: bus physical mapped address of h/w link table
-+ * @assoclen: associated data length, in CAAM endianness
-+ * @assoclen_dma: bus physical mapped address of req->assoclen
-+ * @sgt: the h/w link table, followed by IV
-+ */
-+struct aead_edesc {
-+      int src_nents;
-+      int dst_nents;
-+      dma_addr_t iv_dma;
-+      int qm_sg_bytes;
-+      dma_addr_t qm_sg_dma;
-+      unsigned int assoclen;
-+      dma_addr_t assoclen_dma;
-+      struct dpaa2_sg_entry sgt[0];
-+};
-+
-+/*
-+ * tls_edesc - s/w-extended tls descriptor
-+ * @src_nents: number of segments in input scatterlist
-+ * @dst_nents: number of segments in output scatterlist
-+ * @iv_dma: dma address of iv for checking continuity and link table
-+ * @qm_sg_bytes: length of dma mapped h/w link table
-+ * @qm_sg_dma: bus physical mapped address of h/w link table
-+ * @tmp: array of scatterlists used by 'scatterwalk_ffwd'
-+ * @dst: pointer to output scatterlist, usefull for unmapping
-+ * @sgt: the h/w link table, followed by IV
-+ */
-+struct tls_edesc {
-+      int src_nents;
-+      int dst_nents;
-+      dma_addr_t iv_dma;
-+      int qm_sg_bytes;
-+      dma_addr_t qm_sg_dma;
-+      struct scatterlist tmp[2];
-+      struct scatterlist *dst;
-+      struct dpaa2_sg_entry sgt[0];
-+};
-+
-+/*
-+ * skcipher_edesc - s/w-extended skcipher descriptor
-+ * @src_nents: number of segments in input scatterlist
-+ * @dst_nents: number of segments in output scatterlist
-+ * @iv_dma: dma address of iv for checking continuity and link table
-+ * @qm_sg_bytes: length of dma mapped qm_sg space
-+ * @qm_sg_dma: I/O virtual address of h/w link table
-+ * @sgt: the h/w link table, followed by IV
-+ */
-+struct skcipher_edesc {
-+      int src_nents;
-+      int dst_nents;
-+      dma_addr_t iv_dma;
-+      int qm_sg_bytes;
-+      dma_addr_t qm_sg_dma;
-+      struct dpaa2_sg_entry sgt[0];
-+};
-+
-+/*
-+ * ahash_edesc - s/w-extended ahash descriptor
-+ * @dst_dma: I/O virtual address of req->result
-+ * @qm_sg_dma: I/O virtual address of h/w link table
-+ * @src_nents: number of segments in input scatterlist
-+ * @qm_sg_bytes: length of dma mapped qm_sg space
-+ * @sgt: pointer to h/w link table
-+ */
-+struct ahash_edesc {
-+      dma_addr_t dst_dma;
-+      dma_addr_t qm_sg_dma;
-+      int src_nents;
-+      int qm_sg_bytes;
-+      struct dpaa2_sg_entry sgt[0];
-+};
-+
-+/**
-+ * caam_flc - Flow Context (FLC)
-+ * @flc: Flow Context options
-+ * @sh_desc: Shared Descriptor
-+ */
-+struct caam_flc {
-+      u32 flc[16];
-+      u32 sh_desc[MAX_SDLEN];
-+} ____cacheline_aligned;
-+
-+enum optype {
-+      ENCRYPT = 0,
-+      DECRYPT,
-+      NUM_OP
-+};
-+
-+/**
-+ * caam_request - the request structure the driver application should fill while
-+ *                submitting a job to driver.
-+ * @fd_flt: Frame list table defining input and output
-+ *          fd_flt[0] - FLE pointing to output buffer
-+ *          fd_flt[1] - FLE pointing to input buffer
-+ * @fd_flt_dma: DMA address for the frame list table
-+ * @flc: Flow Context
-+ * @flc_dma: I/O virtual address of Flow Context
-+ * @cbk: Callback function to invoke when job is completed
-+ * @ctx: arbit context attached with request by the application
-+ * @edesc: extended descriptor; points to one of {skcipher,aead}_edesc
-+ */
-+struct caam_request {
-+      struct dpaa2_fl_entry fd_flt[2];
-+      dma_addr_t fd_flt_dma;
-+      struct caam_flc *flc;
-+      dma_addr_t flc_dma;
-+      void (*cbk)(void *ctx, u32 err);
-+      void *ctx;
-+      void *edesc;
-+};
-+
-+/**
-+ * dpaa2_caam_enqueue() - enqueue a crypto request
-+ * @dev: device associated with the DPSECI object
-+ * @req: pointer to caam_request
-+ */
-+int dpaa2_caam_enqueue(struct device *dev, struct caam_request *req);
-+
-+#endif        /* _CAAMALG_QI2_H_ */
---- a/drivers/crypto/caam/caamhash.c
-+++ b/drivers/crypto/caam/caamhash.c
-@@ -2,6 +2,7 @@
-  * caam - Freescale FSL CAAM support for ahash functions of crypto API
-  *
-  * Copyright 2011 Freescale Semiconductor, Inc.
-+ * Copyright 2018 NXP
-  *
-  * Based on caamalg.c crypto API driver.
-  *
-@@ -62,6 +63,7 @@
- #include "error.h"
- #include "sg_sw_sec4.h"
- #include "key_gen.h"
-+#include "caamhash_desc.h"
- #define CAAM_CRA_PRIORITY             3000
-@@ -71,14 +73,6 @@
- #define CAAM_MAX_HASH_BLOCK_SIZE      SHA512_BLOCK_SIZE
- #define CAAM_MAX_HASH_DIGEST_SIZE     SHA512_DIGEST_SIZE
--/* length of descriptors text */
--#define DESC_AHASH_BASE                       (3 * CAAM_CMD_SZ)
--#define DESC_AHASH_UPDATE_LEN         (6 * CAAM_CMD_SZ)
--#define DESC_AHASH_UPDATE_FIRST_LEN   (DESC_AHASH_BASE + 4 * CAAM_CMD_SZ)
--#define DESC_AHASH_FINAL_LEN          (DESC_AHASH_BASE + 5 * CAAM_CMD_SZ)
--#define DESC_AHASH_FINUP_LEN          (DESC_AHASH_BASE + 5 * CAAM_CMD_SZ)
--#define DESC_AHASH_DIGEST_LEN         (DESC_AHASH_BASE + 4 * CAAM_CMD_SZ)
--
- #define DESC_HASH_MAX_USED_BYTES      (DESC_AHASH_FINAL_LEN + \
-                                        CAAM_MAX_HASH_KEY_SIZE)
- #define DESC_HASH_MAX_USED_LEN                (DESC_HASH_MAX_USED_BYTES / CAAM_CMD_SZ)
-@@ -107,6 +101,7 @@ struct caam_hash_ctx {
-       dma_addr_t sh_desc_update_first_dma;
-       dma_addr_t sh_desc_fin_dma;
-       dma_addr_t sh_desc_digest_dma;
-+      enum dma_data_direction dir;
-       struct device *jrdev;
-       u8 key[CAAM_MAX_HASH_KEY_SIZE];
-       int ctx_len;
-@@ -218,7 +213,7 @@ static inline int buf_map_to_sec4_sg(str
- }
- /* Map state->caam_ctx, and add it to link table */
--static inline int ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev,
-+static inline int ctx_map_to_sec4_sg(struct device *jrdev,
-                                    struct caam_hash_state *state, int ctx_len,
-                                    struct sec4_sg_entry *sec4_sg, u32 flag)
- {
-@@ -234,68 +229,22 @@ static inline int ctx_map_to_sec4_sg(u32
-       return 0;
- }
--/*
-- * For ahash update, final and finup (import_ctx = true)
-- *     import context, read and write to seqout
-- * For ahash firsts and digest (import_ctx = false)
-- *     read and write to seqout
-- */
--static inline void ahash_gen_sh_desc(u32 *desc, u32 state, int digestsize,
--                                   struct caam_hash_ctx *ctx, bool import_ctx)
--{
--      u32 op = ctx->adata.algtype;
--      u32 *skip_key_load;
--
--      init_sh_desc(desc, HDR_SHARE_SERIAL);
--
--      /* Append key if it has been set; ahash update excluded */
--      if ((state != OP_ALG_AS_UPDATE) && (ctx->adata.keylen)) {
--              /* Skip key loading if already shared */
--              skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
--                                          JUMP_COND_SHRD);
--
--              append_key_as_imm(desc, ctx->key, ctx->adata.keylen_pad,
--                                ctx->adata.keylen, CLASS_2 |
--                                KEY_DEST_MDHA_SPLIT | KEY_ENC);
--
--              set_jump_tgt_here(desc, skip_key_load);
--
--              op |= OP_ALG_AAI_HMAC_PRECOMP;
--      }
--
--      /* If needed, import context from software */
--      if (import_ctx)
--              append_seq_load(desc, ctx->ctx_len, LDST_CLASS_2_CCB |
--                              LDST_SRCDST_BYTE_CONTEXT);
--
--      /* Class 2 operation */
--      append_operation(desc, op | state | OP_ALG_ENCRYPT);
--
--      /*
--       * Load from buf and/or src and write to req->result or state->context
--       * Calculate remaining bytes to read
--       */
--      append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
--      /* Read remaining bytes */
--      append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 |
--                           FIFOLD_TYPE_MSG | KEY_VLF);
--      /* Store class2 context bytes */
--      append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
--                       LDST_SRCDST_BYTE_CONTEXT);
--}
--
- static int ahash_set_sh_desc(struct crypto_ahash *ahash)
- {
-       struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-       int digestsize = crypto_ahash_digestsize(ahash);
-       struct device *jrdev = ctx->jrdev;
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
-       u32 *desc;
-+      ctx->adata.key_virt = ctx->key;
-+
-       /* ahash_update shared descriptor */
-       desc = ctx->sh_desc_update;
--      ahash_gen_sh_desc(desc, OP_ALG_AS_UPDATE, ctx->ctx_len, ctx, true);
-+      cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_UPDATE, ctx->ctx_len,
-+                        ctx->ctx_len, true, ctrlpriv->era);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_update_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
- #ifdef DEBUG
-       print_hex_dump(KERN_ERR,
-                      "ahash update shdesc@"__stringify(__LINE__)": ",
-@@ -304,9 +253,10 @@ static int ahash_set_sh_desc(struct cryp
-       /* ahash_update_first shared descriptor */
-       desc = ctx->sh_desc_update_first;
--      ahash_gen_sh_desc(desc, OP_ALG_AS_INIT, ctx->ctx_len, ctx, false);
-+      cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_INIT, ctx->ctx_len,
-+                        ctx->ctx_len, false, ctrlpriv->era);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_update_first_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
- #ifdef DEBUG
-       print_hex_dump(KERN_ERR,
-                      "ahash update first shdesc@"__stringify(__LINE__)": ",
-@@ -315,9 +265,10 @@ static int ahash_set_sh_desc(struct cryp
-       /* ahash_final shared descriptor */
-       desc = ctx->sh_desc_fin;
--      ahash_gen_sh_desc(desc, OP_ALG_AS_FINALIZE, digestsize, ctx, true);
-+      cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_FINALIZE, digestsize,
-+                        ctx->ctx_len, true, ctrlpriv->era);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_fin_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
- #ifdef DEBUG
-       print_hex_dump(KERN_ERR, "ahash final shdesc@"__stringify(__LINE__)": ",
-                      DUMP_PREFIX_ADDRESS, 16, 4, desc,
-@@ -326,9 +277,10 @@ static int ahash_set_sh_desc(struct cryp
-       /* ahash_digest shared descriptor */
-       desc = ctx->sh_desc_digest;
--      ahash_gen_sh_desc(desc, OP_ALG_AS_INITFINAL, digestsize, ctx, false);
-+      cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_INITFINAL, digestsize,
-+                        ctx->ctx_len, false, ctrlpriv->era);
-       dma_sync_single_for_device(jrdev, ctx->sh_desc_digest_dma,
--                                 desc_bytes(desc), DMA_TO_DEVICE);
-+                                 desc_bytes(desc), ctx->dir);
- #ifdef DEBUG
-       print_hex_dump(KERN_ERR,
-                      "ahash digest shdesc@"__stringify(__LINE__)": ",
-@@ -421,6 +373,7 @@ static int ahash_setkey(struct crypto_ah
-       struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
-       int blocksize = crypto_tfm_alg_blocksize(&ahash->base);
-       int digestsize = crypto_ahash_digestsize(ahash);
-+      struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
-       int ret;
-       u8 *hashed_key = NULL;
-@@ -441,16 +394,26 @@ static int ahash_setkey(struct crypto_ah
-               key = hashed_key;
-       }
--      ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, key, keylen,
--                          CAAM_MAX_HASH_KEY_SIZE);
--      if (ret)
--              goto bad_free_key;
-+      /*
-+       * If DKP is supported, use it in the shared descriptor to generate
-+       * the split key.
-+       */
-+      if (ctrlpriv->era >= 6) {
-+              ctx->adata.key_inline = true;
-+              ctx->adata.keylen = keylen;
-+              ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
-+                                                    OP_ALG_ALGSEL_MASK);
--#ifdef DEBUG
--      print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
--                     DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
--                     ctx->adata.keylen_pad, 1);
--#endif
-+              if (ctx->adata.keylen_pad > CAAM_MAX_HASH_KEY_SIZE)
-+                      goto bad_free_key;
-+
-+              memcpy(ctx->key, key, keylen);
-+      } else {
-+              ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, key,
-+                                  keylen, CAAM_MAX_HASH_KEY_SIZE);
-+              if (ret)
-+                      goto bad_free_key;
-+      }
-       kfree(hashed_key);
-       return ahash_set_sh_desc(ahash);
-@@ -773,7 +736,7 @@ static int ahash_update_ctx(struct ahash
-               edesc->src_nents = src_nents;
-               edesc->sec4_sg_bytes = sec4_sg_bytes;
--              ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
-+              ret = ctx_map_to_sec4_sg(jrdev, state, ctx->ctx_len,
-                                        edesc->sec4_sg, DMA_BIDIRECTIONAL);
-               if (ret)
-                       goto unmap_ctx;
-@@ -871,9 +834,8 @@ static int ahash_final_ctx(struct ahash_
-       desc = edesc->hw_desc;
-       edesc->sec4_sg_bytes = sec4_sg_bytes;
--      edesc->src_nents = 0;
--      ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
-+      ret = ctx_map_to_sec4_sg(jrdev, state, ctx->ctx_len,
-                                edesc->sec4_sg, DMA_TO_DEVICE);
-       if (ret)
-               goto unmap_ctx;
-@@ -967,7 +929,7 @@ static int ahash_finup_ctx(struct ahash_
-       edesc->src_nents = src_nents;
--      ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
-+      ret = ctx_map_to_sec4_sg(jrdev, state, ctx->ctx_len,
-                                edesc->sec4_sg, DMA_TO_DEVICE);
-       if (ret)
-               goto unmap_ctx;
-@@ -1126,7 +1088,6 @@ static int ahash_final_no_ctx(struct aha
-               dev_err(jrdev, "unable to map dst\n");
-               goto unmap;
-       }
--      edesc->src_nents = 0;
- #ifdef DEBUG
-       print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
-@@ -1208,7 +1169,6 @@ static int ahash_update_no_ctx(struct ah
-               edesc->src_nents = src_nents;
-               edesc->sec4_sg_bytes = sec4_sg_bytes;
--              edesc->dst_dma = 0;
-               ret = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg, state);
-               if (ret)
-@@ -1420,7 +1380,6 @@ static int ahash_update_first(struct aha
-               }
-               edesc->src_nents = src_nents;
--              edesc->dst_dma = 0;
-               ret = ahash_edesc_add_src(ctx, edesc, req, mapped_nents, 0, 0,
-                                         to_hash);
-@@ -1722,6 +1681,7 @@ static int caam_hash_cra_init(struct cry
-                                        HASH_MSG_LEN + 64,
-                                        HASH_MSG_LEN + SHA512_DIGEST_SIZE };
-       dma_addr_t dma_addr;
-+      struct caam_drv_private *priv;
-       /*
-        * Get a Job ring from Job Ring driver to ensure in-order
-@@ -1733,10 +1693,13 @@ static int caam_hash_cra_init(struct cry
-               return PTR_ERR(ctx->jrdev);
-       }
-+      priv = dev_get_drvdata(ctx->jrdev->parent);
-+      ctx->dir = priv->era >= 6 ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
-+
-       dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_update,
-                                       offsetof(struct caam_hash_ctx,
-                                                sh_desc_update_dma),
--                                      DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
-+                                      ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
-       if (dma_mapping_error(ctx->jrdev, dma_addr)) {
-               dev_err(ctx->jrdev, "unable to map shared descriptors\n");
-               caam_jr_free(ctx->jrdev);
-@@ -1771,11 +1734,11 @@ static void caam_hash_cra_exit(struct cr
-       dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_update_dma,
-                              offsetof(struct caam_hash_ctx,
-                                       sh_desc_update_dma),
--                             DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
-+                             ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
-       caam_jr_free(ctx->jrdev);
- }
--static void __exit caam_algapi_hash_exit(void)
-+void caam_algapi_hash_exit(void)
- {
-       struct caam_hash_alg *t_alg, *n;
-@@ -1834,56 +1797,38 @@ caam_hash_alloc(struct caam_hash_templat
-       return t_alg;
- }
--static int __init caam_algapi_hash_init(void)
-+int caam_algapi_hash_init(struct device *ctrldev)
- {
--      struct device_node *dev_node;
--      struct platform_device *pdev;
--      struct device *ctrldev;
-       int i = 0, err = 0;
--      struct caam_drv_private *priv;
-+      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
-       unsigned int md_limit = SHA512_DIGEST_SIZE;
--      u32 cha_inst, cha_vid;
--
--      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
--      if (!dev_node) {
--              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
--              if (!dev_node)
--                      return -ENODEV;
--      }
--
--      pdev = of_find_device_by_node(dev_node);
--      if (!pdev) {
--              of_node_put(dev_node);
--              return -ENODEV;
--      }
--
--      ctrldev = &pdev->dev;
--      priv = dev_get_drvdata(ctrldev);
--      of_node_put(dev_node);
--
--      /*
--       * If priv is NULL, it's probably because the caam driver wasn't
--       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
--       */
--      if (!priv)
--              return -ENODEV;
-+      u32 md_inst, md_vid;
-       /*
-        * Register crypto algorithms the device supports.  First, identify
-        * presence and attributes of MD block.
-        */
--      cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
--      cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
-+      if (priv->era < 10) {
-+              md_vid = (rd_reg32(&priv->ctrl->perfmon.cha_id_ls) &
-+                        CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
-+              md_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) &
-+                         CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
-+      } else {
-+              u32 mdha = rd_reg32(&priv->ctrl->vreg.mdha);
-+
-+              md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
-+              md_inst = mdha & CHA_VER_NUM_MASK;
-+      }
-       /*
-        * Skip registration of any hashing algorithms if MD block
-        * is not present.
-        */
--      if (!((cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT))
-+      if (!md_inst)
-               return -ENODEV;
-       /* Limit digest size based on LP256 */
--      if ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256)
-+      if (md_vid == CHA_VER_VID_MD_LP256)
-               md_limit = SHA256_DIGEST_SIZE;
-       INIT_LIST_HEAD(&hash_list);
-@@ -1934,10 +1879,3 @@ static int __init caam_algapi_hash_init(
-       return err;
- }
--
--module_init(caam_algapi_hash_init);
--module_exit(caam_algapi_hash_exit);
--
--MODULE_LICENSE("GPL");
--MODULE_DESCRIPTION("FSL CAAM support for ahash functions of crypto API");
--MODULE_AUTHOR("Freescale Semiconductor - NMG");
---- /dev/null
-+++ b/drivers/crypto/caam/caamhash_desc.c
-@@ -0,0 +1,108 @@
-+/*
-+ * Shared descriptors for ahash algorithms
-+ *
-+ * Copyright 2017 NXP
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *     * Redistributions of source code must retain the above copyright
-+ *     notice, this list of conditions and the following disclaimer.
-+ *     * Redistributions in binary form must reproduce the above copyright
-+ *     notice, this list of conditions and the following disclaimer in the
-+ *     documentation and/or other materials provided with the distribution.
-+ *     * Neither the names of the above-listed copyright holders nor the
-+ *     names of any contributors may be used to endorse or promote products
-+ *     derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include "compat.h"
-+#include "desc_constr.h"
-+#include "caamhash_desc.h"
-+
-+/**
-+ * cnstr_shdsc_ahash - ahash shared descriptor
-+ * @desc: pointer to buffer used for descriptor construction
-+ * @adata: pointer to authentication transform definitions.
-+ *         A split key is required for SEC Era < 6; the size of the split key
-+ *         is specified in this case.
-+ *         Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
-+ *         SHA256, SHA384, SHA512}.
-+ * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
-+ * @digestsize: algorithm's digest size
-+ * @ctx_len: size of Context Register
-+ * @import_ctx: true if previous Context Register needs to be restored
-+ *              must be true for ahash update and final
-+ *              must be false for for ahash first and digest
-+ * @era: SEC Era
-+ */
-+void cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state,
-+                     int digestsize, int ctx_len, bool import_ctx, int era)
-+{
-+      u32 op = adata->algtype;
-+
-+      init_sh_desc(desc, HDR_SHARE_SERIAL);
-+
-+      /* Append key if it has been set; ahash update excluded */
-+      if (state != OP_ALG_AS_UPDATE && adata->keylen) {
-+              u32 *skip_key_load;
-+
-+              /* Skip key loading if already shared */
-+              skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
-+                                          JUMP_COND_SHRD);
-+
-+              if (era < 6)
-+                      append_key_as_imm(desc, adata->key_virt,
-+                                        adata->keylen_pad,
-+                                        adata->keylen, CLASS_2 |
-+                                        KEY_DEST_MDHA_SPLIT | KEY_ENC);
-+              else
-+                      append_proto_dkp(desc, adata);
-+
-+              set_jump_tgt_here(desc, skip_key_load);
-+
-+              op |= OP_ALG_AAI_HMAC_PRECOMP;
-+      }
-+
-+      /* If needed, import context from software */
-+      if (import_ctx)
-+              append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB |
-+                              LDST_SRCDST_BYTE_CONTEXT);
-+
-+      /* Class 2 operation */
-+      append_operation(desc, op | state | OP_ALG_ENCRYPT);
-+
-+      /*
-+       * Load from buf and/or src and write to req->result or state->context
-+       * Calculate remaining bytes to read
-+       */
-+      append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
-+      /* Read remaining bytes */
-+      append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 |
-+                           FIFOLD_TYPE_MSG | KEY_VLF);
-+      /* Store class2 context bytes */
-+      append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
-+                       LDST_SRCDST_BYTE_CONTEXT);
-+}
-+EXPORT_SYMBOL(cnstr_shdsc_ahash);
-+
-+MODULE_LICENSE("Dual BSD/GPL");
-+MODULE_DESCRIPTION("FSL CAAM ahash descriptors support");
-+MODULE_AUTHOR("NXP Semiconductors");
---- /dev/null
-+++ b/drivers/crypto/caam/caamhash_desc.h
-@@ -0,0 +1,49 @@
-+/*
-+ * Shared descriptors for ahash algorithms
-+ *
-+ * Copyright 2017 NXP
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *     * Redistributions of source code must retain the above copyright
-+ *     notice, this list of conditions and the following disclaimer.
-+ *     * Redistributions in binary form must reproduce the above copyright
-+ *     notice, this list of conditions and the following disclaimer in the
-+ *     documentation and/or other materials provided with the distribution.
-+ *     * Neither the names of the above-listed copyright holders nor the
-+ *     names of any contributors may be used to endorse or promote products
-+ *     derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#ifndef _CAAMHASH_DESC_H_
-+#define _CAAMHASH_DESC_H_
-+
-+/* length of descriptors text */
-+#define DESC_AHASH_BASE                       (3 * CAAM_CMD_SZ)
-+#define DESC_AHASH_UPDATE_LEN         (6 * CAAM_CMD_SZ)
-+#define DESC_AHASH_UPDATE_FIRST_LEN   (DESC_AHASH_BASE + 4 * CAAM_CMD_SZ)
-+#define DESC_AHASH_FINAL_LEN          (DESC_AHASH_BASE + 5 * CAAM_CMD_SZ)
-+#define DESC_AHASH_DIGEST_LEN         (DESC_AHASH_BASE + 4 * CAAM_CMD_SZ)
-+
-+void cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state,
-+                     int digestsize, int ctx_len, bool import_ctx, int era);
-+
-+#endif /* _CAAMHASH_DESC_H_ */
---- a/drivers/crypto/caam/caampkc.c
-+++ b/drivers/crypto/caam/caampkc.c
-@@ -2,6 +2,7 @@
-  * caam - Freescale FSL CAAM support for Public Key Cryptography
-  *
-  * Copyright 2016 Freescale Semiconductor, Inc.
-+ * Copyright 2018 NXP
-  *
-  * There is no Shared Descriptor for PKC so that the Job Descriptor must carry
-  * all the desired key parameters, input and output pointers.
-@@ -1017,46 +1018,22 @@ static struct akcipher_alg caam_rsa = {
- };
- /* Public Key Cryptography module initialization handler */
--static int __init caam_pkc_init(void)
-+int caam_pkc_init(struct device *ctrldev)
- {
--      struct device_node *dev_node;
--      struct platform_device *pdev;
--      struct device *ctrldev;
--      struct caam_drv_private *priv;
--      u32 cha_inst, pk_inst;
-+      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
-+      u32 pk_inst;
-       int err;
--      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
--      if (!dev_node) {
--              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
--              if (!dev_node)
--                      return -ENODEV;
--      }
--
--      pdev = of_find_device_by_node(dev_node);
--      if (!pdev) {
--              of_node_put(dev_node);
--              return -ENODEV;
--      }
--
--      ctrldev = &pdev->dev;
--      priv = dev_get_drvdata(ctrldev);
--      of_node_put(dev_node);
--
--      /*
--       * If priv is NULL, it's probably because the caam driver wasn't
--       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
--       */
--      if (!priv)
--              return -ENODEV;
--
-       /* Determine public key hardware accelerator presence. */
--      cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
--      pk_inst = (cha_inst & CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT;
-+      if (priv->era < 10)
-+              pk_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) &
-+                         CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT;
-+      else
-+              pk_inst = rd_reg32(&priv->ctrl->vreg.pkha) & CHA_VER_NUM_MASK;
-       /* Do not register algorithms if PKHA is not present. */
-       if (!pk_inst)
--              return -ENODEV;
-+              return 0;
-       err = crypto_register_akcipher(&caam_rsa);
-       if (err)
-@@ -1068,14 +1045,7 @@ static int __init caam_pkc_init(void)
-       return err;
- }
--static void __exit caam_pkc_exit(void)
-+void caam_pkc_exit(void)
- {
-       crypto_unregister_akcipher(&caam_rsa);
- }
--
--module_init(caam_pkc_init);
--module_exit(caam_pkc_exit);
--
--MODULE_LICENSE("Dual BSD/GPL");
--MODULE_DESCRIPTION("FSL CAAM support for PKC functions of crypto API");
--MODULE_AUTHOR("Freescale Semiconductor");
---- a/drivers/crypto/caam/caamrng.c
-+++ b/drivers/crypto/caam/caamrng.c
-@@ -2,6 +2,7 @@
-  * caam - Freescale FSL CAAM support for hw_random
-  *
-  * Copyright 2011 Freescale Semiconductor, Inc.
-+ * Copyright 2018 NXP
-  *
-  * Based on caamalg.c crypto API driver.
-  *
-@@ -294,49 +295,29 @@ static struct hwrng caam_rng = {
-       .read           = caam_read,
- };
--static void __exit caam_rng_exit(void)
-+void caam_rng_exit(void)
- {
-       caam_jr_free(rng_ctx->jrdev);
-       hwrng_unregister(&caam_rng);
-       kfree(rng_ctx);
- }
--static int __init caam_rng_init(void)
-+int caam_rng_init(struct device *ctrldev)
- {
-       struct device *dev;
--      struct device_node *dev_node;
--      struct platform_device *pdev;
--      struct device *ctrldev;
--      struct caam_drv_private *priv;
-+      u32 rng_inst;
-+      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
-       int err;
--      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
--      if (!dev_node) {
--              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
--              if (!dev_node)
--                      return -ENODEV;
--      }
--
--      pdev = of_find_device_by_node(dev_node);
--      if (!pdev) {
--              of_node_put(dev_node);
--              return -ENODEV;
--      }
--
--      ctrldev = &pdev->dev;
--      priv = dev_get_drvdata(ctrldev);
--      of_node_put(dev_node);
--
--      /*
--       * If priv is NULL, it's probably because the caam driver wasn't
--       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
--       */
--      if (!priv)
--              return -ENODEV;
--
-       /* Check for an instantiated RNG before registration */
--      if (!(rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & CHA_ID_LS_RNG_MASK))
--              return -ENODEV;
-+      if (priv->era < 10)
-+              rng_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) &
-+                          CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
-+      else
-+              rng_inst = rd_reg32(&priv->ctrl->vreg.rng) & CHA_VER_NUM_MASK;
-+
-+      if (!rng_inst)
-+              return 0;
-       dev = caam_jr_alloc();
-       if (IS_ERR(dev)) {
-@@ -364,10 +345,3 @@ free_caam_alloc:
-       caam_jr_free(dev);
-       return err;
- }
--
--module_init(caam_rng_init);
--module_exit(caam_rng_exit);
--
--MODULE_LICENSE("GPL");
--MODULE_DESCRIPTION("FSL CAAM support for hw_random API");
--MODULE_AUTHOR("Freescale Semiconductor - NMG");
---- a/drivers/crypto/caam/compat.h
-+++ b/drivers/crypto/caam/compat.h
-@@ -17,6 +17,7 @@
- #include <linux/of_platform.h>
- #include <linux/dma-mapping.h>
- #include <linux/io.h>
-+#include <linux/iommu.h>
- #include <linux/spinlock.h>
- #include <linux/rtnetlink.h>
- #include <linux/in.h>
-@@ -34,10 +35,13 @@
- #include <crypto/des.h>
- #include <crypto/sha.h>
- #include <crypto/md5.h>
-+#include <crypto/chacha20.h>
-+#include <crypto/poly1305.h>
- #include <crypto/internal/aead.h>
- #include <crypto/authenc.h>
- #include <crypto/akcipher.h>
- #include <crypto/scatterwalk.h>
-+#include <crypto/skcipher.h>
- #include <crypto/internal/skcipher.h>
- #include <crypto/internal/hash.h>
- #include <crypto/internal/rsa.h>
---- a/drivers/crypto/caam/ctrl.c
-+++ b/drivers/crypto/caam/ctrl.c
-@@ -2,6 +2,7 @@
-  * Controller-level driver, kernel property detection, initialization
-  *
-  * Copyright 2008-2012 Freescale Semiconductor, Inc.
-+ * Copyright 2018 NXP
-  */
- #include <linux/device.h>
-@@ -16,17 +17,15 @@
- #include "desc_constr.h"
- #include "ctrl.h"
--bool caam_little_end;
--EXPORT_SYMBOL(caam_little_end);
- bool caam_dpaa2;
- EXPORT_SYMBOL(caam_dpaa2);
--bool caam_imx;
--EXPORT_SYMBOL(caam_imx);
- #ifdef CONFIG_CAAM_QI
- #include "qi.h"
- #endif
-+static struct platform_device *caam_dma_dev;
-+
- /*
-  * i.MX targets tend to have clock control subsystems that can
-  * enable/disable clocking to our device.
-@@ -105,7 +104,7 @@ static inline int run_descriptor_deco0(s
-       struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl;
-       struct caam_deco __iomem *deco = ctrlpriv->deco;
-       unsigned int timeout = 100000;
--      u32 deco_dbg_reg, flags;
-+      u32 deco_dbg_reg, deco_state, flags;
-       int i;
-@@ -148,13 +147,22 @@ static inline int run_descriptor_deco0(s
-       timeout = 10000000;
-       do {
-               deco_dbg_reg = rd_reg32(&deco->desc_dbg);
-+
-+              if (ctrlpriv->era < 10)
-+                      deco_state = (deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) >>
-+                                   DESC_DBG_DECO_STAT_SHIFT;
-+              else
-+                      deco_state = (rd_reg32(&deco->dbg_exec) &
-+                                    DESC_DER_DECO_STAT_MASK) >>
-+                                   DESC_DER_DECO_STAT_SHIFT;
-+
-               /*
-                * If an error occured in the descriptor, then
-                * the DECO status field will be set to 0x0D
-                */
--              if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) ==
--                  DESC_DBG_DECO_STAT_HOST_ERR)
-+              if (deco_state == DECO_STAT_HOST_ERR)
-                       break;
-+
-               cpu_relax();
-       } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
-@@ -316,15 +324,15 @@ static int caam_remove(struct platform_d
-       of_platform_depopulate(ctrldev);
- #ifdef CONFIG_CAAM_QI
--      if (ctrlpriv->qidev)
--              caam_qi_shutdown(ctrlpriv->qidev);
-+      if (ctrlpriv->qi_init)
-+              caam_qi_shutdown(ctrldev);
- #endif
-       /*
-        * De-initialize RNG state handles initialized by this driver.
--       * In case of DPAA 2.x, RNG is managed by MC firmware.
-+       * In case of SoCs with Management Complex, RNG is managed by MC f/w.
-        */
--      if (!caam_dpaa2 && ctrlpriv->rng4_sh_init)
-+      if (!ctrlpriv->mc_en && ctrlpriv->rng4_sh_init)
-               deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init);
-       /* Shut down debug views */
-@@ -332,6 +340,9 @@ static int caam_remove(struct platform_d
-       debugfs_remove_recursive(ctrlpriv->dfs_root);
- #endif
-+      if (caam_dma_dev)
-+              platform_device_unregister(caam_dma_dev);
-+
-       /* Unmap controller region */
-       iounmap(ctrl);
-@@ -433,6 +444,10 @@ static int caam_probe(struct platform_de
-               {.family = "Freescale i.MX"},
-               {},
-       };
-+      static struct platform_device_info caam_dma_pdev_info = {
-+              .name = "caam-dma",
-+              .id = PLATFORM_DEVID_NONE
-+      };
-       struct device *dev;
-       struct device_node *nprop, *np;
-       struct caam_ctrl __iomem *ctrl;
-@@ -442,7 +457,7 @@ static int caam_probe(struct platform_de
-       struct caam_perfmon *perfmon;
- #endif
-       u32 scfgr, comp_params;
--      u32 cha_vid_ls;
-+      u8 rng_vid;
-       int pg_size;
-       int BLOCK_OFFSET = 0;
-@@ -454,15 +469,54 @@ static int caam_probe(struct platform_de
-       dev_set_drvdata(dev, ctrlpriv);
-       nprop = pdev->dev.of_node;
-+      /* Get configuration properties from device tree */
-+      /* First, get register page */
-+      ctrl = of_iomap(nprop, 0);
-+      if (!ctrl) {
-+              dev_err(dev, "caam: of_iomap() failed\n");
-+              return -ENOMEM;
-+      }
-+
-+      caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) &
-+                                (CSTA_PLEND | CSTA_ALT_PLEND));
-       caam_imx = (bool)soc_device_match(imx_soc);
-+      comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms);
-+      caam_dpaa2 = !!(comp_params & CTPR_MS_DPAA2);
-+      ctrlpriv->qi_present = !!(comp_params & CTPR_MS_QI_MASK);
-+
-+#ifdef CONFIG_CAAM_QI
-+      /* If (DPAA 1.x) QI present, check whether dependencies are available */
-+      if (ctrlpriv->qi_present && !caam_dpaa2) {
-+              ret = qman_is_probed();
-+              if (!ret) {
-+                      ret = -EPROBE_DEFER;
-+                      goto iounmap_ctrl;
-+              } else if (ret < 0) {
-+                      dev_err(dev, "failing probe due to qman probe error\n");
-+                      ret = -ENODEV;
-+                      goto iounmap_ctrl;
-+              }
-+
-+              ret = qman_portals_probed();
-+              if (!ret) {
-+                      ret = -EPROBE_DEFER;
-+                      goto iounmap_ctrl;
-+              } else if (ret < 0) {
-+                      dev_err(dev, "failing probe due to qman portals probe error\n");
-+                      ret = -ENODEV;
-+                      goto iounmap_ctrl;
-+              }
-+      }
-+#endif
-+
-       /* Enable clocking */
-       clk = caam_drv_identify_clk(&pdev->dev, "ipg");
-       if (IS_ERR(clk)) {
-               ret = PTR_ERR(clk);
-               dev_err(&pdev->dev,
-                       "can't identify CAAM ipg clk: %d\n", ret);
--              return ret;
-+              goto iounmap_ctrl;
-       }
-       ctrlpriv->caam_ipg = clk;
-@@ -471,7 +525,7 @@ static int caam_probe(struct platform_de
-               ret = PTR_ERR(clk);
-               dev_err(&pdev->dev,
-                       "can't identify CAAM mem clk: %d\n", ret);
--              return ret;
-+              goto iounmap_ctrl;
-       }
-       ctrlpriv->caam_mem = clk;
-@@ -480,7 +534,7 @@ static int caam_probe(struct platform_de
-               ret = PTR_ERR(clk);
-               dev_err(&pdev->dev,
-                       "can't identify CAAM aclk clk: %d\n", ret);
--              return ret;
-+              goto iounmap_ctrl;
-       }
-       ctrlpriv->caam_aclk = clk;
-@@ -490,7 +544,7 @@ static int caam_probe(struct platform_de
-                       ret = PTR_ERR(clk);
-                       dev_err(&pdev->dev,
-                               "can't identify CAAM emi_slow clk: %d\n", ret);
--                      return ret;
-+                      goto iounmap_ctrl;
-               }
-               ctrlpriv->caam_emi_slow = clk;
-       }
-@@ -498,7 +552,7 @@ static int caam_probe(struct platform_de
-       ret = clk_prepare_enable(ctrlpriv->caam_ipg);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "can't enable CAAM ipg clock: %d\n", ret);
--              return ret;
-+              goto iounmap_ctrl;
-       }
-       ret = clk_prepare_enable(ctrlpriv->caam_mem);
-@@ -523,25 +577,10 @@ static int caam_probe(struct platform_de
-               }
-       }
--      /* Get configuration properties from device tree */
--      /* First, get register page */
--      ctrl = of_iomap(nprop, 0);
--      if (ctrl == NULL) {
--              dev_err(dev, "caam: of_iomap() failed\n");
--              ret = -ENOMEM;
--              goto disable_caam_emi_slow;
--      }
--
--      caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) &
--                                (CSTA_PLEND | CSTA_ALT_PLEND));
--
--      /* Finding the page size for using the CTPR_MS register */
--      comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms);
--      pg_size = (comp_params & CTPR_MS_PG_SZ_MASK) >> CTPR_MS_PG_SZ_SHIFT;
--
-       /* Allocating the BLOCK_OFFSET based on the supported page size on
-        * the platform
-        */
-+      pg_size = (comp_params & CTPR_MS_PG_SZ_MASK) >> CTPR_MS_PG_SZ_SHIFT;
-       if (pg_size == 0)
-               BLOCK_OFFSET = PG_SIZE_4K;
-       else
-@@ -563,11 +602,14 @@ static int caam_probe(struct platform_de
-       /*
-        * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
-        * long pointers in master configuration register.
--       * In case of DPAA 2.x, Management Complex firmware performs
-+       * In case of SoCs with Management Complex, MC f/w performs
-        * the configuration.
-        */
--      caam_dpaa2 = !!(comp_params & CTPR_MS_DPAA2);
--      if (!caam_dpaa2)
-+      np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-mc");
-+      ctrlpriv->mc_en = !!np;
-+      of_node_put(np);
-+
-+      if (!ctrlpriv->mc_en)
-               clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR,
-                             MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
-                             MCFGR_WDENABLE | MCFGR_LARGE_BURST |
-@@ -612,14 +654,11 @@ static int caam_probe(struct platform_de
-       }
-       if (ret) {
-               dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);
--              goto iounmap_ctrl;
-+              goto disable_caam_emi_slow;
-       }
--      ret = of_platform_populate(nprop, caam_match, NULL, dev);
--      if (ret) {
--              dev_err(dev, "JR platform devices creation error\n");
--              goto iounmap_ctrl;
--      }
-+      ctrlpriv->era = caam_get_era();
-+      ctrlpriv->domain = iommu_get_domain_for_dev(dev);
- #ifdef CONFIG_DEBUG_FS
-       /*
-@@ -633,21 +672,7 @@ static int caam_probe(struct platform_de
-       ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root);
- #endif
--      ring = 0;
--      for_each_available_child_of_node(nprop, np)
--              if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
--                  of_device_is_compatible(np, "fsl,sec4.0-job-ring")) {
--                      ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *)
--                                           ((__force uint8_t *)ctrl +
--                                           (ring + JR_BLOCK_NUMBER) *
--                                            BLOCK_OFFSET
--                                           );
--                      ctrlpriv->total_jobrs++;
--                      ring++;
--              }
--
-       /* Check to see if (DPAA 1.x) QI present. If so, enable */
--      ctrlpriv->qi_present = !!(comp_params & CTPR_MS_QI_MASK);
-       if (ctrlpriv->qi_present && !caam_dpaa2) {
-               ctrlpriv->qi = (struct caam_queue_if __iomem __force *)
-                              ((__force uint8_t *)ctrl +
-@@ -664,6 +689,25 @@ static int caam_probe(struct platform_de
- #endif
-       }
-+      ret = of_platform_populate(nprop, caam_match, NULL, dev);
-+      if (ret) {
-+              dev_err(dev, "JR platform devices creation error\n");
-+              goto shutdown_qi;
-+      }
-+
-+      ring = 0;
-+      for_each_available_child_of_node(nprop, np)
-+              if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
-+                  of_device_is_compatible(np, "fsl,sec4.0-job-ring")) {
-+                      ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *)
-+                                           ((__force uint8_t *)ctrl +
-+                                           (ring + JR_BLOCK_NUMBER) *
-+                                            BLOCK_OFFSET
-+                                           );
-+                      ctrlpriv->total_jobrs++;
-+                      ring++;
-+              }
-+
-       /* If no QI and no rings specified, quit and go home */
-       if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) {
-               dev_err(dev, "no queues configured, terminating\n");
-@@ -671,15 +715,29 @@ static int caam_probe(struct platform_de
-               goto caam_remove;
-       }
--      cha_vid_ls = rd_reg32(&ctrl->perfmon.cha_id_ls);
-+      caam_dma_pdev_info.parent = dev;
-+      caam_dma_pdev_info.dma_mask = dma_get_mask(dev);
-+      caam_dma_dev = platform_device_register_full(&caam_dma_pdev_info);
-+      if (IS_ERR(caam_dma_dev)) {
-+              dev_err(dev, "Unable to create and register caam-dma dev\n");
-+              caam_dma_dev = 0;
-+      } else {
-+              set_dma_ops(&caam_dma_dev->dev, get_dma_ops(dev));
-+      }
-+
-+      if (ctrlpriv->era < 10)
-+              rng_vid = (rd_reg32(&ctrl->perfmon.cha_id_ls) &
-+                         CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
-+      else
-+              rng_vid = (rd_reg32(&ctrl->vreg.rng) & CHA_VER_VID_MASK) >>
-+                         CHA_VER_VID_SHIFT;
-       /*
-        * If SEC has RNG version >= 4 and RNG state handle has not been
-        * already instantiated, do RNG instantiation
--       * In case of DPAA 2.x, RNG is managed by MC firmware.
-+       * In case of SoCs with Management Complex, RNG is managed by MC f/w.
-        */
--      if (!caam_dpaa2 &&
--          (cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) {
-+      if (!ctrlpriv->mc_en && rng_vid >= 4) {
-               ctrlpriv->rng4_sh_init =
-                       rd_reg32(&ctrl->r4tst[0].rdsta);
-               /*
-@@ -746,10 +804,9 @@ static int caam_probe(struct platform_de
-       /* Report "alive" for developer to see */
-       dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,
--               caam_get_era());
--      dev_info(dev, "job rings = %d, qi = %d, dpaa2 = %s\n",
--               ctrlpriv->total_jobrs, ctrlpriv->qi_present,
--               caam_dpaa2 ? "yes" : "no");
-+               ctrlpriv->era);
-+      dev_info(dev, "job rings = %d, qi = %d\n",
-+               ctrlpriv->total_jobrs, ctrlpriv->qi_present);
- #ifdef CONFIG_DEBUG_FS
-       debugfs_create_file("rq_dequeued", S_IRUSR | S_IRGRP | S_IROTH,
-@@ -816,8 +873,11 @@ caam_remove:
-       caam_remove(pdev);
-       return ret;
--iounmap_ctrl:
--      iounmap(ctrl);
-+shutdown_qi:
-+#ifdef CONFIG_CAAM_QI
-+      if (ctrlpriv->qi_init)
-+              caam_qi_shutdown(dev);
-+#endif
- disable_caam_emi_slow:
-       if (ctrlpriv->caam_emi_slow)
-               clk_disable_unprepare(ctrlpriv->caam_emi_slow);
-@@ -827,6 +887,8 @@ disable_caam_mem:
-       clk_disable_unprepare(ctrlpriv->caam_mem);
- disable_caam_ipg:
-       clk_disable_unprepare(ctrlpriv->caam_ipg);
-+iounmap_ctrl:
-+      iounmap(ctrl);
-       return ret;
- }
---- a/drivers/crypto/caam/desc.h
-+++ b/drivers/crypto/caam/desc.h
-@@ -4,6 +4,7 @@
-  * Definitions to support CAAM descriptor instruction generation
-  *
-  * Copyright 2008-2011 Freescale Semiconductor, Inc.
-+ * Copyright 2018 NXP
-  */
- #ifndef DESC_H
-@@ -42,6 +43,7 @@
- #define CMD_SEQ_LOAD          (0x03 << CMD_SHIFT)
- #define CMD_FIFO_LOAD         (0x04 << CMD_SHIFT)
- #define CMD_SEQ_FIFO_LOAD     (0x05 << CMD_SHIFT)
-+#define CMD_MOVEB             (0x07 << CMD_SHIFT)
- #define CMD_STORE             (0x0a << CMD_SHIFT)
- #define CMD_SEQ_STORE         (0x0b << CMD_SHIFT)
- #define CMD_FIFO_STORE                (0x0c << CMD_SHIFT)
-@@ -242,6 +244,7 @@
- #define LDST_SRCDST_WORD_DESCBUF_SHARED       (0x42 << LDST_SRCDST_SHIFT)
- #define LDST_SRCDST_WORD_DESCBUF_JOB_WE       (0x45 << LDST_SRCDST_SHIFT)
- #define LDST_SRCDST_WORD_DESCBUF_SHARED_WE (0x46 << LDST_SRCDST_SHIFT)
-+#define LDST_SRCDST_WORD_INFO_FIFO_SM (0x71 << LDST_SRCDST_SHIFT)
- #define LDST_SRCDST_WORD_INFO_FIFO    (0x7a << LDST_SRCDST_SHIFT)
- /* Offset in source/destination */
-@@ -284,6 +287,12 @@
- #define LDLEN_SET_OFIFO_OFFSET_SHIFT  0
- #define LDLEN_SET_OFIFO_OFFSET_MASK   (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT)
-+/* Special Length definitions when dst=sm, nfifo-{sm,m} */
-+#define LDLEN_MATH0                   0
-+#define LDLEN_MATH1                   1
-+#define LDLEN_MATH2                   2
-+#define LDLEN_MATH3                   3
-+
- /*
-  * FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE
-  * Command Constructs
-@@ -355,6 +364,7 @@
- #define FIFOLD_TYPE_PK_N      (0x08 << FIFOLD_TYPE_SHIFT)
- #define FIFOLD_TYPE_PK_A      (0x0c << FIFOLD_TYPE_SHIFT)
- #define FIFOLD_TYPE_PK_B      (0x0d << FIFOLD_TYPE_SHIFT)
-+#define FIFOLD_TYPE_IFIFO     (0x0f << FIFOLD_TYPE_SHIFT)
- /* Other types. Need to OR in last/flush bits as desired */
- #define FIFOLD_TYPE_MSG_MASK  (0x38 << FIFOLD_TYPE_SHIFT)
-@@ -408,6 +418,7 @@
- #define FIFOST_TYPE_MESSAGE_DATA (0x30 << FIFOST_TYPE_SHIFT)
- #define FIFOST_TYPE_RNGSTORE   (0x34 << FIFOST_TYPE_SHIFT)
- #define FIFOST_TYPE_RNGFIFO    (0x35 << FIFOST_TYPE_SHIFT)
-+#define FIFOST_TYPE_METADATA   (0x3e << FIFOST_TYPE_SHIFT)
- #define FIFOST_TYPE_SKIP       (0x3f << FIFOST_TYPE_SHIFT)
- /*
-@@ -444,6 +455,18 @@
- #define OP_PCLID_DSAVERIFY    (0x16 << OP_PCLID_SHIFT)
- #define OP_PCLID_RSAENC_PUBKEY  (0x18 << OP_PCLID_SHIFT)
- #define OP_PCLID_RSADEC_PRVKEY  (0x19 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_MD5      (0x20 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_SHA1     (0x21 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_SHA224   (0x22 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_SHA256   (0x23 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_SHA384   (0x24 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_SHA512   (0x25 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_RIF_MD5  (0x60 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_RIF_SHA1 (0x61 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_RIF_SHA224       (0x62 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_RIF_SHA256       (0x63 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_RIF_SHA384       (0x64 << OP_PCLID_SHIFT)
-+#define OP_PCLID_DKP_RIF_SHA512       (0x65 << OP_PCLID_SHIFT)
- /* Assuming OP_TYPE = OP_TYPE_DECAP_PROTOCOL/ENCAP_PROTOCOL */
- #define OP_PCLID_IPSEC                (0x01 << OP_PCLID_SHIFT)
-@@ -1093,6 +1116,22 @@
- /* MacSec protinfos */
- #define OP_PCL_MACSEC                          0x0001
-+/* Derived Key Protocol (DKP) Protinfo */
-+#define OP_PCL_DKP_SRC_SHIFT  14
-+#define OP_PCL_DKP_SRC_MASK   (3 << OP_PCL_DKP_SRC_SHIFT)
-+#define OP_PCL_DKP_SRC_IMM    (0 << OP_PCL_DKP_SRC_SHIFT)
-+#define OP_PCL_DKP_SRC_SEQ    (1 << OP_PCL_DKP_SRC_SHIFT)
-+#define OP_PCL_DKP_SRC_PTR    (2 << OP_PCL_DKP_SRC_SHIFT)
-+#define OP_PCL_DKP_SRC_SGF    (3 << OP_PCL_DKP_SRC_SHIFT)
-+#define OP_PCL_DKP_DST_SHIFT  12
-+#define OP_PCL_DKP_DST_MASK   (3 << OP_PCL_DKP_DST_SHIFT)
-+#define OP_PCL_DKP_DST_IMM    (0 << OP_PCL_DKP_DST_SHIFT)
-+#define OP_PCL_DKP_DST_SEQ    (1 << OP_PCL_DKP_DST_SHIFT)
-+#define OP_PCL_DKP_DST_PTR    (2 << OP_PCL_DKP_DST_SHIFT)
-+#define OP_PCL_DKP_DST_SGF    (3 << OP_PCL_DKP_DST_SHIFT)
-+#define OP_PCL_DKP_KEY_SHIFT  0
-+#define OP_PCL_DKP_KEY_MASK   (0xfff << OP_PCL_DKP_KEY_SHIFT)
-+
- /* PKI unidirectional protocol protinfo bits */
- #define OP_PCL_PKPROT_TEST                     0x0008
- #define OP_PCL_PKPROT_DECRYPT                  0x0004
-@@ -1105,6 +1144,12 @@
- #define OP_ALG_TYPE_CLASS1    (2 << OP_ALG_TYPE_SHIFT)
- #define OP_ALG_TYPE_CLASS2    (4 << OP_ALG_TYPE_SHIFT)
-+/* version register fields */
-+#define OP_VER_CCHA_NUM  0x000000ff /* Number CCHAs instantiated */
-+#define OP_VER_CCHA_MISC 0x0000ff00 /* CCHA Miscellaneous Information */
-+#define OP_VER_CCHA_REV  0x00ff0000 /* CCHA Revision Number */
-+#define OP_VER_CCHA_VID  0xff000000 /* CCHA Version ID */
-+
- #define OP_ALG_ALGSEL_SHIFT   16
- #define OP_ALG_ALGSEL_MASK    (0xff << OP_ALG_ALGSEL_SHIFT)
- #define OP_ALG_ALGSEL_SUBMASK (0x0f << OP_ALG_ALGSEL_SHIFT)
-@@ -1124,6 +1169,8 @@
- #define OP_ALG_ALGSEL_KASUMI  (0x70 << OP_ALG_ALGSEL_SHIFT)
- #define OP_ALG_ALGSEL_CRC     (0x90 << OP_ALG_ALGSEL_SHIFT)
- #define OP_ALG_ALGSEL_SNOW_F9 (0xA0 << OP_ALG_ALGSEL_SHIFT)
-+#define OP_ALG_ALGSEL_CHACHA20        (0xD0 << OP_ALG_ALGSEL_SHIFT)
-+#define OP_ALG_ALGSEL_POLY1305        (0xE0 << OP_ALG_ALGSEL_SHIFT)
- #define OP_ALG_AAI_SHIFT      4
- #define OP_ALG_AAI_MASK               (0x1ff << OP_ALG_AAI_SHIFT)
-@@ -1171,6 +1218,11 @@
- #define OP_ALG_AAI_RNG4_AI    (0x80 << OP_ALG_AAI_SHIFT)
- #define OP_ALG_AAI_RNG4_SK    (0x100 << OP_ALG_AAI_SHIFT)
-+/* Chacha20 AAI set */
-+#define OP_ALG_AAI_AEAD       (0x002 << OP_ALG_AAI_SHIFT)
-+#define OP_ALG_AAI_KEYSTREAM  (0x001 << OP_ALG_AAI_SHIFT)
-+#define OP_ALG_AAI_BC8                (0x008 << OP_ALG_AAI_SHIFT)
-+
- /* hmac/smac AAI set */
- #define OP_ALG_AAI_HASH               (0x00 << OP_ALG_AAI_SHIFT)
- #define OP_ALG_AAI_HMAC               (0x01 << OP_ALG_AAI_SHIFT)
-@@ -1359,6 +1411,7 @@
- #define MOVE_SRC_MATH3                (0x07 << MOVE_SRC_SHIFT)
- #define MOVE_SRC_INFIFO               (0x08 << MOVE_SRC_SHIFT)
- #define MOVE_SRC_INFIFO_CL    (0x09 << MOVE_SRC_SHIFT)
-+#define MOVE_SRC_AUX_ABLK     (0x0a << MOVE_SRC_SHIFT)
- #define MOVE_DEST_SHIFT               16
- #define MOVE_DEST_MASK                (0x0f << MOVE_DEST_SHIFT)
-@@ -1385,6 +1438,10 @@
- #define MOVELEN_MRSEL_SHIFT   0
- #define MOVELEN_MRSEL_MASK    (0x3 << MOVE_LEN_SHIFT)
-+#define MOVELEN_MRSEL_MATH0   (0 << MOVELEN_MRSEL_SHIFT)
-+#define MOVELEN_MRSEL_MATH1   (1 << MOVELEN_MRSEL_SHIFT)
-+#define MOVELEN_MRSEL_MATH2   (2 << MOVELEN_MRSEL_SHIFT)
-+#define MOVELEN_MRSEL_MATH3   (3 << MOVELEN_MRSEL_SHIFT)
- /*
-  * MATH Command Constructs
-@@ -1440,10 +1497,11 @@
- #define MATH_SRC1_REG2                (0x02 << MATH_SRC1_SHIFT)
- #define MATH_SRC1_REG3                (0x03 << MATH_SRC1_SHIFT)
- #define MATH_SRC1_IMM         (0x04 << MATH_SRC1_SHIFT)
--#define MATH_SRC1_DPOVRD      (0x07 << MATH_SRC0_SHIFT)
-+#define MATH_SRC1_DPOVRD      (0x07 << MATH_SRC1_SHIFT)
- #define MATH_SRC1_INFIFO      (0x0a << MATH_SRC1_SHIFT)
- #define MATH_SRC1_OUTFIFO     (0x0b << MATH_SRC1_SHIFT)
- #define MATH_SRC1_ONE         (0x0c << MATH_SRC1_SHIFT)
-+#define MATH_SRC1_ZERO                (0x0f << MATH_SRC1_SHIFT)
- /* Destination selectors */
- #define MATH_DEST_SHIFT               8
-@@ -1452,6 +1510,7 @@
- #define MATH_DEST_REG1                (0x01 << MATH_DEST_SHIFT)
- #define MATH_DEST_REG2                (0x02 << MATH_DEST_SHIFT)
- #define MATH_DEST_REG3                (0x03 << MATH_DEST_SHIFT)
-+#define MATH_DEST_DPOVRD      (0x07 << MATH_DEST_SHIFT)
- #define MATH_DEST_SEQINLEN    (0x08 << MATH_DEST_SHIFT)
- #define MATH_DEST_SEQOUTLEN   (0x09 << MATH_DEST_SHIFT)
- #define MATH_DEST_VARSEQINLEN (0x0a << MATH_DEST_SHIFT)
-@@ -1560,6 +1619,7 @@
- #define NFIFOENTRY_DTYPE_IV   (0x2 << NFIFOENTRY_DTYPE_SHIFT)
- #define NFIFOENTRY_DTYPE_SAD  (0x3 << NFIFOENTRY_DTYPE_SHIFT)
- #define NFIFOENTRY_DTYPE_ICV  (0xA << NFIFOENTRY_DTYPE_SHIFT)
-+#define NFIFOENTRY_DTYPE_POLY (0xB << NFIFOENTRY_DTYPE_SHIFT)
- #define NFIFOENTRY_DTYPE_SKIP (0xE << NFIFOENTRY_DTYPE_SHIFT)
- #define NFIFOENTRY_DTYPE_MSG  (0xF << NFIFOENTRY_DTYPE_SHIFT)
-@@ -1624,4 +1684,31 @@
- /* Frame Descriptor Command for Replacement Job Descriptor */
- #define FD_CMD_REPLACE_JOB_DESC                               0x20000000
-+/* CHA Control Register bits */
-+#define CCTRL_RESET_CHA_ALL          0x1
-+#define CCTRL_RESET_CHA_AESA         0x2
-+#define CCTRL_RESET_CHA_DESA         0x4
-+#define CCTRL_RESET_CHA_AFHA         0x8
-+#define CCTRL_RESET_CHA_KFHA         0x10
-+#define CCTRL_RESET_CHA_SF8A         0x20
-+#define CCTRL_RESET_CHA_PKHA         0x40
-+#define CCTRL_RESET_CHA_MDHA         0x80
-+#define CCTRL_RESET_CHA_CRCA         0x100
-+#define CCTRL_RESET_CHA_RNG          0x200
-+#define CCTRL_RESET_CHA_SF9A         0x400
-+#define CCTRL_RESET_CHA_ZUCE         0x800
-+#define CCTRL_RESET_CHA_ZUCA         0x1000
-+#define CCTRL_UNLOAD_PK_A0           0x10000
-+#define CCTRL_UNLOAD_PK_A1           0x20000
-+#define CCTRL_UNLOAD_PK_A2           0x40000
-+#define CCTRL_UNLOAD_PK_A3           0x80000
-+#define CCTRL_UNLOAD_PK_B0           0x100000
-+#define CCTRL_UNLOAD_PK_B1           0x200000
-+#define CCTRL_UNLOAD_PK_B2           0x400000
-+#define CCTRL_UNLOAD_PK_B3           0x800000
-+#define CCTRL_UNLOAD_PK_N            0x1000000
-+#define CCTRL_UNLOAD_PK_A            0x4000000
-+#define CCTRL_UNLOAD_PK_B            0x8000000
-+#define CCTRL_UNLOAD_SBOX            0x10000000
-+
- #endif /* DESC_H */
---- a/drivers/crypto/caam/desc_constr.h
-+++ b/drivers/crypto/caam/desc_constr.h
-@@ -109,7 +109,7 @@ static inline void init_job_desc_shared(
-       append_ptr(desc, ptr);
- }
--static inline void append_data(u32 * const desc, void *data, int len)
-+static inline void append_data(u32 * const desc, const void *data, int len)
- {
-       u32 *offset = desc_end(desc);
-@@ -172,7 +172,7 @@ static inline void append_cmd_ptr_extlen
-       append_cmd(desc, len);
- }
--static inline void append_cmd_data(u32 * const desc, void *data, int len,
-+static inline void append_cmd_data(u32 * const desc, const void *data, int len,
-                                  u32 command)
- {
-       append_cmd(desc, command | IMMEDIATE | len);
-@@ -189,6 +189,8 @@ static inline u32 *append_##cmd(u32 * co
- }
- APPEND_CMD_RET(jump, JUMP)
- APPEND_CMD_RET(move, MOVE)
-+APPEND_CMD_RET(moveb, MOVEB)
-+APPEND_CMD_RET(move_len, MOVE_LEN)
- static inline void set_jump_tgt_here(u32 * const desc, u32 *jump_cmd)
- {
-@@ -271,7 +273,7 @@ APPEND_SEQ_PTR_INTLEN(in, IN)
- APPEND_SEQ_PTR_INTLEN(out, OUT)
- #define APPEND_CMD_PTR_TO_IMM(cmd, op) \
--static inline void append_##cmd##_as_imm(u32 * const desc, void *data, \
-+static inline void append_##cmd##_as_imm(u32 * const desc, const void *data, \
-                                        unsigned int len, u32 options) \
- { \
-       PRINT_POS; \
-@@ -312,7 +314,7 @@ APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_
-  * from length of immediate data provided, e.g., split keys
-  */
- #define APPEND_CMD_PTR_TO_IMM2(cmd, op) \
--static inline void append_##cmd##_as_imm(u32 * const desc, void *data, \
-+static inline void append_##cmd##_as_imm(u32 * const desc, const void *data, \
-                                        unsigned int data_len, \
-                                        unsigned int len, u32 options) \
- { \
-@@ -327,7 +329,11 @@ static inline void append_##cmd##_imm_##
-                                            u32 options) \
- { \
-       PRINT_POS; \
--      append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \
-+      if (options & LDST_LEN_MASK) \
-+              append_cmd(desc, CMD_##op | IMMEDIATE | options); \
-+      else \
-+              append_cmd(desc, CMD_##op | IMMEDIATE | options | \
-+                         sizeof(type)); \
-       append_cmd(desc, immediate); \
- }
- APPEND_CMD_RAW_IMM(load, LOAD, u32);
-@@ -452,7 +458,7 @@ struct alginfo {
-       unsigned int keylen_pad;
-       union {
-               dma_addr_t key_dma;
--              void *key_virt;
-+              const void *key_virt;
-       };
-       bool key_inline;
- };
-@@ -496,4 +502,45 @@ static inline int desc_inline_query(unsi
-       return (rem_bytes >= 0) ? 0 : -1;
- }
-+/**
-+ * append_proto_dkp - Derived Key Protocol (DKP): key -> split key
-+ * @desc: pointer to buffer used for descriptor construction
-+ * @adata: pointer to authentication transform definitions.
-+ *         keylen should be the length of initial key, while keylen_pad
-+ *         the length of the derived (split) key.
-+ *         Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
-+ *         SHA256, SHA384, SHA512}.
-+ */
-+static inline void append_proto_dkp(u32 * const desc, struct alginfo *adata)
-+{
-+      u32 protid;
-+
-+      /*
-+       * Quick & dirty translation from OP_ALG_ALGSEL_{MD5, SHA*}
-+       * to OP_PCLID_DKP_{MD5, SHA*}
-+       */
-+      protid = (adata->algtype & OP_ALG_ALGSEL_SUBMASK) |
-+               (0x20 << OP_ALG_ALGSEL_SHIFT);
-+
-+      if (adata->key_inline) {
-+              int words;
-+
-+              append_operation(desc, OP_TYPE_UNI_PROTOCOL | protid |
-+                               OP_PCL_DKP_SRC_IMM | OP_PCL_DKP_DST_IMM |
-+                               adata->keylen);
-+              append_data(desc, adata->key_virt, adata->keylen);
-+
-+              /* Reserve space in descriptor buffer for the derived key */
-+              words = (ALIGN(adata->keylen_pad, CAAM_CMD_SZ) -
-+                       ALIGN(adata->keylen, CAAM_CMD_SZ)) / CAAM_CMD_SZ;
-+              if (words)
-+                      (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + words);
-+      } else {
-+              append_operation(desc, OP_TYPE_UNI_PROTOCOL | protid |
-+                               OP_PCL_DKP_SRC_PTR | OP_PCL_DKP_DST_PTR |
-+                               adata->keylen);
-+              append_ptr(desc, adata->key_dma);
-+      }
-+}
-+
- #endif /* DESC_CONSTR_H */
---- /dev/null
-+++ b/drivers/crypto/caam/dpseci.c
-@@ -0,0 +1,865 @@
-+/*
-+ * Copyright 2013-2016 Freescale Semiconductor Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *     * Redistributions of source code must retain the above copyright
-+ *     notice, this list of conditions and the following disclaimer.
-+ *     * Redistributions in binary form must reproduce the above copyright
-+ *     notice, this list of conditions and the following disclaimer in the
-+ *     documentation and/or other materials provided with the distribution.
-+ *     * Neither the names of the above-listed copyright holders nor the
-+ *     names of any contributors may be used to endorse or promote products
-+ *     derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include <linux/fsl/mc.h>
-+#include "../../../drivers/staging/fsl-mc/include/dpopr.h"
-+#include "dpseci.h"
-+#include "dpseci_cmd.h"
-+
-+/**
-+ * dpseci_open() - Open a control session for the specified object
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @dpseci_id:        DPSECI unique ID
-+ * @token:    Returned token; use in subsequent API calls
-+ *
-+ * This function can be used to open a control session for an already created
-+ * object; an object may have been declared in the DPL or by calling the
-+ * dpseci_create() function.
-+ * This function returns a unique authentication token, associated with the
-+ * specific object ID and the specific MC portal; this token must be used in all
-+ * subsequent commands for this specific object.
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int dpseci_id,
-+              u16 *token)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_open *cmd_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_OPEN,
-+                                        cmd_flags,
-+                                        0);
-+      cmd_params = (struct dpseci_cmd_open *)cmd.params;
-+      cmd_params->dpseci_id = cpu_to_le32(dpseci_id);
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      *token = mc_cmd_hdr_read_token(&cmd);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_close() - Close the control session of the object
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ *
-+ * After this function is called, no further operations are allowed on the
-+ * object without opening a new control session.
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CLOSE,
-+                                        cmd_flags,
-+                                        token);
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_create() - Create the DPSECI object
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @dprc_token:       Parent container token; '0' for default container
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @cfg:      Configuration structure
-+ * @obj_id:   returned object id
-+ *
-+ * Create the DPSECI object, allocate required resources and perform required
-+ * initialization.
-+ *
-+ * The object can be created either by declaring it in the DPL file, or by
-+ * calling this function.
-+ *
-+ * The function accepts an authentication token of a parent container that this
-+ * object should be assigned to. The token can be '0' so the object will be
-+ * assigned to the default container.
-+ * The newly created object can be opened with the returned object id and using
-+ * the container's associated tokens and MC portals.
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_create(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags,
-+                const struct dpseci_cfg *cfg, u32 *obj_id)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_create *cmd_params;
-+      int i, err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CREATE,
-+                                        cmd_flags,
-+                                        dprc_token);
-+      cmd_params = (struct dpseci_cmd_create *)cmd.params;
-+      for (i = 0; i < 8; i++)
-+              cmd_params->priorities[i] = cfg->priorities[i];
-+      for (i = 0; i < 8; i++)
-+              cmd_params->priorities2[i] = cfg->priorities[8 + i];
-+      cmd_params->num_tx_queues = cfg->num_tx_queues;
-+      cmd_params->num_rx_queues = cfg->num_rx_queues;
-+      cmd_params->options = cpu_to_le32(cfg->options);
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      *obj_id = mc_cmd_read_object_id(&cmd);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_destroy() - Destroy the DPSECI object and release all its resources
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @dprc_token: Parent container token; '0' for default container
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @object_id:        The object id; it must be a valid id within the container that
-+ *            created this object
-+ *
-+ * The function accepts the authentication token of the parent container that
-+ * created the object (not the one that currently owns the object). The object
-+ * is searched within parent using the provided 'object_id'.
-+ * All tokens to the object must be closed before calling destroy.
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_destroy(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags,
-+                 u32 object_id)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_destroy *cmd_params;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_DESTROY,
-+                                        cmd_flags,
-+                                        dprc_token);
-+      cmd_params = (struct dpseci_cmd_destroy *)cmd.params;
-+      cmd_params->object_id = cpu_to_le32(object_id);
-+
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_enable() - Enable the DPSECI, allow sending and receiving frames
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_ENABLE,
-+                                        cmd_flags,
-+                                        token);
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_disable() - Disable the DPSECI, stop sending and receiving frames
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_DISABLE,
-+                                        cmd_flags,
-+                                        token);
-+
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_is_enabled() - Check if the DPSECI is enabled.
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @en:               Returns '1' if object is enabled; '0' otherwise
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_is_enabled(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                    int *en)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_rsp_is_enabled *rsp_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_IS_ENABLED,
-+                                        cmd_flags,
-+                                        token);
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      rsp_params = (struct dpseci_rsp_is_enabled *)cmd.params;
-+      *en = dpseci_get_field(rsp_params->is_enabled, ENABLE);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_reset() - Reset the DPSECI, returns the object to initial state.
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_RESET,
-+                                        cmd_flags,
-+                                        token);
-+
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_get_irq_enable() - Get overall interrupt state
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @irq_index:        The interrupt index to configure
-+ * @en:               Returned Interrupt state - enable = 1, disable = 0
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                        u8 irq_index, u8 *en)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_irq_enable *cmd_params;
-+      struct dpseci_rsp_get_irq_enable *rsp_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_ENABLE,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_irq_enable *)cmd.params;
-+      cmd_params->irq_index = irq_index;
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      rsp_params = (struct dpseci_rsp_get_irq_enable *)cmd.params;
-+      *en = rsp_params->enable_state;
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_set_irq_enable() - Set overall interrupt state.
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @irq_index:        The interrupt index to configure
-+ * @en:               Interrupt state - enable = 1, disable = 0
-+ *
-+ * Allows GPP software to control when interrupts are generated.
-+ * Each interrupt can have up to 32 causes. The enable/disable control's the
-+ * overall interrupt state. If the interrupt is disabled no causes will cause
-+ * an interrupt.
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                        u8 irq_index, u8 en)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_irq_enable *cmd_params;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_ENABLE,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_irq_enable *)cmd.params;
-+      cmd_params->irq_index = irq_index;
-+      cmd_params->enable_state = en;
-+
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_get_irq_mask() - Get interrupt mask.
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @irq_index:        The interrupt index to configure
-+ * @mask:     Returned event mask to trigger interrupt
-+ *
-+ * Every interrupt can have up to 32 causes and the interrupt model supports
-+ * masking/unmasking each cause independently.
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 irq_index, u32 *mask)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_irq_mask *cmd_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_MASK,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_irq_mask *)cmd.params;
-+      cmd_params->irq_index = irq_index;
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      *mask = le32_to_cpu(cmd_params->mask);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_set_irq_mask() - Set interrupt mask.
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @irq_index:        The interrupt index to configure
-+ * @mask:     event mask to trigger interrupt;
-+ *            each bit:
-+ *                    0 = ignore event
-+ *                    1 = consider event for asserting IRQ
-+ *
-+ * Every interrupt can have up to 32 causes and the interrupt model supports
-+ * masking/unmasking each cause independently
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 irq_index, u32 mask)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_irq_mask *cmd_params;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_MASK,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_irq_mask *)cmd.params;
-+      cmd_params->mask = cpu_to_le32(mask);
-+      cmd_params->irq_index = irq_index;
-+
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_get_irq_status() - Get the current status of any pending interrupts
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @irq_index:        The interrupt index to configure
-+ * @status:   Returned interrupts status - one bit per cause:
-+ *                    0 = no interrupt pending
-+ *                    1 = interrupt pending
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                        u8 irq_index, u32 *status)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_irq_status *cmd_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_STATUS,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_irq_status *)cmd.params;
-+      cmd_params->status = cpu_to_le32(*status);
-+      cmd_params->irq_index = irq_index;
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      *status = le32_to_cpu(cmd_params->status);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_clear_irq_status() - Clear a pending interrupt's status
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @irq_index:        The interrupt index to configure
-+ * @status:   bits to clear (W1C) - one bit per cause:
-+ *                    0 = don't change
-+ *                    1 = clear status bit
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                          u8 irq_index, u32 status)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_irq_status *cmd_params;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CLEAR_IRQ_STATUS,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_irq_status *)cmd.params;
-+      cmd_params->status = cpu_to_le32(status);
-+      cmd_params->irq_index = irq_index;
-+
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_get_attributes() - Retrieve DPSECI attributes
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @attr:     Returned object's attributes
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                        struct dpseci_attr *attr)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_rsp_get_attributes *rsp_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_ATTR,
-+                                        cmd_flags,
-+                                        token);
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      rsp_params = (struct dpseci_rsp_get_attributes *)cmd.params;
-+      attr->id = le32_to_cpu(rsp_params->id);
-+      attr->num_tx_queues = rsp_params->num_tx_queues;
-+      attr->num_rx_queues = rsp_params->num_rx_queues;
-+      attr->options = le32_to_cpu(rsp_params->options);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_set_rx_queue() - Set Rx queue configuration
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @queue:    Select the queue relative to number of priorities configured at
-+ *            DPSECI creation; use DPSECI_ALL_QUEUES to configure all
-+ *            Rx queues identically.
-+ * @cfg:      Rx queue configuration
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_set_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 queue, const struct dpseci_rx_queue_cfg *cfg)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_queue *cmd_params;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_RX_QUEUE,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_queue *)cmd.params;
-+      cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
-+      cmd_params->priority = cfg->dest_cfg.priority;
-+      cmd_params->queue = queue;
-+      dpseci_set_field(cmd_params->dest_type, DEST_TYPE,
-+                       cfg->dest_cfg.dest_type);
-+      cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
-+      cmd_params->options = cpu_to_le32(cfg->options);
-+      dpseci_set_field(cmd_params->order_preservation_en, ORDER_PRESERVATION,
-+                       cfg->order_preservation_en);
-+
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_get_rx_queue() - Retrieve Rx queue attributes
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @queue:    Select the queue relative to number of priorities configured at
-+ *            DPSECI creation
-+ * @attr:     Returned Rx queue attributes
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 queue, struct dpseci_rx_queue_attr *attr)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_queue *cmd_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_RX_QUEUE,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_queue *)cmd.params;
-+      cmd_params->queue = queue;
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      attr->dest_cfg.dest_id = le32_to_cpu(cmd_params->dest_id);
-+      attr->dest_cfg.priority = cmd_params->priority;
-+      attr->dest_cfg.dest_type = dpseci_get_field(cmd_params->dest_type,
-+                                                  DEST_TYPE);
-+      attr->user_ctx = le64_to_cpu(cmd_params->user_ctx);
-+      attr->fqid = le32_to_cpu(cmd_params->fqid);
-+      attr->order_preservation_en =
-+              dpseci_get_field(cmd_params->order_preservation_en,
-+                               ORDER_PRESERVATION);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_get_tx_queue() - Retrieve Tx queue attributes
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @queue:    Select the queue relative to number of priorities configured at
-+ *            DPSECI creation
-+ * @attr:     Returned Tx queue attributes
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_tx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 queue, struct dpseci_tx_queue_attr *attr)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_queue *cmd_params;
-+      struct dpseci_rsp_get_tx_queue *rsp_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_TX_QUEUE,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_queue *)cmd.params;
-+      cmd_params->queue = queue;
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      rsp_params = (struct dpseci_rsp_get_tx_queue *)cmd.params;
-+      attr->fqid = le32_to_cpu(rsp_params->fqid);
-+      attr->priority = rsp_params->priority;
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_get_sec_attr() - Retrieve SEC accelerator attributes
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @attr:     Returned SEC attributes
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_sec_attr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      struct dpseci_sec_attr *attr)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_rsp_get_sec_attr *rsp_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_SEC_ATTR,
-+                                        cmd_flags,
-+                                        token);
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      rsp_params = (struct dpseci_rsp_get_sec_attr *)cmd.params;
-+      attr->ip_id = le16_to_cpu(rsp_params->ip_id);
-+      attr->major_rev = rsp_params->major_rev;
-+      attr->minor_rev = rsp_params->minor_rev;
-+      attr->era = rsp_params->era;
-+      attr->deco_num = rsp_params->deco_num;
-+      attr->zuc_auth_acc_num = rsp_params->zuc_auth_acc_num;
-+      attr->zuc_enc_acc_num = rsp_params->zuc_enc_acc_num;
-+      attr->snow_f8_acc_num = rsp_params->snow_f8_acc_num;
-+      attr->snow_f9_acc_num = rsp_params->snow_f9_acc_num;
-+      attr->crc_acc_num = rsp_params->crc_acc_num;
-+      attr->pk_acc_num = rsp_params->pk_acc_num;
-+      attr->kasumi_acc_num = rsp_params->kasumi_acc_num;
-+      attr->rng_acc_num = rsp_params->rng_acc_num;
-+      attr->md_acc_num = rsp_params->md_acc_num;
-+      attr->arc4_acc_num = rsp_params->arc4_acc_num;
-+      attr->des_acc_num = rsp_params->des_acc_num;
-+      attr->aes_acc_num = rsp_params->aes_acc_num;
-+      attr->ccha_acc_num = rsp_params->ccha_acc_num;
-+      attr->ptha_acc_num = rsp_params->ptha_acc_num;
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_get_sec_counters() - Retrieve SEC accelerator counters
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @counters: Returned SEC counters
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                          struct dpseci_sec_counters *counters)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_rsp_get_sec_counters *rsp_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_SEC_COUNTERS,
-+                                        cmd_flags,
-+                                        token);
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      rsp_params = (struct dpseci_rsp_get_sec_counters *)cmd.params;
-+      counters->dequeued_requests =
-+              le64_to_cpu(rsp_params->dequeued_requests);
-+      counters->ob_enc_requests = le64_to_cpu(rsp_params->ob_enc_requests);
-+      counters->ib_dec_requests = le64_to_cpu(rsp_params->ib_dec_requests);
-+      counters->ob_enc_bytes = le64_to_cpu(rsp_params->ob_enc_bytes);
-+      counters->ob_prot_bytes = le64_to_cpu(rsp_params->ob_prot_bytes);
-+      counters->ib_dec_bytes = le64_to_cpu(rsp_params->ib_dec_bytes);
-+      counters->ib_valid_bytes = le64_to_cpu(rsp_params->ib_valid_bytes);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_get_api_version() - Get Data Path SEC Interface API version
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @major_ver:        Major version of data path sec API
-+ * @minor_ver:        Minor version of data path sec API
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags,
-+                         u16 *major_ver, u16 *minor_ver)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_rsp_get_api_version *rsp_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_API_VERSION,
-+                                        cmd_flags, 0);
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      rsp_params = (struct dpseci_rsp_get_api_version *)cmd.params;
-+      *major_ver = le16_to_cpu(rsp_params->major);
-+      *minor_ver = le16_to_cpu(rsp_params->minor);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_set_opr() - Set Order Restoration configuration
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @index:    The queue index
-+ * @options:  Configuration mode options; can be OPR_OPT_CREATE or
-+ *            OPR_OPT_RETIRE
-+ * @cfg:      Configuration options for the OPR
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_set_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index,
-+                 u8 options, struct opr_cfg *cfg)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_opr *cmd_params;
-+
-+      cmd.header = mc_encode_cmd_header(
-+                      DPSECI_CMDID_SET_OPR,
-+                      cmd_flags,
-+                      token);
-+      cmd_params = (struct dpseci_cmd_opr *)cmd.params;
-+      cmd_params->index = index;
-+      cmd_params->options = options;
-+      cmd_params->oloe = cfg->oloe;
-+      cmd_params->oeane = cfg->oeane;
-+      cmd_params->olws = cfg->olws;
-+      cmd_params->oa = cfg->oa;
-+      cmd_params->oprrws = cfg->oprrws;
-+
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_get_opr() - Retrieve Order Restoration config and query
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @index:    The queue index
-+ * @cfg:      Returned OPR configuration
-+ * @qry:      Returned OPR query
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index,
-+                 struct opr_cfg *cfg, struct opr_qry *qry)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_opr *cmd_params;
-+      struct dpseci_rsp_get_opr *rsp_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_OPR,
-+                                        cmd_flags,
-+                                        token);
-+      cmd_params = (struct dpseci_cmd_opr *)cmd.params;
-+      cmd_params->index = index;
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      rsp_params = (struct dpseci_rsp_get_opr *)cmd.params;
-+      qry->rip = dpseci_get_field(rsp_params->flags, OPR_RIP);
-+      qry->enable = dpseci_get_field(rsp_params->flags, OPR_ENABLE);
-+      cfg->oloe = rsp_params->oloe;
-+      cfg->oeane = rsp_params->oeane;
-+      cfg->olws = rsp_params->olws;
-+      cfg->oa = rsp_params->oa;
-+      cfg->oprrws = rsp_params->oprrws;
-+      qry->nesn = le16_to_cpu(rsp_params->nesn);
-+      qry->ndsn = le16_to_cpu(rsp_params->ndsn);
-+      qry->ea_tseq = le16_to_cpu(rsp_params->ea_tseq);
-+      qry->tseq_nlis = dpseci_get_field(rsp_params->tseq_nlis, OPR_TSEQ_NLIS);
-+      qry->ea_hseq = le16_to_cpu(rsp_params->ea_hseq);
-+      qry->hseq_nlis = dpseci_get_field(rsp_params->hseq_nlis, OPR_HSEQ_NLIS);
-+      qry->ea_hptr = le16_to_cpu(rsp_params->ea_hptr);
-+      qry->ea_tptr = le16_to_cpu(rsp_params->ea_tptr);
-+      qry->opr_vid = le16_to_cpu(rsp_params->opr_vid);
-+      qry->opr_id = le16_to_cpu(rsp_params->opr_id);
-+
-+      return 0;
-+}
-+
-+/**
-+ * dpseci_set_congestion_notification() - Set congestion group
-+ *    notification configuration
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @cfg:      congestion notification configuration
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_set_congestion_notification(struct fsl_mc_io *mc_io, u32 cmd_flags,
-+      u16 token, const struct dpseci_congestion_notification_cfg *cfg)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_congestion_notification *cmd_params;
-+
-+      cmd.header = mc_encode_cmd_header(
-+                      DPSECI_CMDID_SET_CONGESTION_NOTIFICATION,
-+                      cmd_flags,
-+                      token);
-+      cmd_params = (struct dpseci_cmd_congestion_notification *)cmd.params;
-+      cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
-+      cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode);
-+      cmd_params->priority = cfg->dest_cfg.priority;
-+      dpseci_set_field(cmd_params->options, CGN_DEST_TYPE,
-+                       cfg->dest_cfg.dest_type);
-+      dpseci_set_field(cmd_params->options, CGN_UNITS, cfg->units);
-+      cmd_params->message_iova = cpu_to_le64(cfg->message_iova);
-+      cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx);
-+      cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry);
-+      cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit);
-+
-+      return mc_send_command(mc_io, &cmd);
-+}
-+
-+/**
-+ * dpseci_get_congestion_notification() - Get congestion group notification
-+ *    configuration
-+ * @mc_io:    Pointer to MC portal's I/O object
-+ * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
-+ * @token:    Token of DPSECI object
-+ * @cfg:      congestion notification configuration
-+ *
-+ * Return:    '0' on success, error code otherwise
-+ */
-+int dpseci_get_congestion_notification(struct fsl_mc_io *mc_io, u32 cmd_flags,
-+      u16 token, struct dpseci_congestion_notification_cfg *cfg)
-+{
-+      struct fsl_mc_command cmd = { 0 };
-+      struct dpseci_cmd_congestion_notification *rsp_params;
-+      int err;
-+
-+      cmd.header = mc_encode_cmd_header(
-+                      DPSECI_CMDID_GET_CONGESTION_NOTIFICATION,
-+                      cmd_flags,
-+                      token);
-+      err = mc_send_command(mc_io, &cmd);
-+      if (err)
-+              return err;
-+
-+      rsp_params = (struct dpseci_cmd_congestion_notification *)cmd.params;
-+      cfg->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
-+      cfg->notification_mode = le16_to_cpu(rsp_params->notification_mode);
-+      cfg->dest_cfg.priority = rsp_params->priority;
-+      cfg->dest_cfg.dest_type = dpseci_get_field(rsp_params->options,
-+                                                 CGN_DEST_TYPE);
-+      cfg->units = dpseci_get_field(rsp_params->options, CGN_UNITS);
-+      cfg->message_iova = le64_to_cpu(rsp_params->message_iova);
-+      cfg->message_ctx = le64_to_cpu(rsp_params->message_ctx);
-+      cfg->threshold_entry = le32_to_cpu(rsp_params->threshold_entry);
-+      cfg->threshold_exit = le32_to_cpu(rsp_params->threshold_exit);
-+
-+      return 0;
-+}
---- /dev/null
-+++ b/drivers/crypto/caam/dpseci.h
-@@ -0,0 +1,433 @@
-+/*
-+ * Copyright 2013-2016 Freescale Semiconductor Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *     * Redistributions of source code must retain the above copyright
-+ *     notice, this list of conditions and the following disclaimer.
-+ *     * Redistributions in binary form must reproduce the above copyright
-+ *     notice, this list of conditions and the following disclaimer in the
-+ *     documentation and/or other materials provided with the distribution.
-+ *     * Neither the names of the above-listed copyright holders nor the
-+ *     names of any contributors may be used to endorse or promote products
-+ *     derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+#ifndef _DPSECI_H_
-+#define _DPSECI_H_
-+
-+/*
-+ * Data Path SEC Interface API
-+ * Contains initialization APIs and runtime control APIs for DPSECI
-+ */
-+
-+struct fsl_mc_io;
-+struct opr_cfg;
-+struct opr_qry;
-+
-+/**
-+ * General DPSECI macros
-+ */
-+
-+/**
-+ * Maximum number of Tx/Rx queues per DPSECI object
-+ */
-+#define DPSECI_MAX_QUEUE_NUM          16
-+
-+/**
-+ * All queues considered; see dpseci_set_rx_queue()
-+ */
-+#define DPSECI_ALL_QUEUES     (u8)(-1)
-+
-+int dpseci_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int dpseci_id,
-+              u16 *token);
-+
-+int dpseci_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token);
-+
-+/**
-+ * Enable the Congestion Group support
-+ */
-+#define DPSECI_OPT_HAS_CG             0x000020
-+
-+/**
-+ * Enable the Order Restoration support
-+ */
-+#define DPSECI_OPT_HAS_OPR            0x000040
-+
-+/**
-+ * Order Point Records are shared for the entire DPSECI
-+ */
-+#define DPSECI_OPT_OPR_SHARED         0x000080
-+
-+/**
-+ * struct dpseci_cfg - Structure representing DPSECI configuration
-+ * @options: Any combination of the following options:
-+ *            DPSECI_OPT_HAS_CG
-+ *            DPSECI_OPT_HAS_OPR
-+ *            DPSECI_OPT_OPR_SHARED
-+ * @num_tx_queues: num of queues towards the SEC
-+ * @num_rx_queues: num of queues back from the SEC
-+ * @priorities: Priorities for the SEC hardware processing;
-+ *            each place in the array is the priority of the tx queue
-+ *            towards the SEC;
-+ *            valid priorities are configured with values 1-8;
-+ */
-+struct dpseci_cfg {
-+      u32 options;
-+      u8 num_tx_queues;
-+      u8 num_rx_queues;
-+      u8 priorities[DPSECI_MAX_QUEUE_NUM];
-+};
-+
-+int dpseci_create(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags,
-+                const struct dpseci_cfg *cfg, u32 *obj_id);
-+
-+int dpseci_destroy(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags,
-+                 u32 object_id);
-+
-+int dpseci_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token);
-+
-+int dpseci_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token);
-+
-+int dpseci_is_enabled(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                    int *en);
-+
-+int dpseci_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token);
-+
-+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                        u8 irq_index, u8 *en);
-+
-+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                        u8 irq_index, u8 en);
-+
-+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 irq_index, u32 *mask);
-+
-+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 irq_index, u32 mask);
-+
-+int dpseci_get_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                        u8 irq_index, u32 *status);
-+
-+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                          u8 irq_index, u32 status);
-+
-+/**
-+ * struct dpseci_attr - Structure representing DPSECI attributes
-+ * @id: DPSECI object ID
-+ * @num_tx_queues: number of queues towards the SEC
-+ * @num_rx_queues: number of queues back from the SEC
-+ * @options: any combination of the following options:
-+ *            DPSECI_OPT_HAS_CG
-+ *            DPSECI_OPT_HAS_OPR
-+ *            DPSECI_OPT_OPR_SHARED
-+ */
-+struct dpseci_attr {
-+      int id;
-+      u8 num_tx_queues;
-+      u8 num_rx_queues;
-+      u32 options;
-+};
-+
-+int dpseci_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                        struct dpseci_attr *attr);
-+
-+/**
-+ * enum dpseci_dest - DPSECI destination types
-+ * @DPSECI_DEST_NONE: Unassigned destination; The queue is set in parked mode
-+ *    and does not generate FQDAN notifications; user is expected to dequeue
-+ *    from the queue based on polling or other user-defined method
-+ * @DPSECI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
-+ *    notifications to the specified DPIO; user is expected to dequeue from
-+ *    the queue only after notification is received
-+ * @DPSECI_DEST_DPCON: The queue is set in schedule mode and does not generate
-+ *    FQDAN notifications, but is connected to the specified DPCON object;
-+ *    user is expected to dequeue from the DPCON channel
-+ */
-+enum dpseci_dest {
-+      DPSECI_DEST_NONE = 0,
-+      DPSECI_DEST_DPIO,
-+      DPSECI_DEST_DPCON
-+};
-+
-+/**
-+ * struct dpseci_dest_cfg - Structure representing DPSECI destination parameters
-+ * @dest_type: Destination type
-+ * @dest_id: Either DPIO ID or DPCON ID, depending on the destination type
-+ * @priority: Priority selection within the DPIO or DPCON channel; valid values
-+ *    are 0-1 or 0-7, depending on the number of priorities in that channel;
-+ *    not relevant for 'DPSECI_DEST_NONE' option
-+ */
-+struct dpseci_dest_cfg {
-+      enum dpseci_dest dest_type;
-+      int dest_id;
-+      u8 priority;
-+};
-+
-+/**
-+ * DPSECI queue modification options
-+ */
-+
-+/**
-+ * Select to modify the user's context associated with the queue
-+ */
-+#define DPSECI_QUEUE_OPT_USER_CTX             0x00000001
-+
-+/**
-+ * Select to modify the queue's destination
-+ */
-+#define DPSECI_QUEUE_OPT_DEST                 0x00000002
-+
-+/**
-+ * Select to modify the queue's order preservation
-+ */
-+#define DPSECI_QUEUE_OPT_ORDER_PRESERVATION   0x00000004
-+
-+/**
-+ * struct dpseci_rx_queue_cfg - DPSECI RX queue configuration
-+ * @options: Flags representing the suggested modifications to the queue;
-+ *    Use any combination of 'DPSECI_QUEUE_OPT_<X>' flags
-+ * @order_preservation_en: order preservation configuration for the rx queue
-+ * valid only if 'DPSECI_QUEUE_OPT_ORDER_PRESERVATION' is contained in 'options'
-+ * @user_ctx: User context value provided in the frame descriptor of each
-+ *    dequeued frame; valid only if 'DPSECI_QUEUE_OPT_USER_CTX' is contained
-+ *    in 'options'
-+ * @dest_cfg: Queue destination parameters; valid only if
-+ *    'DPSECI_QUEUE_OPT_DEST' is contained in 'options'
-+ */
-+struct dpseci_rx_queue_cfg {
-+      u32 options;
-+      int order_preservation_en;
-+      u64 user_ctx;
-+      struct dpseci_dest_cfg dest_cfg;
-+};
-+
-+int dpseci_set_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 queue, const struct dpseci_rx_queue_cfg *cfg);
-+
-+/**
-+ * struct dpseci_rx_queue_attr - Structure representing attributes of Rx queues
-+ * @user_ctx: User context value provided in the frame descriptor of each
-+ *    dequeued frame
-+ * @order_preservation_en: Status of the order preservation configuration on the
-+ *    queue
-+ * @dest_cfg: Queue destination configuration
-+ * @fqid: Virtual FQID value to be used for dequeue operations
-+ */
-+struct dpseci_rx_queue_attr {
-+      u64 user_ctx;
-+      int order_preservation_en;
-+      struct dpseci_dest_cfg dest_cfg;
-+      u32 fqid;
-+};
-+
-+int dpseci_get_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 queue, struct dpseci_rx_queue_attr *attr);
-+
-+/**
-+ * struct dpseci_tx_queue_attr - Structure representing attributes of Tx queues
-+ * @fqid: Virtual FQID to be used for sending frames to SEC hardware
-+ * @priority: SEC hardware processing priority for the queue
-+ */
-+struct dpseci_tx_queue_attr {
-+      u32 fqid;
-+      u8 priority;
-+};
-+
-+int dpseci_get_tx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      u8 queue, struct dpseci_tx_queue_attr *attr);
-+
-+/**
-+ * struct dpseci_sec_attr - Structure representing attributes of the SEC
-+ *    hardware accelerator
-+ * @ip_id: ID for SEC
-+ * @major_rev: Major revision number for SEC
-+ * @minor_rev: Minor revision number for SEC
-+ * @era: SEC Era
-+ * @deco_num: The number of copies of the DECO that are implemented in this
-+ *    version of SEC
-+ * @zuc_auth_acc_num: The number of copies of ZUCA that are implemented in this
-+ *    version of SEC
-+ * @zuc_enc_acc_num: The number of copies of ZUCE that are implemented in this
-+ *    version of SEC
-+ * @snow_f8_acc_num: The number of copies of the SNOW-f8 module that are
-+ *    implemented in this version of SEC
-+ * @snow_f9_acc_num: The number of copies of the SNOW-f9 module that are
-+ *    implemented in this version of SEC
-+ * @crc_acc_num: The number of copies of the CRC module that are implemented in
-+ *    this version of SEC
-+ * @pk_acc_num:  The number of copies of the Public Key module that are
-+ *    implemented in this version of SEC
-+ * @kasumi_acc_num: The number of copies of the Kasumi module that are
-+ *    implemented in this version of SEC
-+ * @rng_acc_num: The number of copies of the Random Number Generator that are
-+ *    implemented in this version of SEC
-+ * @md_acc_num: The number of copies of the MDHA (Hashing module) that are
-+ *    implemented in this version of SEC
-+ * @arc4_acc_num: The number of copies of the ARC4 module that are implemented
-+ *    in this version of SEC
-+ * @des_acc_num: The number of copies of the DES module that are implemented in
-+ *    this version of SEC
-+ * @aes_acc_num: The number of copies of the AES module that are implemented in
-+ *    this version of SEC
-+ * @ccha_acc_num: The number of copies of the ChaCha20 module that are
-+ *    implemented in this version of SEC.
-+ * @ptha_acc_num: The number of copies of the Poly1305 module that are
-+ *    implemented in this version of SEC.
-+ **/
-+struct dpseci_sec_attr {
-+      u16 ip_id;
-+      u8 major_rev;
-+      u8 minor_rev;
-+      u8 era;
-+      u8 deco_num;
-+      u8 zuc_auth_acc_num;
-+      u8 zuc_enc_acc_num;
-+      u8 snow_f8_acc_num;
-+      u8 snow_f9_acc_num;
-+      u8 crc_acc_num;
-+      u8 pk_acc_num;
-+      u8 kasumi_acc_num;
-+      u8 rng_acc_num;
-+      u8 md_acc_num;
-+      u8 arc4_acc_num;
-+      u8 des_acc_num;
-+      u8 aes_acc_num;
-+      u8 ccha_acc_num;
-+      u8 ptha_acc_num;
-+};
-+
-+int dpseci_get_sec_attr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                      struct dpseci_sec_attr *attr);
-+
-+/**
-+ * struct dpseci_sec_counters - Structure representing global SEC counters and
-+ *                            not per dpseci counters
-+ * @dequeued_requests:        Number of Requests Dequeued
-+ * @ob_enc_requests:  Number of Outbound Encrypt Requests
-+ * @ib_dec_requests:  Number of Inbound Decrypt Requests
-+ * @ob_enc_bytes:     Number of Outbound Bytes Encrypted
-+ * @ob_prot_bytes:    Number of Outbound Bytes Protected
-+ * @ib_dec_bytes:     Number of Inbound Bytes Decrypted
-+ * @ib_valid_bytes:   Number of Inbound Bytes Validated
-+ */
-+struct dpseci_sec_counters {
-+      u64 dequeued_requests;
-+      u64 ob_enc_requests;
-+      u64 ib_dec_requests;
-+      u64 ob_enc_bytes;
-+      u64 ob_prot_bytes;
-+      u64 ib_dec_bytes;
-+      u64 ib_valid_bytes;
-+};
-+
-+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
-+                          struct dpseci_sec_counters *counters);
-+
-+int dpseci_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags,
-+                         u16 *major_ver, u16 *minor_ver);
-+
-+int dpseci_set_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index,
-+                 u8 options, struct opr_cfg *cfg);
-+
-+int dpseci_get_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index,
-+                 struct opr_cfg *cfg, struct opr_qry *qry);
-+
-+/**
-+ * enum dpseci_congestion_unit - DPSECI congestion units
-+ * @DPSECI_CONGESTION_UNIT_BYTES: bytes units
-+ * @DPSECI_CONGESTION_UNIT_FRAMES: frames units
-+ */
-+enum dpseci_congestion_unit {
-+      DPSECI_CONGESTION_UNIT_BYTES = 0,
-+      DPSECI_CONGESTION_UNIT_FRAMES
-+};
-+
-+/**
-+ * CSCN message is written to message_iova once entering a
-+ * congestion state (see 'threshold_entry')
-+ */
-+#define DPSECI_CGN_MODE_WRITE_MEM_ON_ENTER            0x00000001
-+
-+/**
-+ * CSCN message is written to message_iova once exiting a
-+ * congestion state (see 'threshold_exit')
-+ */
-+#define DPSECI_CGN_MODE_WRITE_MEM_ON_EXIT             0x00000002
-+
-+/**
-+ * CSCN write will attempt to allocate into a cache (coherent write);
-+ * valid only if 'DPSECI_CGN_MODE_WRITE_MEM_<X>' is selected
-+ */
-+#define DPSECI_CGN_MODE_COHERENT_WRITE                        0x00000004
-+
-+/**
-+ * if 'dpseci_dest_cfg.dest_type != DPSECI_DEST_NONE' CSCN message is sent to
-+ * DPIO/DPCON's WQ channel once entering a congestion state
-+ * (see 'threshold_entry')
-+ */
-+#define DPSECI_CGN_MODE_NOTIFY_DEST_ON_ENTER          0x00000008
-+
-+/**
-+ * if 'dpseci_dest_cfg.dest_type != DPSECI_DEST_NONE' CSCN message is sent to
-+ * DPIO/DPCON's WQ channel once exiting a congestion state
-+ * (see 'threshold_exit')
-+ */
-+#define DPSECI_CGN_MODE_NOTIFY_DEST_ON_EXIT           0x00000010
-+
-+/**
-+ * if 'dpseci_dest_cfg.dest_type != DPSECI_DEST_NONE' when the CSCN is written
-+ * to the sw-portal's DQRR, the DQRI interrupt is asserted immediately
-+ * (if enabled)
-+ */
-+#define DPSECI_CGN_MODE_INTR_COALESCING_DISABLED      0x00000020
-+
-+/**
-+ * struct dpseci_congestion_notification_cfg - congestion notification
-+ *    configuration
-+ * @units: units type
-+ * @threshold_entry: above this threshold we enter a congestion state.
-+ *    set it to '0' to disable it
-+ * @threshold_exit: below this threshold we exit the congestion state.
-+ * @message_ctx: The context that will be part of the CSCN message
-+ * @message_iova: I/O virtual address (must be in DMA-able memory),
-+ *    must be 16B aligned;
-+ * @dest_cfg: CSCN can be send to either DPIO or DPCON WQ channel
-+ * @notification_mode: Mask of available options; use 'DPSECI_CGN_MODE_<X>'
-+ *    values
-+ */
-+struct dpseci_congestion_notification_cfg {
-+      enum dpseci_congestion_unit units;
-+      u32 threshold_entry;
-+      u32 threshold_exit;
-+      u64 message_ctx;
-+      u64 message_iova;
-+      struct dpseci_dest_cfg dest_cfg;
-+      u16 notification_mode;
-+};
-+
-+int dpseci_set_congestion_notification(struct fsl_mc_io *mc_io, u32 cmd_flags,
-+      u16 token, const struct dpseci_congestion_notification_cfg *cfg);
-+
-+int dpseci_get_congestion_notification(struct fsl_mc_io *mc_io, u32 cmd_flags,
-+      u16 token, struct dpseci_congestion_notification_cfg *cfg);
-+
-+#endif /* _DPSECI_H_ */
---- /dev/null
-+++ b/drivers/crypto/caam/dpseci_cmd.h
-@@ -0,0 +1,287 @@
-+/*
-+ * Copyright 2013-2016 Freescale Semiconductor Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *     * Redistributions of source code must retain the above copyright
-+ *     notice, this list of conditions and the following disclaimer.
-+ *     * Redistributions in binary form must reproduce the above copyright
-+ *     notice, this list of conditions and the following disclaimer in the
-+ *     documentation and/or other materials provided with the distribution.
-+ *     * Neither the names of the above-listed copyright holders nor the
-+ *     names of any contributors may be used to endorse or promote products
-+ *     derived from this software without specific prior written permission.
-+ *
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#ifndef _DPSECI_CMD_H_
-+#define _DPSECI_CMD_H_
-+
-+/* DPSECI Version */
-+#define DPSECI_VER_MAJOR                              5
-+#define DPSECI_VER_MINOR                              3
-+
-+#define DPSECI_VER(maj, min)  (((maj) << 16) | (min))
-+#define DPSECI_VERSION                DPSECI_VER(DPSECI_VER_MAJOR, DPSECI_VER_MINOR)
-+
-+/* Command versioning */
-+#define DPSECI_CMD_BASE_VERSION               1
-+#define DPSECI_CMD_BASE_VERSION_V2    2
-+#define DPSECI_CMD_BASE_VERSION_V3    3
-+#define DPSECI_CMD_ID_OFFSET          4
-+
-+#define DPSECI_CMD_V1(id)     (((id) << DPSECI_CMD_ID_OFFSET) | \
-+                               DPSECI_CMD_BASE_VERSION)
-+
-+#define DPSECI_CMD_V2(id)     (((id) << DPSECI_CMD_ID_OFFSET) | \
-+                               DPSECI_CMD_BASE_VERSION_V2)
-+
-+#define DPSECI_CMD_V3(id)     (((id) << DPSECI_CMD_ID_OFFSET) | \
-+                               DPSECI_CMD_BASE_VERSION_V3)
-+
-+/* Command IDs */
-+#define DPSECI_CMDID_CLOSE                            DPSECI_CMD_V1(0x800)
-+#define DPSECI_CMDID_OPEN                             DPSECI_CMD_V1(0x809)
-+#define DPSECI_CMDID_CREATE                           DPSECI_CMD_V3(0x909)
-+#define DPSECI_CMDID_DESTROY                          DPSECI_CMD_V1(0x989)
-+#define DPSECI_CMDID_GET_API_VERSION                  DPSECI_CMD_V1(0xa09)
-+
-+#define DPSECI_CMDID_ENABLE                           DPSECI_CMD_V1(0x002)
-+#define DPSECI_CMDID_DISABLE                          DPSECI_CMD_V1(0x003)
-+#define DPSECI_CMDID_GET_ATTR                         DPSECI_CMD_V1(0x004)
-+#define DPSECI_CMDID_RESET                            DPSECI_CMD_V1(0x005)
-+#define DPSECI_CMDID_IS_ENABLED                               DPSECI_CMD_V1(0x006)
-+
-+#define DPSECI_CMDID_SET_IRQ_ENABLE                   DPSECI_CMD_V1(0x012)
-+#define DPSECI_CMDID_GET_IRQ_ENABLE                   DPSECI_CMD_V1(0x013)
-+#define DPSECI_CMDID_SET_IRQ_MASK                     DPSECI_CMD_V1(0x014)
-+#define DPSECI_CMDID_GET_IRQ_MASK                     DPSECI_CMD_V1(0x015)
-+#define DPSECI_CMDID_GET_IRQ_STATUS                   DPSECI_CMD_V1(0x016)
-+#define DPSECI_CMDID_CLEAR_IRQ_STATUS                 DPSECI_CMD_V1(0x017)
-+
-+#define DPSECI_CMDID_SET_RX_QUEUE                     DPSECI_CMD_V1(0x194)
-+#define DPSECI_CMDID_GET_RX_QUEUE                     DPSECI_CMD_V1(0x196)
-+#define DPSECI_CMDID_GET_TX_QUEUE                     DPSECI_CMD_V1(0x197)
-+#define DPSECI_CMDID_GET_SEC_ATTR                     DPSECI_CMD_V2(0x198)
-+#define DPSECI_CMDID_GET_SEC_COUNTERS                 DPSECI_CMD_V1(0x199)
-+#define DPSECI_CMDID_SET_OPR                          DPSECI_CMD_V1(0x19A)
-+#define DPSECI_CMDID_GET_OPR                          DPSECI_CMD_V1(0x19B)
-+#define DPSECI_CMDID_SET_CONGESTION_NOTIFICATION      DPSECI_CMD_V1(0x170)
-+#define DPSECI_CMDID_GET_CONGESTION_NOTIFICATION      DPSECI_CMD_V1(0x171)
-+
-+/* Macros for accessing command fields smaller than 1 byte */
-+#define DPSECI_MASK(field)    \
-+      GENMASK(DPSECI_##field##_SHIFT + DPSECI_##field##_SIZE - 1,     \
-+              DPSECI_##field##_SHIFT)
-+
-+#define dpseci_set_field(var, field, val)     \
-+      ((var) |= (((val) << DPSECI_##field##_SHIFT) & DPSECI_MASK(field)))
-+
-+#define dpseci_get_field(var, field)  \
-+      (((var) & DPSECI_MASK(field)) >> DPSECI_##field##_SHIFT)
-+
-+struct dpseci_cmd_open {
-+      __le32 dpseci_id;
-+};
-+
-+struct dpseci_cmd_create {
-+      u8 priorities[8];
-+      u8 num_tx_queues;
-+      u8 num_rx_queues;
-+      u8 pad0[6];
-+      __le32 options;
-+      __le32 pad1;
-+      u8 priorities2[8];
-+};
-+
-+struct dpseci_cmd_destroy {
-+      __le32 object_id;
-+};
-+
-+#define DPSECI_ENABLE_SHIFT   0
-+#define DPSECI_ENABLE_SIZE    1
-+
-+struct dpseci_rsp_is_enabled {
-+      u8 is_enabled;
-+};
-+
-+struct dpseci_cmd_irq_enable {
-+      u8 enable_state;
-+      u8 pad[3];
-+      u8 irq_index;
-+};
-+
-+struct dpseci_rsp_get_irq_enable {
-+      u8 enable_state;
-+};
-+
-+struct dpseci_cmd_irq_mask {
-+      __le32 mask;
-+      u8 irq_index;
-+};
-+
-+struct dpseci_cmd_irq_status {
-+      __le32 status;
-+      u8 irq_index;
-+};
-+
-+struct dpseci_rsp_get_attributes {
-+      __le32 id;
-+      __le32 pad0;
-+      u8 num_tx_queues;
-+      u8 num_rx_queues;
-+      u8 pad1[6];
-+      __le32 options;
-+};
-+
-+#define DPSECI_DEST_TYPE_SHIFT        0
-+#define DPSECI_DEST_TYPE_SIZE 4
-+
-+#define DPSECI_ORDER_PRESERVATION_SHIFT       0
-+#define DPSECI_ORDER_PRESERVATION_SIZE        1
-+
-+struct dpseci_cmd_queue {
-+      __le32 dest_id;
-+      u8 priority;
-+      u8 queue;
-+      u8 dest_type;
-+      u8 pad;
-+      __le64 user_ctx;
-+      union {
-+              __le32 options;
-+              __le32 fqid;
-+      };
-+      u8 order_preservation_en;
-+};
-+
-+struct dpseci_rsp_get_tx_queue {
-+      __le32 pad;
-+      __le32 fqid;
-+      u8 priority;
-+};
-+
-+struct dpseci_rsp_get_sec_attr {
-+      __le16 ip_id;
-+      u8 major_rev;
-+      u8 minor_rev;
-+      u8 era;
-+      u8 pad0[3];
-+      u8 deco_num;
-+      u8 zuc_auth_acc_num;
-+      u8 zuc_enc_acc_num;
-+      u8 pad1;
-+      u8 snow_f8_acc_num;
-+      u8 snow_f9_acc_num;
-+      u8 crc_acc_num;
-+      u8 pad2;
-+      u8 pk_acc_num;
-+      u8 kasumi_acc_num;
-+      u8 rng_acc_num;
-+      u8 pad3;
-+      u8 md_acc_num;
-+      u8 arc4_acc_num;
-+      u8 des_acc_num;
-+      u8 aes_acc_num;
-+      u8 ccha_acc_num;
-+      u8 ptha_acc_num;
-+};
-+
-+struct dpseci_rsp_get_sec_counters {
-+      __le64 dequeued_requests;
-+      __le64 ob_enc_requests;
-+      __le64 ib_dec_requests;
-+      __le64 ob_enc_bytes;
-+      __le64 ob_prot_bytes;
-+      __le64 ib_dec_bytes;
-+      __le64 ib_valid_bytes;
-+};
-+
-+struct dpseci_rsp_get_api_version {
-+      __le16 major;
-+      __le16 minor;
-+};
-+
-+struct dpseci_cmd_opr {
-+      __le16 pad;
-+      u8 index;
-+      u8 options;
-+      u8 pad1[7];
-+      u8 oloe;
-+      u8 oeane;
-+      u8 olws;
-+      u8 oa;
-+      u8 oprrws;
-+};
-+
-+#define DPSECI_OPR_RIP_SHIFT          0
-+#define DPSECI_OPR_RIP_SIZE           1
-+#define DPSECI_OPR_ENABLE_SHIFT               1
-+#define DPSECI_OPR_ENABLE_SIZE                1
-+#define DPSECI_OPR_TSEQ_NLIS_SHIFT    0
-+#define DPSECI_OPR_TSEQ_NLIS_SIZE     1
-+#define DPSECI_OPR_HSEQ_NLIS_SHIFT    0
-+#define DPSECI_OPR_HSEQ_NLIS_SIZE     1
-+
-+struct dpseci_rsp_get_opr {
-+      __le64 pad;
-+      u8 flags;
-+      u8 pad0[2];
-+      u8 oloe;
-+      u8 oeane;
-+      u8 olws;
-+      u8 oa;
-+      u8 oprrws;
-+      __le16 nesn;
-+      __le16 pad1;
-+      __le16 ndsn;
-+      __le16 pad2;
-+      __le16 ea_tseq;
-+      u8 tseq_nlis;
-+      u8 pad3;
-+      __le16 ea_hseq;
-+      u8 hseq_nlis;
-+      u8 pad4;
-+      __le16 ea_hptr;
-+      __le16 pad5;
-+      __le16 ea_tptr;
-+      __le16 pad6;
-+      __le16 opr_vid;
-+      __le16 pad7;
-+      __le16 opr_id;
-+};
-+
-+#define DPSECI_CGN_DEST_TYPE_SHIFT    0
-+#define DPSECI_CGN_DEST_TYPE_SIZE     4
-+#define DPSECI_CGN_UNITS_SHIFT                4
-+#define DPSECI_CGN_UNITS_SIZE         2
-+
-+struct dpseci_cmd_congestion_notification {
-+      __le32 dest_id;
-+      __le16 notification_mode;
-+      u8 priority;
-+      u8 options;
-+      __le64 message_iova;
-+      __le64 message_ctx;
-+      __le32 threshold_entry;
-+      __le32 threshold_exit;
-+};
-+
-+#endif /* _DPSECI_CMD_H_ */
---- a/drivers/crypto/caam/error.c
-+++ b/drivers/crypto/caam/error.c
-@@ -50,6 +50,12 @@ void caam_dump_sg(const char *level, con
- #endif /* DEBUG */
- EXPORT_SYMBOL(caam_dump_sg);
-+bool caam_little_end;
-+EXPORT_SYMBOL(caam_little_end);
-+
-+bool caam_imx;
-+EXPORT_SYMBOL(caam_imx);
-+
- static const struct {
-       u8 value;
-       const char *error_text;
-@@ -108,6 +114,54 @@ static const struct {
-       { 0xF1, "3GPP HFN matches or exceeds the Threshold" },
- };
-+static const struct {
-+      u8 value;
-+      const char *error_text;
-+} qi_error_list[] = {
-+      { 0x1F, "Job terminated by FQ or ICID flush" },
-+      { 0x20, "FD format error"},
-+      { 0x21, "FD command format error"},
-+      { 0x23, "FL format error"},
-+      { 0x25, "CRJD specified in FD, but not enabled in FLC"},
-+      { 0x30, "Max. buffer size too small"},
-+      { 0x31, "DHR exceeds max. buffer size (allocate mode, S/G format)"},
-+      { 0x32, "SGT exceeds max. buffer size (allocate mode, S/G format"},
-+      { 0x33, "Size over/underflow (allocate mode)"},
-+      { 0x34, "Size over/underflow (reuse mode)"},
-+      { 0x35, "Length exceeds max. short length (allocate mode, S/G/ format)"},
-+      { 0x36, "Memory footprint exceeds max. value (allocate mode, S/G/ format)"},
-+      { 0x41, "SBC frame format not supported (allocate mode)"},
-+      { 0x42, "Pool 0 invalid / pool 1 size < pool 0 size (allocate mode)"},
-+      { 0x43, "Annotation output enabled but ASAR = 0 (allocate mode)"},
-+      { 0x44, "Unsupported or reserved frame format or SGHR = 1 (reuse mode)"},
-+      { 0x45, "DHR correction underflow (reuse mode, single buffer format)"},
-+      { 0x46, "Annotation length exceeds offset (reuse mode)"},
-+      { 0x48, "Annotation output enabled but ASA limited by ASAR (reuse mode)"},
-+      { 0x49, "Data offset correction exceeds input frame data length (reuse mode)"},
-+      { 0x4B, "Annotation output enabled but ASA cannote be expanded (frame list)"},
-+      { 0x51, "Unsupported IF reuse mode"},
-+      { 0x52, "Unsupported FL use mode"},
-+      { 0x53, "Unsupported RJD use mode"},
-+      { 0x54, "Unsupported inline descriptor use mode"},
-+      { 0xC0, "Table buffer pool 0 depletion"},
-+      { 0xC1, "Table buffer pool 1 depletion"},
-+      { 0xC2, "Data buffer pool 0 depletion, no OF allocated"},
-+      { 0xC3, "Data buffer pool 1 depletion, no OF allocated"},
-+      { 0xC4, "Data buffer pool 0 depletion, partial OF allocated"},
-+      { 0xC5, "Data buffer pool 1 depletion, partial OF allocated"},
-+      { 0xD0, "FLC read error"},
-+      { 0xD1, "FL read error"},
-+      { 0xD2, "FL write error"},
-+      { 0xD3, "OF SGT write error"},
-+      { 0xD4, "PTA read error"},
-+      { 0xD5, "PTA write error"},
-+      { 0xD6, "OF SGT F-bit write error"},
-+      { 0xD7, "ASA write error"},
-+      { 0xE1, "FLC[ICR]=0 ICID error"},
-+      { 0xE2, "FLC[ICR]=1 ICID error"},
-+      { 0xE4, "source of ICID flush not trusted (BDI = 0)"},
-+};
-+
- static const char * const cha_id_list[] = {
-       "",
-       "AES",
-@@ -236,6 +290,27 @@ static void report_deco_status(struct de
-               status, error, idx_str, idx, err_str, err_err_code);
- }
-+static void report_qi_status(struct device *qidev, const u32 status,
-+                           const char *error)
-+{
-+      u8 err_id = status & JRSTA_QIERR_ERROR_MASK;
-+      const char *err_str = "unidentified error value 0x";
-+      char err_err_code[3] = { 0 };
-+      int i;
-+
-+      for (i = 0; i < ARRAY_SIZE(qi_error_list); i++)
-+              if (qi_error_list[i].value == err_id)
-+                      break;
-+
-+      if (i != ARRAY_SIZE(qi_error_list) && qi_error_list[i].error_text)
-+              err_str = qi_error_list[i].error_text;
-+      else
-+              snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id);
-+
-+      dev_err(qidev, "%08x: %s: %s%s\n",
-+              status, error, err_str, err_err_code);
-+}
-+
- static void report_jr_status(struct device *jrdev, const u32 status,
-                            const char *error)
- {
-@@ -250,7 +325,7 @@ static void report_cond_code_status(stru
-               status, error, __func__);
- }
--void caam_jr_strstatus(struct device *jrdev, u32 status)
-+void caam_strstatus(struct device *jrdev, u32 status, bool qi_v2)
- {
-       static const struct stat_src {
-               void (*report_ssed)(struct device *jrdev, const u32 status,
-@@ -262,7 +337,7 @@ void caam_jr_strstatus(struct device *jr
-               { report_ccb_status, "CCB" },
-               { report_jump_status, "Jump" },
-               { report_deco_status, "DECO" },
--              { NULL, "Queue Manager Interface" },
-+              { report_qi_status, "Queue Manager Interface" },
-               { report_jr_status, "Job Ring" },
-               { report_cond_code_status, "Condition Code" },
-               { NULL, NULL },
-@@ -288,4 +363,4 @@ void caam_jr_strstatus(struct device *jr
-       else
-               dev_err(jrdev, "%d: unknown error source\n", ssrc);
- }
--EXPORT_SYMBOL(caam_jr_strstatus);
-+EXPORT_SYMBOL(caam_strstatus);
---- a/drivers/crypto/caam/error.h
-+++ b/drivers/crypto/caam/error.h
-@@ -8,7 +8,11 @@
- #ifndef CAAM_ERROR_H
- #define CAAM_ERROR_H
- #define CAAM_ERROR_STR_MAX 302
--void caam_jr_strstatus(struct device *jrdev, u32 status);
-+
-+void caam_strstatus(struct device *dev, u32 status, bool qi_v2);
-+
-+#define caam_jr_strstatus(jrdev, status) caam_strstatus(jrdev, status, false)
-+#define caam_qi2_strstatus(qidev, status) caam_strstatus(qidev, status, true)
- void caam_dump_sg(const char *level, const char *prefix_str, int prefix_type,
-                 int rowsize, int groupsize, struct scatterlist *sg,
---- a/drivers/crypto/caam/intern.h
-+++ b/drivers/crypto/caam/intern.h
-@@ -65,10 +65,6 @@ struct caam_drv_private_jr {
-  * Driver-private storage for a single CAAM block instance
-  */
- struct caam_drv_private {
--#ifdef CONFIG_CAAM_QI
--      struct device *qidev;
--#endif
--
-       /* Physical-presence section */
-       struct caam_ctrl __iomem *ctrl; /* controller region */
-       struct caam_deco __iomem *deco; /* DECO/CCB views */
-@@ -76,14 +72,21 @@ struct caam_drv_private {
-       struct caam_queue_if __iomem *qi; /* QI control region */
-       struct caam_job_ring __iomem *jr[4];    /* JobR's register space */
-+      struct iommu_domain *domain;
-+
-       /*
-        * Detected geometry block. Filled in from device tree if powerpc,
-        * or from register-based version detection code
-        */
-       u8 total_jobrs;         /* Total Job Rings in device */
-       u8 qi_present;          /* Nonzero if QI present in device */
-+#ifdef CONFIG_CAAM_QI
-+      u8 qi_init;             /* Nonzero if QI has been initialized */
-+#endif
-+      u8 mc_en;               /* Nonzero if MC f/w is active */
-       int secvio_irq;         /* Security violation interrupt number */
-       int virt_en;            /* Virtualization enabled in CAAM */
-+      int era;                /* CAAM Era (internal HW revision) */
- #define       RNG4_MAX_HANDLES 2
-       /* RNG4 block */
-@@ -108,8 +111,95 @@ struct caam_drv_private {
- #endif
- };
--void caam_jr_algapi_init(struct device *dev);
--void caam_jr_algapi_remove(struct device *dev);
-+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API
-+
-+int caam_algapi_init(struct device *dev);
-+void caam_algapi_exit(void);
-+
-+#else
-+
-+static inline int caam_algapi_init(struct device *dev)
-+{
-+      return 0;
-+}
-+
-+static inline void caam_algapi_exit(void)
-+{
-+}
-+
-+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API */
-+
-+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API
-+
-+int caam_algapi_hash_init(struct device *dev);
-+void caam_algapi_hash_exit(void);
-+
-+#else
-+
-+static inline int caam_algapi_hash_init(struct device *dev)
-+{
-+      return 0;
-+}
-+
-+static inline void caam_algapi_hash_exit(void)
-+{
-+}
-+
-+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API */
-+
-+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API
-+
-+int caam_pkc_init(struct device *dev);
-+void caam_pkc_exit(void);
-+
-+#else
-+
-+static inline int caam_pkc_init(struct device *dev)
-+{
-+      return 0;
-+}
-+
-+static inline void caam_pkc_exit(void)
-+{
-+}
-+
-+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API */
-+
-+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API
-+
-+int caam_rng_init(struct device *dev);
-+void caam_rng_exit(void);
-+
-+#else
-+
-+static inline int caam_rng_init(struct device *dev)
-+{
-+      return 0;
-+}
-+
-+static inline void caam_rng_exit(void)
-+{
-+}
-+
-+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API */
-+
-+#ifdef CONFIG_CAAM_QI
-+
-+int caam_qi_algapi_init(struct device *dev);
-+void caam_qi_algapi_exit(void);
-+
-+#else
-+
-+static inline int caam_qi_algapi_init(struct device *dev)
-+{
-+      return 0;
-+}
-+
-+static inline void caam_qi_algapi_exit(void)
-+{
-+}
-+
-+#endif /* CONFIG_CAAM_QI */
- #ifdef CONFIG_DEBUG_FS
- static int caam_debugfs_u64_get(void *data, u64 *val)
---- a/drivers/crypto/caam/jr.c
-+++ b/drivers/crypto/caam/jr.c
-@@ -23,6 +23,52 @@ struct jr_driver_data {
- static struct jr_driver_data driver_data;
-+static int jr_driver_probed;
-+
-+int caam_jr_driver_probed(void)
-+{
-+      return jr_driver_probed;
-+}
-+EXPORT_SYMBOL(caam_jr_driver_probed);
-+
-+static DEFINE_MUTEX(algs_lock);
-+static unsigned int active_devs;
-+
-+static void register_algs(struct device *dev)
-+{
-+      mutex_lock(&algs_lock);
-+
-+      if (++active_devs != 1)
-+              goto algs_unlock;
-+
-+      caam_algapi_init(dev);
-+      caam_algapi_hash_init(dev);
-+      caam_pkc_init(dev);
-+      caam_rng_init(dev);
-+      caam_qi_algapi_init(dev);
-+
-+algs_unlock:
-+      mutex_unlock(&algs_lock);
-+}
-+
-+static void unregister_algs(void)
-+{
-+      mutex_lock(&algs_lock);
-+
-+      if (--active_devs != 0)
-+              goto algs_unlock;
-+
-+      caam_qi_algapi_exit();
-+
-+      caam_rng_exit();
-+      caam_pkc_exit();
-+      caam_algapi_hash_exit();
-+      caam_algapi_exit();
-+
-+algs_unlock:
-+      mutex_unlock(&algs_lock);
-+}
-+
- static int caam_reset_hw_jr(struct device *dev)
- {
-       struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
-@@ -108,6 +154,9 @@ static int caam_jr_remove(struct platfor
-               return -EBUSY;
-       }
-+      /* Unregister JR-based RNG & crypto algorithms */
-+      unregister_algs();
-+
-       /* Remove the node from Physical JobR list maintained by driver */
-       spin_lock(&driver_data.jr_alloc_lock);
-       list_del(&jrpriv->list_node);
-@@ -119,6 +168,8 @@ static int caam_jr_remove(struct platfor
-               dev_err(jrdev, "Failed to shut down job ring\n");
-       irq_dispose_mapping(jrpriv->irq);
-+      jr_driver_probed--;
-+
-       return ret;
- }
-@@ -282,6 +333,36 @@ struct device *caam_jr_alloc(void)
- EXPORT_SYMBOL(caam_jr_alloc);
- /**
-+ * caam_jridx_alloc() - Alloc a specific job ring based on its index.
-+ *
-+ * returns :  pointer to the newly allocated physical
-+ *          JobR dev can be written to if successful.
-+ **/
-+struct device *caam_jridx_alloc(int idx)
-+{
-+      struct caam_drv_private_jr *jrpriv;
-+      struct device *dev = ERR_PTR(-ENODEV);
-+
-+      spin_lock(&driver_data.jr_alloc_lock);
-+
-+      if (list_empty(&driver_data.jr_list))
-+              goto end;
-+
-+      list_for_each_entry(jrpriv, &driver_data.jr_list, list_node) {
-+              if (jrpriv->ridx == idx) {
-+                      atomic_inc(&jrpriv->tfm_count);
-+                      dev = jrpriv->dev;
-+                      break;
-+              }
-+      }
-+
-+end:
-+      spin_unlock(&driver_data.jr_alloc_lock);
-+      return dev;
-+}
-+EXPORT_SYMBOL(caam_jridx_alloc);
-+
-+/**
-  * caam_jr_free() - Free the Job Ring
-  * @rdev     - points to the dev that identifies the Job ring to
-  *             be released.
-@@ -539,6 +620,9 @@ static int caam_jr_probe(struct platform
-       atomic_set(&jrpriv->tfm_count, 0);
-+      register_algs(jrdev->parent);
-+      jr_driver_probed++;
-+
-       return 0;
- }
---- a/drivers/crypto/caam/jr.h
-+++ b/drivers/crypto/caam/jr.h
-@@ -9,7 +9,9 @@
- #define JR_H
- /* Prototypes for backend-level services exposed to APIs */
-+int caam_jr_driver_probed(void);
- struct device *caam_jr_alloc(void);
-+struct device *caam_jridx_alloc(int idx);
- void caam_jr_free(struct device *rdev);
- int caam_jr_enqueue(struct device *dev, u32 *desc,
-                   void (*cbk)(struct device *dev, u32 *desc, u32 status,
---- a/drivers/crypto/caam/key_gen.c
-+++ b/drivers/crypto/caam/key_gen.c
-@@ -11,36 +11,6 @@
- #include "desc_constr.h"
- #include "key_gen.h"
--/**
-- * split_key_len - Compute MDHA split key length for a given algorithm
-- * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
-- *        SHA224, SHA384, SHA512.
-- *
-- * Return: MDHA split key length
-- */
--static inline u32 split_key_len(u32 hash)
--{
--      /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
--      static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
--      u32 idx;
--
--      idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT;
--
--      return (u32)(mdpadlen[idx] * 2);
--}
--
--/**
-- * split_key_pad_len - Compute MDHA split key pad length for a given algorithm
-- * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
-- *        SHA224, SHA384, SHA512.
-- *
-- * Return: MDHA split key pad length
-- */
--static inline u32 split_key_pad_len(u32 hash)
--{
--      return ALIGN(split_key_len(hash), 16);
--}
--
- void split_key_done(struct device *dev, u32 *desc, u32 err,
-                          void *context)
- {
---- a/drivers/crypto/caam/key_gen.h
-+++ b/drivers/crypto/caam/key_gen.h
-@@ -6,6 +6,36 @@
-  *
-  */
-+/**
-+ * split_key_len - Compute MDHA split key length for a given algorithm
-+ * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
-+ *        SHA224, SHA384, SHA512.
-+ *
-+ * Return: MDHA split key length
-+ */
-+static inline u32 split_key_len(u32 hash)
-+{
-+      /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
-+      static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
-+      u32 idx;
-+
-+      idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT;
-+
-+      return (u32)(mdpadlen[idx] * 2);
-+}
-+
-+/**
-+ * split_key_pad_len - Compute MDHA split key pad length for a given algorithm
-+ * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
-+ *        SHA224, SHA384, SHA512.
-+ *
-+ * Return: MDHA split key pad length
-+ */
-+static inline u32 split_key_pad_len(u32 hash)
-+{
-+      return ALIGN(split_key_len(hash), 16);
-+}
-+
- struct split_key_result {
-       struct completion completion;
-       int err;
---- a/drivers/crypto/caam/qi.c
-+++ b/drivers/crypto/caam/qi.c
-@@ -9,7 +9,7 @@
- #include <linux/cpumask.h>
- #include <linux/kthread.h>
--#include <soc/fsl/qman.h>
-+#include <linux/fsl_qman.h>
- #include "regs.h"
- #include "qi.h"
-@@ -58,11 +58,9 @@ static DEFINE_PER_CPU(int, last_cpu);
- /*
-  * caam_qi_priv - CAAM QI backend private params
-  * @cgr: QMan congestion group
-- * @qi_pdev: platform device for QI backend
-  */
- struct caam_qi_priv {
-       struct qman_cgr cgr;
--      struct platform_device *qi_pdev;
- };
- static struct caam_qi_priv qipriv ____cacheline_aligned;
-@@ -102,26 +100,34 @@ static int mod_init_cpu;
-  */
- static struct kmem_cache *qi_cache;
-+static void *caam_iova_to_virt(struct iommu_domain *domain,
-+                             dma_addr_t iova_addr)
-+{
-+      phys_addr_t phys_addr;
-+
-+      phys_addr = domain ? iommu_iova_to_phys(domain, iova_addr) : iova_addr;
-+
-+      return phys_to_virt(phys_addr);
-+}
-+
- int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req)
- {
-       struct qm_fd fd;
--      dma_addr_t addr;
-       int ret;
-       int num_retries = 0;
--      qm_fd_clear_fd(&fd);
--      qm_fd_set_compound(&fd, qm_sg_entry_get_len(&req->fd_sgt[1]));
--
--      addr = dma_map_single(qidev, req->fd_sgt, sizeof(req->fd_sgt),
-+      fd.cmd = 0;
-+      fd.format = qm_fd_compound;
-+      fd.cong_weight = caam32_to_cpu(req->fd_sgt[1].length);
-+      fd.addr = dma_map_single(qidev, req->fd_sgt, sizeof(req->fd_sgt),
-                             DMA_BIDIRECTIONAL);
--      if (dma_mapping_error(qidev, addr)) {
-+      if (dma_mapping_error(qidev, fd.addr)) {
-               dev_err(qidev, "DMA mapping error for QI enqueue request\n");
-               return -EIO;
-       }
--      qm_fd_addr_set64(&fd, addr);
-       do {
--              ret = qman_enqueue(req->drv_ctx->req_fq, &fd);
-+              ret = qman_enqueue(req->drv_ctx->req_fq, &fd, 0);
-               if (likely(!ret))
-                       return 0;
-@@ -137,20 +143,21 @@ int caam_qi_enqueue(struct device *qidev
- EXPORT_SYMBOL(caam_qi_enqueue);
- static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq,
--                         const union qm_mr_entry *msg)
-+                         const struct qm_mr_entry *msg)
- {
-       const struct qm_fd *fd;
-       struct caam_drv_req *drv_req;
-       struct device *qidev = &(raw_cpu_ptr(&pcpu_qipriv)->net_dev.dev);
-+      struct caam_drv_private *priv = dev_get_drvdata(qidev);
-       fd = &msg->ern.fd;
--      if (qm_fd_get_format(fd) != qm_fd_compound) {
-+      if (fd->format != qm_fd_compound) {
-               dev_err(qidev, "Non-compound FD from CAAM\n");
-               return;
-       }
--      drv_req = (struct caam_drv_req *)phys_to_virt(qm_fd_addr_get64(fd));
-+      drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
-       if (!drv_req) {
-               dev_err(qidev,
-                       "Can't find original request for CAAM response\n");
-@@ -180,20 +187,22 @@ static struct qman_fq *create_caam_req_f
-       req_fq->cb.fqs = NULL;
-       ret = qman_create_fq(0, QMAN_FQ_FLAG_DYNAMIC_FQID |
--                              QMAN_FQ_FLAG_TO_DCPORTAL, req_fq);
-+                              QMAN_FQ_FLAG_TO_DCPORTAL | QMAN_FQ_FLAG_LOCKED,
-+                           req_fq);
-       if (ret) {
-               dev_err(qidev, "Failed to create session req FQ\n");
-               goto create_req_fq_fail;
-       }
--      memset(&opts, 0, sizeof(opts));
--      opts.we_mask = cpu_to_be16(QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_DESTWQ |
--                                 QM_INITFQ_WE_CONTEXTB |
--                                 QM_INITFQ_WE_CONTEXTA | QM_INITFQ_WE_CGID);
--      opts.fqd.fq_ctrl = cpu_to_be16(QM_FQCTRL_CPCSTASH | QM_FQCTRL_CGE);
--      qm_fqd_set_destwq(&opts.fqd, qm_channel_caam, 2);
--      opts.fqd.context_b = cpu_to_be32(qman_fq_fqid(rsp_fq));
--      qm_fqd_context_a_set64(&opts.fqd, hwdesc);
-+      opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_DESTWQ |
-+                     QM_INITFQ_WE_CONTEXTB | QM_INITFQ_WE_CONTEXTA |
-+                     QM_INITFQ_WE_CGID;
-+      opts.fqd.fq_ctrl = QM_FQCTRL_CPCSTASH | QM_FQCTRL_CGE;
-+      opts.fqd.dest.channel = qm_channel_caam;
-+      opts.fqd.dest.wq = 2;
-+      opts.fqd.context_b = qman_fq_fqid(rsp_fq);
-+      opts.fqd.context_a.hi = upper_32_bits(hwdesc);
-+      opts.fqd.context_a.lo = lower_32_bits(hwdesc);
-       opts.fqd.cgid = qipriv.cgr.cgrid;
-       ret = qman_init_fq(req_fq, fq_sched_flag, &opts);
-@@ -207,7 +216,7 @@ static struct qman_fq *create_caam_req_f
-       return req_fq;
- init_req_fq_fail:
--      qman_destroy_fq(req_fq);
-+      qman_destroy_fq(req_fq, 0);
- create_req_fq_fail:
-       kfree(req_fq);
-       return ERR_PTR(ret);
-@@ -275,7 +284,7 @@ empty_fq:
-       if (ret)
-               dev_err(qidev, "OOS of FQID: %u failed\n", fq->fqid);
--      qman_destroy_fq(fq);
-+      qman_destroy_fq(fq, 0);
-       kfree(fq);
-       return ret;
-@@ -292,7 +301,7 @@ static int empty_caam_fq(struct qman_fq
-               if (ret)
-                       return ret;
--              if (!qm_mcr_np_get(&np, frm_cnt))
-+              if (!np.frm_cnt)
-                       break;
-               msleep(20);
-@@ -495,7 +504,7 @@ EXPORT_SYMBOL(caam_drv_ctx_rel);
- int caam_qi_shutdown(struct device *qidev)
- {
-       int i, ret;
--      struct caam_qi_priv *priv = dev_get_drvdata(qidev);
-+      struct caam_qi_priv *priv = &qipriv;
-       const cpumask_t *cpus = qman_affine_cpus();
-       struct cpumask old_cpumask = current->cpus_allowed;
-@@ -528,7 +537,6 @@ int caam_qi_shutdown(struct device *qide
-       /* Now that we're done with the CGRs, restore the cpus allowed mask */
-       set_cpus_allowed_ptr(current, &old_cpumask);
--      platform_device_unregister(priv->qi_pdev);
-       return ret;
- }
-@@ -572,22 +580,28 @@ static enum qman_cb_dqrr_result caam_rsp
-       struct caam_drv_req *drv_req;
-       const struct qm_fd *fd;
-       struct device *qidev = &(raw_cpu_ptr(&pcpu_qipriv)->net_dev.dev);
--      u32 status;
-+      struct caam_drv_private *priv = dev_get_drvdata(qidev);
-       if (caam_qi_napi_schedule(p, caam_napi))
-               return qman_cb_dqrr_stop;
-       fd = &dqrr->fd;
--      status = be32_to_cpu(fd->status);
--      if (unlikely(status))
--              dev_err(qidev, "Error: %#x in CAAM response FD\n", status);
-+      if (unlikely(fd->status)) {
-+              u32 ssrc = fd->status & JRSTA_SSRC_MASK;
-+              u8 err_id = fd->status & JRSTA_CCBERR_ERRID_MASK;
--      if (unlikely(qm_fd_get_format(fd) != qm_fd_compound)) {
-+              if (ssrc != JRSTA_SSRC_CCB_ERROR ||
-+                  err_id != JRSTA_CCBERR_ERRID_ICVCHK)
-+                      dev_err(qidev, "Error: %#x in CAAM response FD\n",
-+                              fd->status);
-+      }
-+
-+      if (unlikely(fd->format != qm_fd_compound)) {
-               dev_err(qidev, "Non-compound FD from CAAM\n");
-               return qman_cb_dqrr_consume;
-       }
--      drv_req = (struct caam_drv_req *)phys_to_virt(qm_fd_addr_get64(fd));
-+      drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
-       if (unlikely(!drv_req)) {
-               dev_err(qidev,
-                       "Can't find original request for caam response\n");
-@@ -597,7 +611,7 @@ static enum qman_cb_dqrr_result caam_rsp
-       dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd),
-                        sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL);
--      drv_req->cbk(drv_req, status);
-+      drv_req->cbk(drv_req, fd->status);
-       return qman_cb_dqrr_consume;
- }
-@@ -621,17 +635,18 @@ static int alloc_rsp_fq_cpu(struct devic
-               return -ENODEV;
-       }
--      memset(&opts, 0, sizeof(opts));
--      opts.we_mask = cpu_to_be16(QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_DESTWQ |
--                                 QM_INITFQ_WE_CONTEXTB |
--                                 QM_INITFQ_WE_CONTEXTA | QM_INITFQ_WE_CGID);
--      opts.fqd.fq_ctrl = cpu_to_be16(QM_FQCTRL_CTXASTASHING |
--                                     QM_FQCTRL_CPCSTASH | QM_FQCTRL_CGE);
--      qm_fqd_set_destwq(&opts.fqd, qman_affine_channel(cpu), 3);
-+      opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_DESTWQ |
-+              QM_INITFQ_WE_CONTEXTB | QM_INITFQ_WE_CONTEXTA |
-+              QM_INITFQ_WE_CGID;
-+      opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING | QM_FQCTRL_CPCSTASH |
-+                         QM_FQCTRL_CGE;
-+      opts.fqd.dest.channel = qman_affine_channel(cpu);
-+      opts.fqd.dest.wq = 3;
-       opts.fqd.cgid = qipriv.cgr.cgrid;
-       opts.fqd.context_a.stashing.exclusive = QM_STASHING_EXCL_CTX |
-                                               QM_STASHING_EXCL_DATA;
--      qm_fqd_set_stashing(&opts.fqd, 0, 1, 1);
-+      opts.fqd.context_a.stashing.data_cl = 1;
-+      opts.fqd.context_a.stashing.context_cl = 1;
-       ret = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &opts);
-       if (ret) {
-@@ -650,9 +665,8 @@ static int init_cgr(struct device *qidev
- {
-       int ret;
-       struct qm_mcc_initcgr opts;
--      const u64 cpus = *(u64 *)qman_affine_cpus();
--      const int num_cpus = hweight64(cpus);
--      const u64 val = num_cpus * MAX_RSP_FQ_BACKLOG_PER_CPU;
-+      const u64 val = (u64)cpumask_weight(qman_affine_cpus()) *
-+                      MAX_RSP_FQ_BACKLOG_PER_CPU;
-       ret = qman_alloc_cgrid(&qipriv.cgr.cgrid);
-       if (ret) {
-@@ -662,8 +676,7 @@ static int init_cgr(struct device *qidev
-       qipriv.cgr.cb = cgr_cb;
-       memset(&opts, 0, sizeof(opts));
--      opts.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES |
--                                 QM_CGR_WE_MODE);
-+      opts.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES | QM_CGR_WE_MODE;
-       opts.cgr.cscn_en = QM_CGR_EN;
-       opts.cgr.mode = QMAN_CGR_MODE_FRAME;
-       qm_cgr_cs_thres_set64(&opts.cgr.cs_thres, val, 1);
-@@ -708,15 +721,10 @@ static void free_rsp_fqs(void)
- int caam_qi_init(struct platform_device *caam_pdev)
- {
-       int err, i;
--      struct platform_device *qi_pdev;
-       struct device *ctrldev = &caam_pdev->dev, *qidev;
-       struct caam_drv_private *ctrlpriv;
-       const cpumask_t *cpus = qman_affine_cpus();
-       struct cpumask old_cpumask = current->cpus_allowed;
--      static struct platform_device_info qi_pdev_info = {
--              .name = "caam_qi",
--              .id = PLATFORM_DEVID_NONE
--      };
-       /*
-        * QMAN requires CGRs to be removed from same CPU+portal from where it
-@@ -728,24 +736,13 @@ int caam_qi_init(struct platform_device
-       mod_init_cpu = cpumask_first(cpus);
-       set_cpus_allowed_ptr(current, get_cpu_mask(mod_init_cpu));
--      qi_pdev_info.parent = ctrldev;
--      qi_pdev_info.dma_mask = dma_get_mask(ctrldev);
--      qi_pdev = platform_device_register_full(&qi_pdev_info);
--      if (IS_ERR(qi_pdev))
--              return PTR_ERR(qi_pdev);
--      set_dma_ops(&qi_pdev->dev, get_dma_ops(ctrldev));
--
-       ctrlpriv = dev_get_drvdata(ctrldev);
--      qidev = &qi_pdev->dev;
--
--      qipriv.qi_pdev = qi_pdev;
--      dev_set_drvdata(qidev, &qipriv);
-+      qidev = ctrldev;
-       /* Initialize the congestion detection */
-       err = init_cgr(qidev);
-       if (err) {
-               dev_err(qidev, "CGR initialization failed: %d\n", err);
--              platform_device_unregister(qi_pdev);
-               return err;
-       }
-@@ -754,7 +751,6 @@ int caam_qi_init(struct platform_device
-       if (err) {
-               dev_err(qidev, "Can't allocate CAAM response FQs: %d\n", err);
-               free_rsp_fqs();
--              platform_device_unregister(qi_pdev);
-               return err;
-       }
-@@ -777,15 +773,11 @@ int caam_qi_init(struct platform_device
-               napi_enable(irqtask);
-       }
--      /* Hook up QI device to parent controlling caam device */
--      ctrlpriv->qidev = qidev;
--
-       qi_cache = kmem_cache_create("caamqicache", CAAM_QI_MEMCACHE_SIZE, 0,
-                                    SLAB_CACHE_DMA, NULL);
-       if (!qi_cache) {
-               dev_err(qidev, "Can't allocate CAAM cache\n");
-               free_rsp_fqs();
--              platform_device_unregister(qi_pdev);
-               return -ENOMEM;
-       }
-@@ -795,6 +787,8 @@ int caam_qi_init(struct platform_device
-       debugfs_create_file("qi_congested", 0444, ctrlpriv->ctl,
-                           &times_congested, &caam_fops_u64_ro);
- #endif
-+
-+      ctrlpriv->qi_init = 1;
-       dev_info(qidev, "Linux CAAM Queue I/F driver initialised\n");
-       return 0;
- }
---- a/drivers/crypto/caam/qi.h
-+++ b/drivers/crypto/caam/qi.h
-@@ -9,7 +9,7 @@
- #ifndef __QI_H__
- #define __QI_H__
--#include <soc/fsl/qman.h>
-+#include <linux/fsl_qman.h>
- #include "compat.h"
- #include "desc.h"
- #include "desc_constr.h"
---- a/drivers/crypto/caam/regs.h
-+++ b/drivers/crypto/caam/regs.h
-@@ -3,6 +3,7 @@
-  * CAAM hardware register-level view
-  *
-  * Copyright 2008-2011 Freescale Semiconductor, Inc.
-+ * Copyright 2018 NXP
-  */
- #ifndef REGS_H
-@@ -211,6 +212,47 @@ struct jr_outentry {
-       u32 jrstatus;   /* Status for completed descriptor */
- } __packed;
-+/* Version registers (Era 10+)        e80-eff */
-+struct version_regs {
-+      u32 crca;       /* CRCA_VERSION */
-+      u32 afha;       /* AFHA_VERSION */
-+      u32 kfha;       /* KFHA_VERSION */
-+      u32 pkha;       /* PKHA_VERSION */
-+      u32 aesa;       /* AESA_VERSION */
-+      u32 mdha;       /* MDHA_VERSION */
-+      u32 desa;       /* DESA_VERSION */
-+      u32 snw8a;      /* SNW8A_VERSION */
-+      u32 snw9a;      /* SNW9A_VERSION */
-+      u32 zuce;       /* ZUCE_VERSION */
-+      u32 zuca;       /* ZUCA_VERSION */
-+      u32 ccha;       /* CCHA_VERSION */
-+      u32 ptha;       /* PTHA_VERSION */
-+      u32 rng;        /* RNG_VERSION */
-+      u32 trng;       /* TRNG_VERSION */
-+      u32 aaha;       /* AAHA_VERSION */
-+      u32 rsvd[10];
-+      u32 sr;         /* SR_VERSION */
-+      u32 dma;        /* DMA_VERSION */
-+      u32 ai;         /* AI_VERSION */
-+      u32 qi;         /* QI_VERSION */
-+      u32 jr;         /* JR_VERSION */
-+      u32 deco;       /* DECO_VERSION */
-+};
-+
-+/* Version registers bitfields */
-+
-+/* Number of CHAs instantiated */
-+#define CHA_VER_NUM_MASK      0xffull
-+/* CHA Miscellaneous Information */
-+#define CHA_VER_MISC_SHIFT    8
-+#define CHA_VER_MISC_MASK     (0xffull << CHA_VER_MISC_SHIFT)
-+/* CHA Revision Number */
-+#define CHA_VER_REV_SHIFT     16
-+#define CHA_VER_REV_MASK      (0xffull << CHA_VER_REV_SHIFT)
-+/* CHA Version ID */
-+#define CHA_VER_VID_SHIFT     24
-+#define CHA_VER_VID_MASK      (0xffull << CHA_VER_VID_SHIFT)
-+
- /*
-  * caam_perfmon - Performance Monitor/Secure Memory Status/
-  *                CAAM Global Status/Component Version IDs
-@@ -223,15 +265,13 @@ struct jr_outentry {
- #define CHA_NUM_MS_DECONUM_MASK       (0xfull << CHA_NUM_MS_DECONUM_SHIFT)
- /*
-- * CHA version IDs / instantiation bitfields
-+ * CHA version IDs / instantiation bitfields (< Era 10)
-  * Defined for use with the cha_id fields in perfmon, but the same shift/mask
-  * selectors can be used to pull out the number of instantiated blocks within
-  * cha_num fields in perfmon because the locations are the same.
-  */
- #define CHA_ID_LS_AES_SHIFT   0
- #define CHA_ID_LS_AES_MASK    (0xfull << CHA_ID_LS_AES_SHIFT)
--#define CHA_ID_LS_AES_LP      (0x3ull << CHA_ID_LS_AES_SHIFT)
--#define CHA_ID_LS_AES_HP      (0x4ull << CHA_ID_LS_AES_SHIFT)
- #define CHA_ID_LS_DES_SHIFT   4
- #define CHA_ID_LS_DES_MASK    (0xfull << CHA_ID_LS_DES_SHIFT)
-@@ -241,9 +281,6 @@ struct jr_outentry {
- #define CHA_ID_LS_MD_SHIFT    12
- #define CHA_ID_LS_MD_MASK     (0xfull << CHA_ID_LS_MD_SHIFT)
--#define CHA_ID_LS_MD_LP256    (0x0ull << CHA_ID_LS_MD_SHIFT)
--#define CHA_ID_LS_MD_LP512    (0x1ull << CHA_ID_LS_MD_SHIFT)
--#define CHA_ID_LS_MD_HP               (0x2ull << CHA_ID_LS_MD_SHIFT)
- #define CHA_ID_LS_RNG_SHIFT   16
- #define CHA_ID_LS_RNG_MASK    (0xfull << CHA_ID_LS_RNG_SHIFT)
-@@ -269,6 +306,13 @@ struct jr_outentry {
- #define CHA_ID_MS_JR_SHIFT    28
- #define CHA_ID_MS_JR_MASK     (0xfull << CHA_ID_MS_JR_SHIFT)
-+/* Specific CHA version IDs */
-+#define CHA_VER_VID_AES_LP    0x3ull
-+#define CHA_VER_VID_AES_HP    0x4ull
-+#define CHA_VER_VID_MD_LP256  0x0ull
-+#define CHA_VER_VID_MD_LP512  0x1ull
-+#define CHA_VER_VID_MD_HP     0x2ull
-+
- struct sec_vid {
-       u16 ip_id;
-       u8 maj_rev;
-@@ -473,8 +517,10 @@ struct caam_ctrl {
-               struct rng4tst r4tst[2];
-       };
--      u32 rsvd9[448];
-+      u32 rsvd9[416];
-+      /* Version registers - introduced with era 10           e80-eff */
-+      struct version_regs vreg;
-       /* Performance Monitor                                  f00-fff */
-       struct caam_perfmon perfmon;
- };
-@@ -564,8 +610,10 @@ struct caam_job_ring {
-       u32 rsvd11;
-       u32 jrcommand;  /* JRCRx - JobR command */
--      u32 rsvd12[932];
-+      u32 rsvd12[900];
-+      /* Version registers - introduced with era 10           e80-eff */
-+      struct version_regs vreg;
-       /* Performance Monitor                                  f00-fff */
-       struct caam_perfmon perfmon;
- };
-@@ -627,6 +675,8 @@ struct caam_job_ring {
- #define JRSTA_DECOERR_INVSIGN       0x86
- #define JRSTA_DECOERR_DSASIGN       0x87
-+#define JRSTA_QIERR_ERROR_MASK      0x00ff
-+
- #define JRSTA_CCBERR_JUMP           0x08000000
- #define JRSTA_CCBERR_INDEX_MASK     0xff00
- #define JRSTA_CCBERR_INDEX_SHIFT    8
-@@ -870,13 +920,19 @@ struct caam_deco {
-       u32 rsvd29[48];
-       u32 descbuf[64];        /* DxDESB - Descriptor buffer */
-       u32 rscvd30[193];
--#define DESC_DBG_DECO_STAT_HOST_ERR   0x00D00000
- #define DESC_DBG_DECO_STAT_VALID      0x80000000
- #define DESC_DBG_DECO_STAT_MASK               0x00F00000
-+#define DESC_DBG_DECO_STAT_SHIFT      20
-       u32 desc_dbg;           /* DxDDR - DECO Debug Register */
--      u32 rsvd31[126];
-+      u32 rsvd31[13];
-+#define DESC_DER_DECO_STAT_MASK               0x000F0000
-+#define DESC_DER_DECO_STAT_SHIFT      16
-+      u32 dbg_exec;           /* DxDER - DECO Debug Exec Register */
-+      u32 rsvd32[112];
- };
-+#define DECO_STAT_HOST_ERR    0xD
-+
- #define DECO_JQCR_WHL         0x20000000
- #define DECO_JQCR_FOUR                0x10000000
---- a/drivers/crypto/caam/sg_sw_qm.h
-+++ b/drivers/crypto/caam/sg_sw_qm.h
-@@ -34,46 +34,61 @@
- #ifndef __SG_SW_QM_H
- #define __SG_SW_QM_H
--#include <soc/fsl/qman.h>
-+#include <linux/fsl_qman.h>
- #include "regs.h"
-+static inline void cpu_to_hw_sg(struct qm_sg_entry *qm_sg_ptr)
-+{
-+      dma_addr_t addr = qm_sg_ptr->opaque;
-+
-+      qm_sg_ptr->opaque = cpu_to_caam64(addr);
-+      qm_sg_ptr->sgt_efl = cpu_to_caam32(qm_sg_ptr->sgt_efl);
-+}
-+
- static inline void __dma_to_qm_sg(struct qm_sg_entry *qm_sg_ptr, dma_addr_t dma,
--                                u16 offset)
-+                                u32 len, u16 offset)
- {
--      qm_sg_entry_set64(qm_sg_ptr, dma);
-+      qm_sg_ptr->addr = dma;
-+      qm_sg_ptr->length = len;
-       qm_sg_ptr->__reserved2 = 0;
-       qm_sg_ptr->bpid = 0;
--      qm_sg_ptr->offset = cpu_to_be16(offset & QM_SG_OFF_MASK);
-+      qm_sg_ptr->__reserved3 = 0;
-+      qm_sg_ptr->offset = offset & QM_SG_OFFSET_MASK;
-+
-+      cpu_to_hw_sg(qm_sg_ptr);
- }
- static inline void dma_to_qm_sg_one(struct qm_sg_entry *qm_sg_ptr,
-                                   dma_addr_t dma, u32 len, u16 offset)
- {
--      __dma_to_qm_sg(qm_sg_ptr, dma, offset);
--      qm_sg_entry_set_len(qm_sg_ptr, len);
-+      qm_sg_ptr->extension = 0;
-+      qm_sg_ptr->final = 0;
-+      __dma_to_qm_sg(qm_sg_ptr, dma, len, offset);
- }
- static inline void dma_to_qm_sg_one_last(struct qm_sg_entry *qm_sg_ptr,
-                                        dma_addr_t dma, u32 len, u16 offset)
- {
--      __dma_to_qm_sg(qm_sg_ptr, dma, offset);
--      qm_sg_entry_set_f(qm_sg_ptr, len);
-+      qm_sg_ptr->extension = 0;
-+      qm_sg_ptr->final = 1;
-+      __dma_to_qm_sg(qm_sg_ptr, dma, len, offset);
- }
- static inline void dma_to_qm_sg_one_ext(struct qm_sg_entry *qm_sg_ptr,
-                                       dma_addr_t dma, u32 len, u16 offset)
- {
--      __dma_to_qm_sg(qm_sg_ptr, dma, offset);
--      qm_sg_ptr->cfg = cpu_to_be32(QM_SG_EXT | (len & QM_SG_LEN_MASK));
-+      qm_sg_ptr->extension = 1;
-+      qm_sg_ptr->final = 0;
-+      __dma_to_qm_sg(qm_sg_ptr, dma, len, offset);
- }
- static inline void dma_to_qm_sg_one_last_ext(struct qm_sg_entry *qm_sg_ptr,
-                                            dma_addr_t dma, u32 len,
-                                            u16 offset)
- {
--      __dma_to_qm_sg(qm_sg_ptr, dma, offset);
--      qm_sg_ptr->cfg = cpu_to_be32(QM_SG_EXT | QM_SG_FIN |
--                                   (len & QM_SG_LEN_MASK));
-+      qm_sg_ptr->extension = 1;
-+      qm_sg_ptr->final = 1;
-+      __dma_to_qm_sg(qm_sg_ptr, dma, len, offset);
- }
- /*
-@@ -102,7 +117,10 @@ static inline void sg_to_qm_sg_last(stru
-                                   struct qm_sg_entry *qm_sg_ptr, u16 offset)
- {
-       qm_sg_ptr = sg_to_qm_sg(sg, sg_count, qm_sg_ptr, offset);
--      qm_sg_entry_set_f(qm_sg_ptr, qm_sg_entry_get_len(qm_sg_ptr));
-+
-+      qm_sg_ptr->sgt_efl = caam32_to_cpu(qm_sg_ptr->sgt_efl);
-+      qm_sg_ptr->final = 1;
-+      qm_sg_ptr->sgt_efl = cpu_to_caam32(qm_sg_ptr->sgt_efl);
- }
- #endif /* __SG_SW_QM_H */
---- a/drivers/crypto/talitos.c
-+++ b/drivers/crypto/talitos.c
-@@ -1250,6 +1250,14 @@ static int ipsec_esp(struct talitos_edes
-       ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
-                                sg_count, areq->assoclen, tbl_off, elen);
-+      /*
-+       * In case of SEC 2.x+, cipher in len must include only the ciphertext,
-+       * while extent is used for ICV len.
-+       */
-+      if ((edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP) &&
-+          (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
-+              desc->ptr[4].len = cpu_to_be16(cryptlen);
-+
-       if (ret > 1) {
-               tbl_off += ret;
-               sync_needed = true;
---- a/include/crypto/chacha20.h
-+++ b/include/crypto/chacha20.h
-@@ -13,6 +13,7 @@
- #define CHACHA20_IV_SIZE      16
- #define CHACHA20_KEY_SIZE     32
- #define CHACHA20_BLOCK_SIZE   64
-+#define CHACHAPOLY_IV_SIZE    12
- struct chacha20_ctx {
-       u32 key[8];