mirror of https://gitee.com/openkylin/linux.git
crypto: sun8i-ce - handle different error registers
Error registers are different across SoCs. This patch handle those difference. Signed-off-by: Corentin Labbe <clabbe@baylibre.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
0605fa0f78
commit
e66862e6db
|
@ -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++;
|
||||
|
@ -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));
|
||||
|
||||
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");
|
||||
|
@ -153,7 +196,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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue