All of lore.kernel.org
 help / color / mirror / Atom feed
From: Corentin Labbe <clabbe.montjoie@gmail.com>
To: davem@davemloft.net, herbert@gondor.apana.org.au,
	mripard@kernel.org, wens@csie.org
Cc: linux-arm-kernel@lists.infradead.org,
	linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-sunxi@googlegroups.com,
	Corentin Labbe <clabbe.montjoie@gmail.com>
Subject: [PATCH] crypto: allwinner: sun8i-ce: enable working on big endian
Date: Sun, 17 Nov 2019 17:07:45 +0100	[thread overview]
Message-ID: <20191117160745.32197-1-clabbe.montjoie@gmail.com> (raw)

On big endian kernel, the sun8i-ce crypto driver does not works.
This patch do the necessary modification to permit it to work on BE
kernel (setting descriptor entries as __le32 and adding some cpu_to_le32)

Fixes: 06f751b61329 ("crypto: allwinner - Add sun8i-ce Crypto Engine")
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
---
 .../allwinner/sun8i-ce/sun8i-ce-cipher.c      | 50 +++++++++++--------
 drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h  | 24 ++++-----
 2 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
index b6e7c346c3ae..37d0b6c386a0 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
@@ -90,7 +90,9 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 	struct ce_task *cet;
 	struct scatterlist *sg;
 	unsigned int todo, len, offset, ivsize;
+	dma_addr_t addr_iv = 0, addr_key = 0;
 	void *backup_iv = NULL;
+	u32 common, sym;
 	int flow, i;
 	int nr_sgs = 0;
 	int nr_sgd = 0;
@@ -115,28 +117,31 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 	cet = chan->tl;
 	memset(cet, 0, sizeof(struct ce_task));
 
-	cet->t_id = flow;
-	cet->t_common_ctl = ce->variant->alg_cipher[algt->ce_algo_id];
-	cet->t_common_ctl |= rctx->op_dir | CE_COMM_INT;
-	cet->t_dlen = areq->cryptlen / 4;
+	cet->t_id = cpu_to_le32(flow);
+	common = ce->variant->alg_cipher[algt->ce_algo_id];
+	common |= rctx->op_dir | CE_COMM_INT;
+	cet->t_common_ctl = cpu_to_le32(common);
 	/* CTS and recent CE (H6) need length in bytes, in word otherwise */
 	if (ce->variant->has_t_dlen_in_bytes)
-		cet->t_dlen = areq->cryptlen;
+		cet->t_dlen = cpu_to_le32(areq->cryptlen);
+	else
+		cet->t_dlen = cpu_to_le32(areq->cryptlen / 4);
 
-	cet->t_sym_ctl = ce->variant->op_mode[algt->ce_blockmode];
+	sym = ce->variant->op_mode[algt->ce_blockmode];
 	len = op->keylen;
 	switch (len) {
 	case 128 / 8:
-		cet->t_sym_ctl |= CE_AES_128BITS;
+		sym |= CE_AES_128BITS;
 		break;
 	case 192 / 8:
-		cet->t_sym_ctl |= CE_AES_192BITS;
+		sym |= CE_AES_192BITS;
 		break;
 	case 256 / 8:
-		cet->t_sym_ctl |= CE_AES_256BITS;
+		sym |= CE_AES_256BITS;
 		break;
 	}
 
+	cet->t_sym_ctl = cpu_to_le32(sym);
 	cet->t_asym_ctl = 0;
 
 	chan->op_mode = ce->variant->op_mode[algt->ce_blockmode];
@@ -144,9 +149,9 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 	chan->method = ce->variant->alg_cipher[algt->ce_algo_id];
 	chan->keylen = op->keylen;
 
-	cet->t_key = dma_map_single(ce->dev, op->key, op->keylen,
-				    DMA_TO_DEVICE);
-	if (dma_mapping_error(ce->dev, cet->t_key)) {
+	addr_key = dma_map_single(ce->dev, op->key, op->keylen, DMA_TO_DEVICE);
+	cet->t_key = cpu_to_le32(addr_key);
+	if (dma_mapping_error(ce->dev, addr_key)) {
 		dev_err(ce->dev, "Cannot DMA MAP KEY\n");
 		err = -EFAULT;
 		goto theend;
@@ -171,9 +176,10 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 						 ivsize, 0);
 		}
 		memcpy(chan->bounce_iv, areq->iv, ivsize);
-		cet->t_iv = dma_map_single(ce->dev, chan->bounce_iv,
-					   chan->ivlen, DMA_TO_DEVICE);
-		if (dma_mapping_error(ce->dev, cet->t_iv)) {
+		addr_iv = dma_map_single(ce->dev, chan->bounce_iv, chan->ivlen,
+					 DMA_TO_DEVICE);
+		cet->t_iv = cpu_to_le32(addr_iv);
+		if (dma_mapping_error(ce->dev, addr_iv)) {
 			dev_err(ce->dev, "Cannot DMA MAP IV\n");
 			err = -ENOMEM;
 			goto theend_iv;
@@ -208,9 +214,9 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 
 	len = areq->cryptlen;
 	for_each_sg(areq->src, sg, nr_sgs, i) {
-		cet->t_src[i].addr = sg_dma_address(sg);
+		cet->t_src[i].addr = cpu_to_le32(sg_dma_address(sg));
 		todo = min(len, sg_dma_len(sg));
-		cet->t_src[i].len = todo / 4;
+		cet->t_src[i].len = cpu_to_le32(todo / 4);
 		dev_dbg(ce->dev, "%s total=%u SG(%d %u off=%d) todo=%u\n", __func__,
 			areq->cryptlen, i, cet->t_src[i].len, sg->offset, todo);
 		len -= todo;
@@ -223,9 +229,9 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 
 	len = areq->cryptlen;
 	for_each_sg(areq->dst, sg, nr_sgd, i) {
-		cet->t_dst[i].addr = sg_dma_address(sg);
+		cet->t_dst[i].addr = cpu_to_le32(sg_dma_address(sg));
 		todo = min(len, sg_dma_len(sg));
-		cet->t_dst[i].len = todo / 4;
+		cet->t_dst[i].len = cpu_to_le32(todo / 4);
 		dev_dbg(ce->dev, "%s total=%u SG(%d %u off=%d) todo=%u\n", __func__,
 			areq->cryptlen, i, cet->t_dst[i].len, sg->offset, todo);
 		len -= todo;
@@ -250,8 +256,8 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 
 theend_iv:
 	if (areq->iv && ivsize > 0) {
-		if (cet->t_iv)
-			dma_unmap_single(ce->dev, cet->t_iv, chan->ivlen,
+		if (addr_iv)
+			dma_unmap_single(ce->dev, addr_iv, chan->ivlen,
 					 DMA_TO_DEVICE);
 		offset = areq->cryptlen - ivsize;
 		if (rctx->op_dir & CE_DECRYPTION) {
@@ -265,7 +271,7 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 	}
 
 theend_key:
-	dma_unmap_single(ce->dev, cet->t_key, op->keylen, DMA_TO_DEVICE);
+	dma_unmap_single(ce->dev, addr_key, op->keylen, DMA_TO_DEVICE);
 
 theend:
 	return err;
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
index c6ddad3393ed..43db49ceafe4 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
@@ -103,8 +103,8 @@ struct ce_variant {
 };
 
 struct sginfo {
-	u32 addr;
-	u32 len;
+	__le32 addr;
+	__le32 len;
 } __packed;
 
 /*
@@ -112,18 +112,18 @@ struct sginfo {
  * The structure of this descriptor could be found in the datasheet
  */
 struct ce_task {
-	u32 t_id;
-	u32 t_common_ctl;
-	u32 t_sym_ctl;
-	u32 t_asym_ctl;
-	u32 t_key;
-	u32 t_iv;
-	u32 t_ctr;
-	u32 t_dlen;
+	__le32 t_id;
+	__le32 t_common_ctl;
+	__le32 t_sym_ctl;
+	__le32 t_asym_ctl;
+	__le32 t_key;
+	__le32 t_iv;
+	__le32 t_ctr;
+	__le32 t_dlen;
 	struct sginfo t_src[MAX_SG];
 	struct sginfo t_dst[MAX_SG];
-	u32 next;
-	u32 reserved[3];
+	__le32 next;
+	__le32 reserved[3];
 } __packed __aligned(8);
 
 /*
-- 
2.23.0


WARNING: multiple messages have this Message-ID (diff)
From: Corentin Labbe <clabbe.montjoie@gmail.com>
To: davem@davemloft.net, herbert@gondor.apana.org.au,
	mripard@kernel.org, wens@csie.org
Cc: linux-sunxi@googlegroups.com,
	Corentin Labbe <clabbe.montjoie@gmail.com>,
	linux-crypto@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH] crypto: allwinner: sun8i-ce: enable working on big endian
Date: Sun, 17 Nov 2019 17:07:45 +0100	[thread overview]
Message-ID: <20191117160745.32197-1-clabbe.montjoie@gmail.com> (raw)

On big endian kernel, the sun8i-ce crypto driver does not works.
This patch do the necessary modification to permit it to work on BE
kernel (setting descriptor entries as __le32 and adding some cpu_to_le32)

Fixes: 06f751b61329 ("crypto: allwinner - Add sun8i-ce Crypto Engine")
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
---
 .../allwinner/sun8i-ce/sun8i-ce-cipher.c      | 50 +++++++++++--------
 drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h  | 24 ++++-----
 2 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
index b6e7c346c3ae..37d0b6c386a0 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
@@ -90,7 +90,9 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 	struct ce_task *cet;
 	struct scatterlist *sg;
 	unsigned int todo, len, offset, ivsize;
+	dma_addr_t addr_iv = 0, addr_key = 0;
 	void *backup_iv = NULL;
+	u32 common, sym;
 	int flow, i;
 	int nr_sgs = 0;
 	int nr_sgd = 0;
@@ -115,28 +117,31 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 	cet = chan->tl;
 	memset(cet, 0, sizeof(struct ce_task));
 
-	cet->t_id = flow;
-	cet->t_common_ctl = ce->variant->alg_cipher[algt->ce_algo_id];
-	cet->t_common_ctl |= rctx->op_dir | CE_COMM_INT;
-	cet->t_dlen = areq->cryptlen / 4;
+	cet->t_id = cpu_to_le32(flow);
+	common = ce->variant->alg_cipher[algt->ce_algo_id];
+	common |= rctx->op_dir | CE_COMM_INT;
+	cet->t_common_ctl = cpu_to_le32(common);
 	/* CTS and recent CE (H6) need length in bytes, in word otherwise */
 	if (ce->variant->has_t_dlen_in_bytes)
-		cet->t_dlen = areq->cryptlen;
+		cet->t_dlen = cpu_to_le32(areq->cryptlen);
+	else
+		cet->t_dlen = cpu_to_le32(areq->cryptlen / 4);
 
-	cet->t_sym_ctl = ce->variant->op_mode[algt->ce_blockmode];
+	sym = ce->variant->op_mode[algt->ce_blockmode];
 	len = op->keylen;
 	switch (len) {
 	case 128 / 8:
-		cet->t_sym_ctl |= CE_AES_128BITS;
+		sym |= CE_AES_128BITS;
 		break;
 	case 192 / 8:
-		cet->t_sym_ctl |= CE_AES_192BITS;
+		sym |= CE_AES_192BITS;
 		break;
 	case 256 / 8:
-		cet->t_sym_ctl |= CE_AES_256BITS;
+		sym |= CE_AES_256BITS;
 		break;
 	}
 
+	cet->t_sym_ctl = cpu_to_le32(sym);
 	cet->t_asym_ctl = 0;
 
 	chan->op_mode = ce->variant->op_mode[algt->ce_blockmode];
@@ -144,9 +149,9 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 	chan->method = ce->variant->alg_cipher[algt->ce_algo_id];
 	chan->keylen = op->keylen;
 
-	cet->t_key = dma_map_single(ce->dev, op->key, op->keylen,
-				    DMA_TO_DEVICE);
-	if (dma_mapping_error(ce->dev, cet->t_key)) {
+	addr_key = dma_map_single(ce->dev, op->key, op->keylen, DMA_TO_DEVICE);
+	cet->t_key = cpu_to_le32(addr_key);
+	if (dma_mapping_error(ce->dev, addr_key)) {
 		dev_err(ce->dev, "Cannot DMA MAP KEY\n");
 		err = -EFAULT;
 		goto theend;
@@ -171,9 +176,10 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 						 ivsize, 0);
 		}
 		memcpy(chan->bounce_iv, areq->iv, ivsize);
-		cet->t_iv = dma_map_single(ce->dev, chan->bounce_iv,
-					   chan->ivlen, DMA_TO_DEVICE);
-		if (dma_mapping_error(ce->dev, cet->t_iv)) {
+		addr_iv = dma_map_single(ce->dev, chan->bounce_iv, chan->ivlen,
+					 DMA_TO_DEVICE);
+		cet->t_iv = cpu_to_le32(addr_iv);
+		if (dma_mapping_error(ce->dev, addr_iv)) {
 			dev_err(ce->dev, "Cannot DMA MAP IV\n");
 			err = -ENOMEM;
 			goto theend_iv;
@@ -208,9 +214,9 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 
 	len = areq->cryptlen;
 	for_each_sg(areq->src, sg, nr_sgs, i) {
-		cet->t_src[i].addr = sg_dma_address(sg);
+		cet->t_src[i].addr = cpu_to_le32(sg_dma_address(sg));
 		todo = min(len, sg_dma_len(sg));
-		cet->t_src[i].len = todo / 4;
+		cet->t_src[i].len = cpu_to_le32(todo / 4);
 		dev_dbg(ce->dev, "%s total=%u SG(%d %u off=%d) todo=%u\n", __func__,
 			areq->cryptlen, i, cet->t_src[i].len, sg->offset, todo);
 		len -= todo;
@@ -223,9 +229,9 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 
 	len = areq->cryptlen;
 	for_each_sg(areq->dst, sg, nr_sgd, i) {
-		cet->t_dst[i].addr = sg_dma_address(sg);
+		cet->t_dst[i].addr = cpu_to_le32(sg_dma_address(sg));
 		todo = min(len, sg_dma_len(sg));
-		cet->t_dst[i].len = todo / 4;
+		cet->t_dst[i].len = cpu_to_le32(todo / 4);
 		dev_dbg(ce->dev, "%s total=%u SG(%d %u off=%d) todo=%u\n", __func__,
 			areq->cryptlen, i, cet->t_dst[i].len, sg->offset, todo);
 		len -= todo;
@@ -250,8 +256,8 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 
 theend_iv:
 	if (areq->iv && ivsize > 0) {
-		if (cet->t_iv)
-			dma_unmap_single(ce->dev, cet->t_iv, chan->ivlen,
+		if (addr_iv)
+			dma_unmap_single(ce->dev, addr_iv, chan->ivlen,
 					 DMA_TO_DEVICE);
 		offset = areq->cryptlen - ivsize;
 		if (rctx->op_dir & CE_DECRYPTION) {
@@ -265,7 +271,7 @@ static int sun8i_ce_cipher(struct skcipher_request *areq)
 	}
 
 theend_key:
-	dma_unmap_single(ce->dev, cet->t_key, op->keylen, DMA_TO_DEVICE);
+	dma_unmap_single(ce->dev, addr_key, op->keylen, DMA_TO_DEVICE);
 
 theend:
 	return err;
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
index c6ddad3393ed..43db49ceafe4 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
@@ -103,8 +103,8 @@ struct ce_variant {
 };
 
 struct sginfo {
-	u32 addr;
-	u32 len;
+	__le32 addr;
+	__le32 len;
 } __packed;
 
 /*
@@ -112,18 +112,18 @@ struct sginfo {
  * The structure of this descriptor could be found in the datasheet
  */
 struct ce_task {
-	u32 t_id;
-	u32 t_common_ctl;
-	u32 t_sym_ctl;
-	u32 t_asym_ctl;
-	u32 t_key;
-	u32 t_iv;
-	u32 t_ctr;
-	u32 t_dlen;
+	__le32 t_id;
+	__le32 t_common_ctl;
+	__le32 t_sym_ctl;
+	__le32 t_asym_ctl;
+	__le32 t_key;
+	__le32 t_iv;
+	__le32 t_ctr;
+	__le32 t_dlen;
 	struct sginfo t_src[MAX_SG];
 	struct sginfo t_dst[MAX_SG];
-	u32 next;
-	u32 reserved[3];
+	__le32 next;
+	__le32 reserved[3];
 } __packed __aligned(8);
 
 /*
-- 
2.23.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

             reply	other threads:[~2019-11-17 16:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-17 16:07 Corentin Labbe [this message]
2019-11-17 16:07 ` [PATCH] crypto: allwinner: sun8i-ce: enable working on big endian Corentin Labbe
2019-11-22 11:10 ` Herbert Xu
2019-11-22 11:10   ` Herbert Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191117160745.32197-1-clabbe.montjoie@gmail.com \
    --to=clabbe.montjoie@gmail.com \
    --cc=davem@davemloft.net \
    --cc=herbert@gondor.apana.org.au \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=mripard@kernel.org \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.