crypto: starfive - RSA poll csr for done status
authorJia Jie Ho <jiajie.ho@starfivetech.com>
Tue, 14 Nov 2023 17:12:14 +0000 (01:12 +0800)
committerJaehoon Chung <jh80.chung@samsung.com>
Mon, 19 Feb 2024 00:14:00 +0000 (09:14 +0900)
Hardware could not clear irq status without resetting the entire module.
Driver receives irq immediately when mask bit is cleared causing
intermittent errors in RSA calculations. Switch to use csr polling for
done status instead.

Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
(cherry picked from mainline commit ba6e3ee4f5d6c13e984f8cb5fb1706ca39ff4a0e)
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
Change-Id: Ic3ed68e8390f6e9ca171f601a36e2641bc94720f

drivers/crypto/starfive/jh7110-cryp.c
drivers/crypto/starfive/jh7110-cryp.h
drivers/crypto/starfive/jh7110-rsa.c

index 4f5b681..425fddf 100644 (file)
@@ -109,12 +109,6 @@ static irqreturn_t starfive_cryp_irq(int irq, void *priv)
                tasklet_schedule(&cryp->hash_done);
        }
 
-       if (status & STARFIVE_IE_FLAG_PKA_DONE) {
-               mask |= STARFIVE_IE_MASK_PKA_DONE;
-               writel(mask, cryp->base + STARFIVE_IE_MASK_OFFSET);
-               complete(&cryp->pka_done);
-       }
-
        return IRQ_HANDLED;
 }
 
@@ -159,8 +153,6 @@ static int starfive_cryp_probe(struct platform_device *pdev)
                return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
                                     "Error getting hardware reset line\n");
 
-       init_completion(&cryp->pka_done);
-
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
                return irq;
index fe011d5..8510f8c 100644 (file)
@@ -125,6 +125,15 @@ union starfive_pka_cacr {
        };
 };
 
+union starfive_pka_casr {
+       u32 v;
+       struct {
+#define STARFIVE_PKA_DONE                      BIT(0)
+               u32 done                        :1;
+               u32 rsvd_0                      :31;
+       };
+};
+
 struct starfive_rsa_key {
        u8      *n;
        u8      *e;
@@ -183,7 +192,6 @@ struct starfive_cryp_dev {
        struct crypto_engine                    *engine;
        struct tasklet_struct                   aes_done;
        struct tasklet_struct                   hash_done;
-       struct completion                       pka_done;
        size_t                                  assoclen;
        size_t                                  total_in;
        size_t                                  total_out;
index f31bbd8..c2b1f59 100644 (file)
@@ -6,13 +6,7 @@
  */
 
 #include <linux/crypto.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-direct.h>
-#include <linux/interrupt.h>
 #include <linux/iopoll.h>
-#include <linux/io.h>
-#include <linux/mod_devicetable.h>
 #include <crypto/akcipher.h>
 #include <crypto/algapi.h>
 #include <crypto/internal/akcipher.h>
 #define STARFIVE_PKA_CAER_OFFSET       (STARFIVE_PKA_REGS_OFFSET + 0x108)
 #define STARFIVE_PKA_CANR_OFFSET       (STARFIVE_PKA_REGS_OFFSET + 0x208)
 
-// R^2 mod N and N0'
+/* R ^ 2 mod N and N0' */
 #define CRYPTO_CMD_PRE                 0x0
-// A * R mod N   ==> A
+/* A * R mod N   ==> A */
 #define CRYPTO_CMD_ARN                 0x5
-// A * E * R mod N ==> A
+/* A * E * R mod N ==> A */
 #define CRYPTO_CMD_AERN                        0x6
-// A * A * R mod N ==> A
+/* A * A * R mod N ==> A */
 #define CRYPTO_CMD_AARN                        0x7
 
 #define STARFIVE_RSA_MAX_KEYSZ         256
 static inline int starfive_pka_wait_done(struct starfive_cryp_ctx *ctx)
 {
        struct starfive_cryp_dev *cryp = ctx->cryp;
+       u32 status;
 
-       return wait_for_completion_timeout(&cryp->pka_done,
-                                          usecs_to_jiffies(100000));
-}
-
-static inline void starfive_pka_irq_mask_clear(struct starfive_cryp_ctx *ctx)
-{
-       struct starfive_cryp_dev *cryp = ctx->cryp;
-       u32 stat;
-
-       stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET);
-       stat &= ~STARFIVE_IE_MASK_PKA_DONE;
-       writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET);
-
-       reinit_completion(&cryp->pka_done);
+       return readl_relaxed_poll_timeout(cryp->base + STARFIVE_PKA_CASR_OFFSET, status,
+                                         status & STARFIVE_PKA_DONE, 10, 100000);
 }
 
 static void starfive_rsa_free_key(struct starfive_rsa_key *key)
