Skip to content

Commit

Permalink
crypto: caam - handle core endianness != caam endianness
Browse files Browse the repository at this point in the history
There are SoCs like LS1043A where CAAM endianness (BE) does not match
the default endianness of the core (LE).
Moreover, there are requirements for the driver to handle cases like
CPU_BIG_ENDIAN=y on ARM-based SoCs.
This requires for a complete rewrite of the I/O accessors.

PPC-specific accessors - {in,out}_{le,be}XX - are replaced with
generic ones - io{read,write}[be]XX.

Endianness is detected dynamically (at runtime) to allow for
multiplatform kernels, for e.g. running the same kernel image
on LS1043A (BE CAAM) and LS2080A (LE CAAM) armv8-based SoCs.

While here: debugfs entries need to take into consideration the
endianness of the core when displaying data. Add the necessary
glue code so the entries remain the same, but they are properly
read, regardless of the core and/or SEC endianness.

Note: pdb.h fixes only what is currently being used (IPsec).

Reviewed-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Alex Porosanu <alexandru.porosanu@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
Horia Geantă authored and Herbert Xu committed May 31, 2016
1 parent bd52f1c commit 261ea05
Show file tree
Hide file tree
Showing 9 changed files with 340 additions and 166 deletions.
4 changes: 0 additions & 4 deletions drivers/crypto/caam/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,6 @@ config CRYPTO_DEV_FSL_CAAM_IMX
def_bool SOC_IMX6 || SOC_IMX7D
depends on CRYPTO_DEV_FSL_CAAM

config CRYPTO_DEV_FSL_CAAM_LE
def_bool CRYPTO_DEV_FSL_CAAM_IMX || SOC_LS1021A
depends on CRYPTO_DEV_FSL_CAAM

config CRYPTO_DEV_FSL_CAAM_DEBUG
bool "Enable debug output in CAAM driver"
depends on CRYPTO_DEV_FSL_CAAM
Expand Down
5 changes: 3 additions & 2 deletions drivers/crypto/caam/caamhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ static int ahash_update_ctx(struct ahash_request *req)
*next_buflen, 0);
} else {
(edesc->sec4_sg + sec4_sg_src_index - 1)->len |=
SEC4_SG_LEN_FIN;
cpu_to_caam32(SEC4_SG_LEN_FIN);
}

state->current_buf = !state->current_buf;
Expand Down Expand Up @@ -949,7 +949,8 @@ static int ahash_final_ctx(struct ahash_request *req)
state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg + 1,
buf, state->buf_dma, buflen,
last_buflen);
(edesc->sec4_sg + sec4_sg_src_index - 1)->len |= SEC4_SG_LEN_FIN;
(edesc->sec4_sg + sec4_sg_src_index - 1)->len |=
cpu_to_caam32(SEC4_SG_LEN_FIN);

edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE);
Expand Down
125 changes: 80 additions & 45 deletions drivers/crypto/caam/ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#include "desc_constr.h"
#include "error.h"

bool caam_little_end;
EXPORT_SYMBOL(caam_little_end);

/*
* i.MX targets tend to have clock control subsystems that can
* enable/disable clocking to our device.
Expand Down Expand Up @@ -106,7 +109,7 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,


if (ctrlpriv->virt_en == 1) {
setbits32(&ctrl->deco_rsr, DECORSR_JR0);
clrsetbits_32(&ctrl->deco_rsr, 0, DECORSR_JR0);

while (!(rd_reg32(&ctrl->deco_rsr) & DECORSR_VALID) &&
--timeout)
Expand All @@ -115,20 +118,20 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
timeout = 100000;
}

setbits32(&ctrl->deco_rq, DECORR_RQD0ENABLE);
clrsetbits_32(&ctrl->deco_rq, 0, DECORR_RQD0ENABLE);

while (!(rd_reg32(&ctrl->deco_rq) & DECORR_DEN0) &&
--timeout)
cpu_relax();

if (!timeout) {
dev_err(ctrldev, "failed to acquire DECO 0\n");
clrbits32(&ctrl->deco_rq, DECORR_RQD0ENABLE);
clrsetbits_32(&ctrl->deco_rq, DECORR_RQD0ENABLE, 0);
return -ENODEV;
}

for (i = 0; i < desc_len(desc); i++)
wr_reg32(&deco->descbuf[i], *(desc + i));
wr_reg32(&deco->descbuf[i], caam32_to_cpu(*(desc + i)));

flags = DECO_JQCR_WHL;
/*
Expand All @@ -139,7 +142,7 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
flags |= DECO_JQCR_FOUR;

/* Instruct the DECO to execute it */
setbits32(&deco->jr_ctl_hi, flags);
clrsetbits_32(&deco->jr_ctl_hi, 0, flags);

timeout = 10000000;
do {
Expand All @@ -158,10 +161,10 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
DECO_OP_STATUS_HI_ERR_MASK;

if (ctrlpriv->virt_en == 1)
clrbits32(&ctrl->deco_rsr, DECORSR_JR0);
clrsetbits_32(&ctrl->deco_rsr, DECORSR_JR0, 0);

/* Mark the DECO as free */
clrbits32(&ctrl->deco_rq, DECORR_RQD0ENABLE);
clrsetbits_32(&ctrl->deco_rq, DECORR_RQD0ENABLE, 0);

if (!timeout)
return -EAGAIN;
Expand Down Expand Up @@ -349,7 +352,7 @@ static void kick_trng(struct platform_device *pdev, int ent_delay)
r4tst = &ctrl->r4tst[0];

/* put RNG4 into program mode */
setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
clrsetbits_32(&r4tst->rtmctl, 0, RTMCTL_PRGM);

/*
* Performance-wise, it does not make sense to
Expand All @@ -363,7 +366,7 @@ static void kick_trng(struct platform_device *pdev, int ent_delay)
>> RTSDCTL_ENT_DLY_SHIFT;
if (ent_delay <= val) {
/* put RNG4 into run mode */
clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
clrsetbits_32(&r4tst->rtmctl, RTMCTL_PRGM, 0);
return;
}

Expand All @@ -381,9 +384,9 @@ static void kick_trng(struct platform_device *pdev, int ent_delay)
* select raw sampling in both entropy shifter
* and statistical checker
*/
setbits32(&val, RTMCTL_SAMP_MODE_RAW_ES_SC);
clrsetbits_32(&val, 0, RTMCTL_SAMP_MODE_RAW_ES_SC);
/* put RNG4 into run mode */
clrbits32(&val, RTMCTL_PRGM);
clrsetbits_32(&val, RTMCTL_PRGM, 0);
/* write back the control register */
wr_reg32(&r4tst->rtmctl, val);
}
Expand All @@ -406,6 +409,23 @@ int caam_get_era(void)
}
EXPORT_SYMBOL(caam_get_era);

#ifdef CONFIG_DEBUG_FS
static int caam_debugfs_u64_get(void *data, u64 *val)
{
*val = caam64_to_cpu(*(u64 *)data);
return 0;
}

static int caam_debugfs_u32_get(void *data, u64 *val)
{
*val = caam32_to_cpu(*(u32 *)data);
return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(caam_fops_u32_ro, caam_debugfs_u32_get, NULL, "%llu\n");
DEFINE_SIMPLE_ATTRIBUTE(caam_fops_u64_ro, caam_debugfs_u64_get, NULL, "%llu\n");
#endif

/* Probe routine for CAAM top (controller) level */
static int caam_probe(struct platform_device *pdev)
{
Expand Down Expand Up @@ -504,6 +524,10 @@ static int caam_probe(struct platform_device *pdev)
ret = -ENOMEM;
goto disable_caam_emi_slow;
}

caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) &
(CSTA_PLEND | CSTA_ALT_PLEND));

/* Finding the page size for using the CTPR_MS register */
comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms);
pg_size = (comp_params & CTPR_MS_PG_SZ_MASK) >> CTPR_MS_PG_SZ_SHIFT;
Expand Down Expand Up @@ -559,9 +583,9 @@ static int caam_probe(struct platform_device *pdev)
}

