Error registers are different across SoCs.
This patch handle those difference.

Signed-off-by: Corentin Labbe <cla...@baylibre.com>
---
 .../crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 62 ++++++++++++++++---
 drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h  |  8 +++
 2 files changed, 62 insertions(+), 8 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c 
b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
index b957061424a1..94969f86b967 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
@@ -40,7 +40,8 @@ static const struct ce_variant ce_h3_variant = {
        .ce_clks = {
                { "bus", 0, 200000000 },
                { "mod", 50000000, 0 },
-               }
+               },
+       .esr = ESR_H3,
 };
 
 static const struct ce_variant ce_h5_variant = {
@@ -51,7 +52,8 @@ static const struct ce_variant ce_h5_variant = {
        .ce_clks = {
                { "bus", 0, 200000000 },
                { "mod", 300000000, 0 },
-               }
+               },
+       .esr = ESR_H5,
 };
 
 static const struct ce_variant ce_h6_variant = {
@@ -64,7 +66,8 @@ static const struct ce_variant ce_h6_variant = {
                { "bus", 0, 200000000 },
                { "mod", 300000000, 0 },
                { "ram", 0, 400000000 },
-               }
+               },
+       .esr = ESR_H6,
 };
 
 static const struct ce_variant ce_a64_variant = {
@@ -75,7 +78,8 @@ static const struct ce_variant ce_a64_variant = {
        .ce_clks = {
                { "bus", 0, 200000000 },
                { "mod", 300000000, 0 },
-               }
+               },
+       .esr = ESR_A64,
 };
 
 static const struct ce_variant ce_r40_variant = {
@@ -86,7 +90,8 @@ static const struct ce_variant ce_r40_variant = {
        .ce_clks = {
                { "bus", 0, 200000000 },
                { "mod", 300000000, 0 },
-               }
+               },
+       .esr = ESR_R40,
 };
 
 /*
@@ -102,6 +107,7 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, 
const char *name)
 {
        u32 v;
        int err = 0;
+       struct ce_task *cet = ce->chanlist[flow].tl;
 
 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
        ce->chanlist[flow].stat_req++;
@@ -128,19 +134,56 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, 
const char *name)
                        msecs_to_jiffies(ce->chanlist[flow].timeout));
 
        if (ce->chanlist[flow].status == 0) {
-               dev_err(ce->dev, "DMA timeout for %s\n", name);
+               dev_err(ce->dev, "DMA timeout for %s (tm=%d) on flow %d\n", 
name,
+                       ce->chanlist[flow].timeout, flow);
                err = -EFAULT;
        }
        /* No need to lock for this read, the channel is locked so
         * nothing could modify the error value for this channel
         */
        v = readl(ce->base + CE_ESR);
-       if (v) {
+       switch (ce->variant->esr) {
+       case ESR_H3:
+               /* Sadly, the error bit is not per flow */
+               if (v) {
+                       dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
+                       err = -EFAULT;
+                       print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 
16, 4,
+                                      cet, sizeof(struct ce_task), false);
+               }
+               if (v & CE_ERR_ALGO_NOTSUP)
+                       dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
+               if (v & CE_ERR_DATALEN)
+                       dev_err(ce->dev, "CE ERROR: data length error\n");
+               if (v & CE_ERR_KEYSRAM)
+                       dev_err(ce->dev, "CE ERROR: keysram access error for 
AES\n");
+               break;
+       case ESR_A64:
+       case ESR_H5:
+       case ESR_R40:
                v >>= (flow * 4);
+               v &= 0xF;
+               if (v) {
+                       dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
+                       err = -EFAULT;
+                       print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 
16, 4,
+                                      cet, sizeof(struct ce_task), false);
+               }
+               if (v & CE_ERR_ALGO_NOTSUP)
+                       dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
+               if (v & CE_ERR_DATALEN)
+                       dev_err(ce->dev, "CE ERROR: data length error\n");
+               if (v & CE_ERR_KEYSRAM)
+                       dev_err(ce->dev, "CE ERROR: keysram access error for 
AES\n");
+               break;
+       case ESR_H6:
+               v >>= (flow * 8);
                v &= 0xFF;
                if (v) {
                        dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
                        err = -EFAULT;
+                       print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 
16, 4,
+                                      cet, sizeof(struct ce_task), false);
                }
                if (v & CE_ERR_ALGO_NOTSUP)
                        dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
@@ -150,7 +193,10 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, 
const char *name)
                        dev_err(ce->dev, "CE ERROR: keysram access error for 
AES\n");
                if (v & CE_ERR_ADDR_INVALID)
                        dev_err(ce->dev, "CE ERROR: address invalid\n");
-               }
+               if (v & CE_ERR_KEYLADDER)
+                       dev_err(ce->dev, "CE ERROR: key ladder configuration 
error\n");
+               break;
+       }
 
        return err;
 }
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h 
b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
index fe97fee74e47..ed1a91da967b 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
@@ -65,6 +65,12 @@
 #define CE_ERR_ADDR_INVALID    BIT(5)
 #define CE_ERR_KEYLADDER       BIT(6)
 
+#define ESR_H3 0
+#define ESR_A64        1
+#define ESR_R40        2
+#define ESR_H5 3
+#define ESR_H6 4
+
 #define CE_DIE_ID_SHIFT        16
 #define CE_DIE_ID_MASK 0x07
 
@@ -94,12 +100,14 @@ struct ce_clock {
  * @has_t_dlen_in_bytes:       Does the request size for cipher is in
  *                             bytes or words
  * @ce_clks:   list of clocks needed by this variant
+ * @esr:       The type of error register
  */
 struct ce_variant {
        char alg_cipher[CE_ID_CIPHER_MAX];
        u32 op_mode[CE_ID_OP_MAX];
        bool has_t_dlen_in_bytes;
        struct ce_clock ce_clks[CE_MAX_CLOCKS];
+       int esr;
 };
 
 struct sginfo {
-- 
2.26.2

Reply via email to