Commit e66862e6 authored by Corentin Labbe's avatar Corentin Labbe Committed by Herbert Xu

crypto: sun8i-ce - handle different error registers

Error registers are different across SoCs.
This patch handle those difference.
Signed-off-by: default avatarCorentin Labbe <clabbe@baylibre.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 0605fa0f
...@@ -40,7 +40,8 @@ static const struct ce_variant ce_h3_variant = { ...@@ -40,7 +40,8 @@ static const struct ce_variant ce_h3_variant = {
.ce_clks = { .ce_clks = {
{ "bus", 0, 200000000 }, { "bus", 0, 200000000 },
{ "mod", 50000000, 0 }, { "mod", 50000000, 0 },
} },
.esr = ESR_H3,
}; };
static const struct ce_variant ce_h5_variant = { static const struct ce_variant ce_h5_variant = {
...@@ -51,7 +52,8 @@ static const struct ce_variant ce_h5_variant = { ...@@ -51,7 +52,8 @@ static const struct ce_variant ce_h5_variant = {
.ce_clks = { .ce_clks = {
{ "bus", 0, 200000000 }, { "bus", 0, 200000000 },
{ "mod", 300000000, 0 }, { "mod", 300000000, 0 },
} },
.esr = ESR_H5,
}; };
static const struct ce_variant ce_h6_variant = { static const struct ce_variant ce_h6_variant = {
...@@ -64,7 +66,8 @@ static const struct ce_variant ce_h6_variant = { ...@@ -64,7 +66,8 @@ static const struct ce_variant ce_h6_variant = {
{ "bus", 0, 200000000 }, { "bus", 0, 200000000 },
{ "mod", 300000000, 0 }, { "mod", 300000000, 0 },
{ "ram", 0, 400000000 }, { "ram", 0, 400000000 },
} },
.esr = ESR_H6,
}; };
static const struct ce_variant ce_a64_variant = { static const struct ce_variant ce_a64_variant = {
...@@ -75,7 +78,8 @@ static const struct ce_variant ce_a64_variant = { ...@@ -75,7 +78,8 @@ static const struct ce_variant ce_a64_variant = {
.ce_clks = { .ce_clks = {
{ "bus", 0, 200000000 }, { "bus", 0, 200000000 },
{ "mod", 300000000, 0 }, { "mod", 300000000, 0 },
} },
.esr = ESR_A64,
}; };
static const struct ce_variant ce_r40_variant = { static const struct ce_variant ce_r40_variant = {
...@@ -86,7 +90,8 @@ static const struct ce_variant ce_r40_variant = { ...@@ -86,7 +90,8 @@ static const struct ce_variant ce_r40_variant = {
.ce_clks = { .ce_clks = {
{ "bus", 0, 200000000 }, { "bus", 0, 200000000 },
{ "mod", 300000000, 0 }, { "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) ...@@ -102,6 +107,7 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name)
{ {
u32 v; u32 v;
int err = 0; int err = 0;
struct ce_task *cet = ce->chanlist[flow].tl;
#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
ce->chanlist[flow].stat_req++; ce->chanlist[flow].stat_req++;
...@@ -131,19 +137,56 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) ...@@ -131,19 +137,56 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name)
msecs_to_jiffies(ce->chanlist[flow].timeout)); msecs_to_jiffies(ce->chanlist[flow].timeout));
if (ce->chanlist[flow].status == 0) { 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; err = -EFAULT;
} }
/* No need to lock for this read, the channel is locked so /* No need to lock for this read, the channel is locked so
* nothing could modify the error value for this channel * nothing could modify the error value for this channel
*/ */
v = readl(ce->base + CE_ESR); v = readl(ce->base + CE_ESR);
switch (ce->variant->esr) {
case ESR_H3:
/* Sadly, the error bit is not per flow */
if (v) { 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 >>= (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; v &= 0xFF;
if (v) { if (v) {
dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow); dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
err = -EFAULT; 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) if (v & CE_ERR_ALGO_NOTSUP)
dev_err(ce->dev, "CE ERROR: algorithm not supported\n"); dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
...@@ -153,6 +196,9 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) ...@@ -153,6 +196,9 @@ 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"); dev_err(ce->dev, "CE ERROR: keysram access error for AES\n");
if (v & CE_ERR_ADDR_INVALID) if (v & CE_ERR_ADDR_INVALID)
dev_err(ce->dev, "CE ERROR: address invalid\n"); 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; return err;
......
...@@ -65,6 +65,12 @@ ...@@ -65,6 +65,12 @@
#define CE_ERR_ADDR_INVALID BIT(5) #define CE_ERR_ADDR_INVALID BIT(5)
#define CE_ERR_KEYLADDER BIT(6) #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_SHIFT 16
#define CE_DIE_ID_MASK 0x07 #define CE_DIE_ID_MASK 0x07
...@@ -94,12 +100,14 @@ struct ce_clock { ...@@ -94,12 +100,14 @@ struct ce_clock {
* @has_t_dlen_in_bytes: Does the request size for cipher is in * @has_t_dlen_in_bytes: Does the request size for cipher is in
* bytes or words * bytes or words
* @ce_clks: list of clocks needed by this variant * @ce_clks: list of clocks needed by this variant
* @esr: The type of error register
*/ */
struct ce_variant { struct ce_variant {
char alg_cipher[CE_ID_CIPHER_MAX]; char alg_cipher[CE_ID_CIPHER_MAX];
u32 op_mode[CE_ID_OP_MAX]; u32 op_mode[CE_ID_OP_MAX];
bool has_t_dlen_in_bytes; bool has_t_dlen_in_bytes;
struct ce_clock ce_clks[CE_MAX_CLOCKS]; struct ce_clock ce_clks[CE_MAX_CLOCKS];
int esr;
}; };
struct sginfo { struct sginfo {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment