crypto: inside-secure - Add support for HW with less ring AIC's than rings
authorPascal van Leeuwen <pascalvanl@gmail.com>
Wed, 18 Sep 2019 06:42:40 +0000 (08:42 +0200)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 4 Oct 2019 15:06:17 +0000 (01:06 +1000)
The current driver assumes one dedicated ring interrupt controller per
ring. However, some existing EIP(1)97 HW has less ring AIC's than rings.
This patch allows the driver to work with such HW by detecting how many
ring AIC's are present and restricting the number of rings it *uses* by
the number of ring AIC's present. This allows it to at least function.
(optimization for the future: add ring dispatch functionality in the
interrupt service routine such that multiple rings can be supported from
one ring AIC, allowing all rings to be used)

Signed-off-by: Pascal van Leeuwen <pvanleeuwen@verimatrix.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/inside-secure/safexcel.c
drivers/crypto/inside-secure/safexcel.h

index 0bcf36c3810b8d0dd0621053bd3e03b5fcf9be95..c40eb1befc51d13ca6837deff6165b80a419b0e5 100644 (file)
@@ -1308,6 +1308,9 @@ static void safexcel_configure(struct safexcel_crypto_priv *priv)
 
        priv->config.pes = priv->hwconfig.hwnumpes;
        priv->config.rings = min_t(u32, priv->hwconfig.hwnumrings, max_rings);
+       /* Cannot currently support more rings than we have ring AICs! */
+       priv->config.rings = min_t(u32, priv->config.rings,
+                                       priv->hwconfig.hwnumraic);
 
        priv->config.cd_size = EIP197_CD64_FETCH_SIZE;
        priv->config.cd_offset = (priv->config.cd_size + mask) & ~mask;
@@ -1481,6 +1484,15 @@ static int safexcel_probe_generic(void *pdev,
                                            EIP197_N_RINGS_MASK;
        }
 
+       /* Scan for ring AIC's */
+       for (i = 0; i < EIP197_MAX_RING_AIC; i++) {
+               version = readl(EIP197_HIA_AIC_R(priv) +
+                               EIP197_HIA_AIC_R_VERSION(i));
+               if (EIP197_REG_LO16(version) != EIP201_VERSION_LE)
+                       break;
+       }
+       priv->hwconfig.hwnumraic = i;
+
        /* Get supported algorithms from EIP96 transform engine */
        priv->hwconfig.algo_flags = readl(EIP197_PE(priv) +
                                    EIP197_PE_EIP96_OPTIONS(0));
@@ -1488,10 +1500,10 @@ static int safexcel_probe_generic(void *pdev,
        /* Print single info line describing what we just detected */
        dev_info(priv->dev, "EIP%d:%x(%d,%d,%d,%d)-HIA:%x(%d,%d,%d),PE:%x,alg:%08x\n",
                 peid, priv->hwconfig.hwver, hwctg, priv->hwconfig.hwnumpes,
-                priv->hwconfig.hwnumrings, priv->hwconfig.hiaver,
-                priv->hwconfig.hwdataw, priv->hwconfig.hwcfsize,
-                priv->hwconfig.hwrfsize, priv->hwconfig.pever,
-                priv->hwconfig.algo_flags);
+                priv->hwconfig.hwnumrings, priv->hwconfig.hwnumraic,
+                priv->hwconfig.hiaver, priv->hwconfig.hwdataw,
+                priv->hwconfig.hwcfsize, priv->hwconfig.hwrfsize,
+                priv->hwconfig.pever, priv->hwconfig.algo_flags);
 
        safexcel_configure(priv);
 
index 2400814e8c147b84cafa6b0b1d706bbb6b9276f6..227771363359f49098f6960a339314271a320231 100644 (file)
@@ -19,6 +19,7 @@
 #define EIP97_VERSION_LE                       0x9e61
 #define EIP197_VERSION_LE                      0x3ac5
 #define EIP96_VERSION_LE                       0x9f60
+#define EIP201_VERSION_LE                      0x36c9
 #define EIP197_REG_LO16(reg)                   (reg & 0xffff)
 #define EIP197_REG_HI16(reg)                   ((reg >> 16) & 0xffff)
 #define EIP197_VERSION_MASK(reg)               ((reg >> 16) & 0xfff)
@@ -32,6 +33,7 @@
 #define EIP197_MAX_RINGS                       4
 #define EIP197_FETCH_DEPTH                     2
 #define EIP197_MAX_BATCH_SZ                    64
+#define EIP197_MAX_RING_AIC                    14
 
 #define EIP197_GFP_FLAGS(base) ((base).flags & CRYPTO_TFM_REQ_MAY_SLEEP ? \
                                 GFP_KERNEL : GFP_ATOMIC)
 #define EIP197_HIA_AIC_R_ENABLED_STAT(r)       (0xe010 - EIP197_HIA_AIC_R_OFF(r))
 #define EIP197_HIA_AIC_R_ACK(r)                        (0xe010 - EIP197_HIA_AIC_R_OFF(r))
 #define EIP197_HIA_AIC_R_ENABLE_CLR(r)         (0xe014 - EIP197_HIA_AIC_R_OFF(r))
+#define EIP197_HIA_AIC_R_VERSION(r)            (0xe01c - EIP197_HIA_AIC_R_OFF(r))
 #define EIP197_HIA_AIC_G_ENABLE_CTRL           0xf808
 #define EIP197_HIA_AIC_G_ENABLED_STAT          0xf810
 #define EIP197_HIA_AIC_G_ACK                   0xf810
@@ -740,6 +743,7 @@ struct safexcel_hwconfig {
        int hwrfsize;
        int hwnumpes;
        int hwnumrings;
+       int hwnumraic;
 };
 
 struct safexcel_crypto_priv {