]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: sun8i-ce - wrap accesses to descriptor address fields
authorAndre Przywara <andre.przywara@arm.com>
Mon, 24 Jun 2024 23:21:08 +0000 (00:21 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Sat, 6 Jul 2024 00:19:59 +0000 (10:19 +1000)
The Allwinner H616 (and later) SoCs support more than 32 bits worth of
physical addresses. To accommodate the larger address space, the CE task
descriptor fields holding addresses are now encoded as "word addresses",
so take the actual address divided by four.
This is true for the fields within the descriptor, but also for the
descriptor base address, in the CE_TDA register.

Wrap all accesses to those fields in a function, which will do the
required division if needed. For now this in unused, so there should be
no change in behaviour.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c
drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c
drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h

index de50c00ba218fb19302438b6df29f24a38a9c591..19b7fb4a93e86ce71247d326c88618352e459ac6 100644 (file)
@@ -190,7 +190,7 @@ static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req
                err = -EFAULT;
                goto theend;
        }
-       cet->t_key = cpu_to_le32(rctx->addr_key);
+       cet->t_key = desc_addr_val_le32(ce, rctx->addr_key);
 
        ivsize = crypto_skcipher_ivsize(tfm);
        if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
@@ -208,7 +208,7 @@ static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req
                        err = -ENOMEM;
                        goto theend_iv;
                }
-               cet->t_iv = cpu_to_le32(rctx->addr_iv);
+               cet->t_iv = desc_addr_val_le32(ce, rctx->addr_iv);
        }
 
        if (areq->src == areq->dst) {
@@ -236,7 +236,7 @@ static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req
 
        len = areq->cryptlen;
        for_each_sg(areq->src, sg, nr_sgs, i) {
-               cet->t_src[i].addr = cpu_to_le32(sg_dma_address(sg));
+               cet->t_src[i].addr = desc_addr_val_le32(ce, sg_dma_address(sg));
                todo = min(len, sg_dma_len(sg));
                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__,
@@ -251,7 +251,7 @@ static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req
 
        len = areq->cryptlen;
        for_each_sg(areq->dst, sg, nr_sgd, i) {
-               cet->t_dst[i].addr = cpu_to_le32(sg_dma_address(sg));
+               cet->t_dst[i].addr = desc_addr_val_le32(ce, sg_dma_address(sg));
                todo = min(len, sg_dma_len(sg));
                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__,
index 0408b2d5d533b856e8c3add8d5f0a24827b9c8d1..6d45c1e559f7d3c787c3b83fe118b7e2b47fb842 100644 (file)
@@ -172,7 +172,7 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name)
        writel(v, ce->base + CE_ICR);
 
        reinit_completion(&ce->chanlist[flow].complete);
-       writel(ce->chanlist[flow].t_phy, ce->base + CE_TDQ);
+       writel(desc_addr_val(ce, ce->chanlist[flow].t_phy), ce->base + CE_TDQ);
 
        ce->chanlist[flow].status = 0;
        /* Be sure all data is written before enabling the task */
index ee2a28c906edee3d30b4f828ebe83b4a8e915867..6072dd9f390b40a1adfd8bf51dee81d6ccd4e3b1 100644 (file)
@@ -403,7 +403,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
 
        len = areq->nbytes;
        for_each_sg(areq->src, sg, nr_sgs, i) {
-               cet->t_src[i].addr = cpu_to_le32(sg_dma_address(sg));
+               cet->t_src[i].addr = desc_addr_val_le32(ce, sg_dma_address(sg));
                todo = min(len, sg_dma_len(sg));
                cet->t_src[i].len = cpu_to_le32(todo / 4);
                len -= todo;
@@ -414,7 +414,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
                goto theend;
        }
        addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE);
-       cet->t_dst[0].addr = cpu_to_le32(addr_res);
+       cet->t_dst[0].addr = desc_addr_val_le32(ce, addr_res);
        cet->t_dst[0].len = cpu_to_le32(digestsize / 4);
        if (dma_mapping_error(ce->dev, addr_res)) {
                dev_err(ce->dev, "DMA map dest\n");
@@ -445,7 +445,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
        }
 
        addr_pad = dma_map_single(ce->dev, buf, j * 4, DMA_TO_DEVICE);
-       cet->t_src[i].addr = cpu_to_le32(addr_pad);
+       cet->t_src[i].addr = desc_addr_val_le32(ce, addr_pad);
        cet->t_src[i].len = cpu_to_le32(j);
        if (dma_mapping_error(ce->dev, addr_pad)) {
                dev_err(ce->dev, "DMA error on padding SG\n");
index 80815379f6fc5500722426b3b45f240226dc0c47..762459867b6c55c245f196bf256d4039d1a6ecb1 100644 (file)
@@ -132,10 +132,10 @@ int sun8i_ce_prng_generate(struct crypto_rng *tfm, const u8 *src,
        cet->t_sym_ctl = cpu_to_le32(sym);
        cet->t_asym_ctl = 0;
 
-       cet->t_key = cpu_to_le32(dma_iv);
-       cet->t_iv = cpu_to_le32(dma_iv);
+       cet->t_key = desc_addr_val_le32(ce, dma_iv);
+       cet->t_iv = desc_addr_val_le32(ce, dma_iv);
 
-       cet->t_dst[0].addr = cpu_to_le32(dma_dst);
+       cet->t_dst[0].addr = desc_addr_val_le32(ce, dma_dst);
        cet->t_dst[0].len = cpu_to_le32(todo / 4);
        ce->chanlist[flow].timeout = 2000;
 
index 9c35f2a83eda858d39f96c39fc75a5079fe1b33e..e1e8bc15202e0381a238f2d1f449f887cf10b5d0 100644 (file)
@@ -77,7 +77,7 @@ static int sun8i_ce_trng_read(struct hwrng *rng, void *data, size_t max, bool wa
        cet->t_sym_ctl = 0;
        cet->t_asym_ctl = 0;
 
-       cet->t_dst[0].addr = cpu_to_le32(dma_dst);
+       cet->t_dst[0].addr = desc_addr_val_le32(ce, dma_dst);
        cet->t_dst[0].len = cpu_to_le32(todo / 4);
        ce->chanlist[flow].timeout = todo;
 
index 93d4985def87a79ccd24672b669d5c6f039bc6c2..3b5c2af013d0da0dad4f3ed6b9285bcfc333156d 100644 (file)
@@ -149,6 +149,7 @@ struct ce_variant {
        bool hash_t_dlen_in_bits;
        bool prng_t_dlen_in_bytes;
        bool trng_t_dlen_in_bytes;
+       bool needs_word_addresses;
        struct ce_clock ce_clks[CE_MAX_CLOCKS];
        int esr;
        unsigned char prng;
@@ -241,6 +242,20 @@ struct sun8i_ce_dev {
 #endif
 };
 
+static inline u32 desc_addr_val(struct sun8i_ce_dev *dev, dma_addr_t addr)
+{
+       if (dev->variant->needs_word_addresses)
+               return addr / 4;
+
+       return addr;
+}
+
+static inline __le32 desc_addr_val_le32(struct sun8i_ce_dev *dev,
+                                       dma_addr_t addr)
+{
+       return cpu_to_le32(desc_addr_val(dev, addr));
+}
+
 /*
  * struct sun8i_cipher_req_ctx - context for a skcipher request
  * @op_dir:            direction (encrypt vs decrypt) for this request