diff options
author | Steve Cornelius <steve.cornelius@freescale.com> | 2014-11-17 11:24:14 -0700 |
---|---|---|
committer | Nitin Garg <nitin.garg@nxp.com> | 2016-01-20 14:28:45 -0600 |
commit | 8a7d9a5cd4cd80920eed9b3594e5b20202a3d337 (patch) | |
tree | 6cff9d0e7d649a1e45bf9c158538a97955548020 /drivers/crypto/caam | |
parent | e77b6c56b7bfdd472c3bf9a9e1c810ea262a62bc (diff) |
MLK-9769-22 Detect HW features during alg registration
i.MX6 instantiates a CAAM with a low-power MDHA block, which does not
compute digests larger than 256 bits. Since the driver installs handlers
for hashes longer than 256 bits in several places, added the ability to
read and interpret the CHA version and instantiations registers, and then
only register handlers that it can support.
[<vicki.milhoan@freescale.com>: Edited to include only caamhash changes]
Signed-off-by: Steve Cornelius <steve.cornelius@freescale.com>
Signed-off-by: Victoria Milhoan <vicki.milhoan@freescale.com>
Signed-off-by: Dan Douglass <dan.douglass@freescale.com>
Diffstat (limited to 'drivers/crypto/caam')
-rw-r--r-- | drivers/crypto/caam/caamhash.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c index 40dcfb342e63..7361d51a4995 100644 --- a/drivers/crypto/caam/caamhash.c +++ b/drivers/crypto/caam/caamhash.c @@ -1934,8 +1934,9 @@ static int __init caam_algapi_hash_init(void) struct device_node *dev_node; struct platform_device *pdev; struct device *ctrldev; - void *priv; - int i = 0, err = 0; + struct caam_drv_private *priv; + int i = 0, err = 0, md_limit = 0, md_inst; + u64 cha_inst; dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); if (!dev_node) { @@ -1945,10 +1946,9 @@ static int __init caam_algapi_hash_init(void) } pdev = of_find_device_by_node(dev_node); - if (!pdev) { - of_node_put(dev_node); + of_node_put(dev_node); + if (!pdev) return -ENODEV; - } ctrldev = &pdev->dev; priv = dev_get_drvdata(ctrldev); @@ -1963,11 +1963,25 @@ static int __init caam_algapi_hash_init(void) INIT_LIST_HEAD(&hash_list); - /* register crypto algorithms the device supports */ + /* register algorithms the device supports */ + cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls); + md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; + if (md_inst) { + md_limit = SHA512_DIGEST_SIZE; + if ((rd_reg32(&priv->ctrl->perfmon.cha_id_ls) & CHA_ID_LS_MD_MASK) + == CHA_ID_LS_MD_LP256) /* LP256 limits digest size */ + md_limit = SHA256_DIGEST_SIZE; + } + for (i = 0; i < ARRAY_SIZE(driver_hash); i++) { - /* TODO: check if h/w supports alg */ struct caam_hash_alg *t_alg; + /* If no MD instantiated, or MD too small, skip */ + if ((!md_inst) || + (driver_hash[i].template_ahash.halg.digestsize > + md_limit)) + continue; + /* register hmac version */ t_alg = caam_hash_alloc(&driver_hash[i], true); if (IS_ERR(t_alg)) { |