summaryrefslogtreecommitdiff
path: root/drivers/crypto/inside-secure/safexcel.c
diff options
context:
space:
mode:
authorPascal van Leeuwen <pascalvanl@gmail.com>2019-12-11 19:32:35 +0300
committerHerbert Xu <herbert@gondor.apana.org.au>2019-12-20 09:58:33 +0300
commit098e51e517bc2e5865c520f3eee8bf83dd320e61 (patch)
treed178bc98e13d412c0bdad67dd2ed7d81303f7775 /drivers/crypto/inside-secure/safexcel.c
parenta30637625822e42f67a6a537147b978551288daf (diff)
downloadlinux-098e51e517bc2e5865c520f3eee8bf83dd320e61.tar.xz
crypto: inside-secure - Fix Unable to fit even 1 command desc error w/ EIP97
Due to the additions of support for modes like AES-CCM and AES-GCM, which require large command tokens, the size of the descriptor has grown such that it now does not fit into the descriptor cache of a standard EIP97 anymore. This means that the driver no longer works on the Marvell Armada 3700LP chip (as used on e.g. Espressobin) that it has always supported. Additionally, performance on EIP197's like Marvell A8K may also degrade due to being able to fit less descriptors in the on-chip cache. Putting these tokens into the descriptor was really a hack and not how the design was supposed to be used - resource allocation did not account for it. So what this patch does, is move the command token out of the descriptor. To avoid having to allocate buffers on the fly for these command tokens, they are stuffed in a "shadow ring", which is a circular buffer of fixed size blocks that runs in lock-step with the descriptor ring. i.e. there is one token block per descriptor. The descriptor ring itself is then pre- populated with the pointers to these token blocks so these do not need to be filled in when building the descriptors later. Signed-off-by: Pascal van Leeuwen <pvanleeuwen@rambus.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/inside-secure/safexcel.c')
-rw-r--r--drivers/crypto/inside-secure/safexcel.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
index 64894d8b442a..2cb53fbae841 100644
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -501,8 +501,8 @@ static int safexcel_hw_setup_cdesc_rings(struct safexcel_crypto_priv *priv)
writel(upper_32_bits(priv->ring[i].cdr.base_dma),
EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_RING_BASE_ADDR_HI);
- writel(EIP197_xDR_DESC_MODE_64BIT | (priv->config.cd_offset << 14) |
- priv->config.cd_size,
+ writel(EIP197_xDR_DESC_MODE_64BIT | EIP197_CDR_DESC_MODE_ADCP |
+ (priv->config.cd_offset << 14) | priv->config.cd_size,
EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_DESC_SIZE);
writel(((cd_fetch_cnt *
(cd_size_rnd << priv->hwconfig.hwdataw)) << 16) |
@@ -974,16 +974,18 @@ int safexcel_invalidate_cache(struct crypto_async_request *async,
{
struct safexcel_command_desc *cdesc;
struct safexcel_result_desc *rdesc;
+ struct safexcel_token *dmmy;
int ret = 0;
/* Prepare command descriptor */
- cdesc = safexcel_add_cdesc(priv, ring, true, true, 0, 0, 0, ctxr_dma);
+ cdesc = safexcel_add_cdesc(priv, ring, true, true, 0, 0, 0, ctxr_dma,
+ &dmmy);
if (IS_ERR(cdesc))
return PTR_ERR(cdesc);
cdesc->control_data.type = EIP197_TYPE_EXTENDED;
cdesc->control_data.options = 0;
- cdesc->control_data.refresh = 0;
+ cdesc->control_data.context_lo &= ~EIP197_CONTEXT_SIZE_MASK;
cdesc->control_data.control0 = CONTEXT_CONTROL_INV_TR;
/* Prepare result descriptor */
@@ -1331,6 +1333,7 @@ static void safexcel_configure(struct safexcel_crypto_priv *priv)
priv->config.cd_size = EIP197_CD64_FETCH_SIZE;
priv->config.cd_offset = (priv->config.cd_size + mask) & ~mask;
+ priv->config.cdsh_offset = (EIP197_MAX_TOKENS + mask) & ~mask;
/* res token is behind the descr, but ofs must be rounded to buswdth */
priv->config.res_offset = (EIP197_RD64_FETCH_SIZE + mask) & ~mask;
@@ -1341,6 +1344,7 @@ static void safexcel_configure(struct safexcel_crypto_priv *priv)
/* convert dwords to bytes */
priv->config.cd_offset *= sizeof(u32);
+ priv->config.cdsh_offset *= sizeof(u32);
priv->config.rd_offset *= sizeof(u32);
priv->config.res_offset *= sizeof(u32);
}