@@ -114,10 +97,9 @@ static int starfive_rsa_montgomery_form(struct starfive_cryp_ctx *ctx,
                rctx->csr.pka.not_r2 = 1;
                rctx->csr.pka.ie = 1;
 
-               starfive_pka_irq_mask_clear(ctx);
                writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
 
-               if (!starfive_pka_wait_done(ctx))
+               if (starfive_pka_wait_done(ctx))
                        return -ETIMEDOUT;
 
                for (loop = 0; loop <= opsize; loop++)
@@ -136,10 +118,9 @@ static int starfive_rsa_montgomery_form(struct starfive_cryp_ctx *ctx,
                rctx->csr.pka.start = 1;
                rctx->csr.pka.ie = 1;
 
-               starfive_pka_irq_mask_clear(ctx);
                writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
 
-               if (!starfive_pka_wait_done(ctx))
+               if (starfive_pka_wait_done(ctx))
                        return -ETIMEDOUT;
        } else {
                rctx->csr.pka.v = 0;
@@ -151,10 +132,9 @@ static int starfive_rsa_montgomery_form(struct starfive_cryp_ctx *ctx,
                rctx->csr.pka.pre_expf = 1;
                rctx->csr.pka.ie = 1;
 
-               starfive_pka_irq_mask_clear(ctx);
                writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
 
-               if (!starfive_pka_wait_done(ctx))
+               if (starfive_pka_wait_done(ctx))
                        return -ETIMEDOUT;
 
                for (loop = 0; loop <= count; loop++)
@@ -172,10 +152,9 @@ static int starfive_rsa_montgomery_form(struct starfive_cryp_ctx *ctx,
                rctx->csr.pka.start = 1;
                rctx->csr.pka.ie = 1;
 
-               starfive_pka_irq_mask_clear(ctx);
                writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
 
-               if (!starfive_pka_wait_done(ctx))
+               if (starfive_pka_wait_done(ctx))
                        return -ETIMEDOUT;
        }
 
@@ -226,11 +205,10 @@ static int starfive_rsa_cpu_start(struct starfive_cryp_ctx *ctx, u32 *result,
                rctx->csr.pka.start = 1;
                rctx->csr.pka.ie = 1;
 
-               starfive_pka_irq_mask_clear(ctx);
                writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
 
                ret = -ETIMEDOUT;
-               if (!starfive_pka_wait_done(ctx))
+               if (starfive_pka_wait_done(ctx))
                        goto rsa_err;
 
                if (mlen) {
@@ -242,10 +220,9 @@ static int starfive_rsa_cpu_start(struct starfive_cryp_ctx *ctx, u32 *result,
                        rctx->csr.pka.start = 1;
                        rctx->csr.pka.ie = 1;
 
-                       starfive_pka_irq_mask_clear(ctx);
                        writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
 
-                       if (!starfive_pka_wait_done(ctx))
+                       if (starfive_pka_wait_done(ctx))
                                goto rsa_err;
                }
        }