if (ctrlpriv->virt_en == 1)
setbits32(&ctrl->jrstart, JRSTART_JR0_START |
JRSTART_JR1_START | JRSTART_JR2_START |
JRSTART_JR3_START);
clrsetbits_32(&ctrl->jrstart, 0, JRSTART_JR0_START |
JRSTART_JR1_START | JRSTART_JR2_START |
JRSTART_JR3_START);

if (sizeof(dma_addr_t) == sizeof(u64))
if (of_device_is_compatible(nprop, "fsl,sec-v5.0"))
Expand Down Expand Up @@ -693,7 +717,7 @@ static int caam_probe(struct platform_device *pdev)
ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK;

/* Enable RDB bit so that RNG works faster */
setbits32(&ctrl->scfgr, SCFGR_RDBENABLE);
clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
}

/* NOTE: RTIC detection ought to go here, around Si time */
Expand All @@ -719,48 +743,59 @@ static int caam_probe(struct platform_device *pdev)
ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root);

/* Controller-level - performance monitor counters */

ctrlpriv->ctl_rq_dequeued =
debugfs_create_u64("rq_dequeued",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->req_dequeued);
debugfs_create_file("rq_dequeued",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->req_dequeued,
&caam_fops_u64_ro);
ctrlpriv->ctl_ob_enc_req =
debugfs_create_u64("ob_rq_encrypted",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ob_enc_req);
debugfs_create_file("ob_rq_encrypted",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ob_enc_req,
&caam_fops_u64_ro);
ctrlpriv->ctl_ib_dec_req =
debugfs_create_u64("ib_rq_decrypted",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ib_dec_req);
debugfs_create_file("ib_rq_decrypted",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ib_dec_req,
&caam_fops_u64_ro);
ctrlpriv->ctl_ob_enc_bytes =
debugfs_create_u64("ob_bytes_encrypted",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ob_enc_bytes);
debugfs_create_file("ob_bytes_encrypted",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ob_enc_bytes,
&caam_fops_u64_ro);
ctrlpriv->ctl_ob_prot_bytes =
debugfs_create_u64("ob_bytes_protected",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ob_prot_bytes);
debugfs_create_file("ob_bytes_protected",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ob_prot_bytes,
&caam_fops_u64_ro);
ctrlpriv->ctl_ib_dec_bytes =
debugfs_create_u64("ib_bytes_decrypted",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ib_dec_bytes);
debugfs_create_file("ib_bytes_decrypted",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ib_dec_bytes,
&caam_fops_u64_ro);
ctrlpriv->ctl_ib_valid_bytes =
debugfs_create_u64("ib_bytes_validated",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ib_valid_bytes);
debugfs_create_file("ib_bytes_validated",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->ib_valid_bytes,
&caam_fops_u64_ro);

/* Controller level - global status values */
ctrlpriv->ctl_faultaddr =
debugfs_create_u64("fault_addr",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->faultaddr);
debugfs_create_file("fault_addr",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->faultaddr,
&caam_fops_u32_ro);
ctrlpriv->ctl_faultdetail =
debugfs_create_u32("fault_detail",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->faultdetail);
debugfs_create_file("fault_detail",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->faultdetail,
&caam_fops_u32_ro);
ctrlpriv->ctl_faultstatus =
debugfs_create_u32("fault_status",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->status);
debugfs_create_file("fault_status",
S_IRUSR | S_IRGRP | S_IROTH,
ctrlpriv->ctl, &perfmon->status,
&caam_fops_u32_ro);

/* Internal covering keys (useful in non-secure mode only) */
ctrlpriv->ctl_kek_wrap.data = &ctrlpriv->ctrl->kek[0];
Expand Down
7 changes: 3 additions & 4 deletions drivers/crypto/caam/desc.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,15 @@
#define SEC4_SG_OFFSET_MASK 0x00001fff

struct sec4_sg_entry {
#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX
#if !defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) && \
defined(CONFIG_CRYPTO_DEV_FSL_CAAM_IMX)
u32 rsvd1;
dma_addr_t ptr;
#else
u64 ptr;
#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_IMX */
u32 len;
u8 rsvd2;
u8 buf_pool_id;
u16 offset;
u32 bpid_offset;
};

/* Max size of any CAAM descriptor in 32-bit words, inclusive of header */
Expand Down
Loading

0 comments on commit 261ea05

Please sign in to comment.