Commit 5fd39c4d authored by Pascal van Leeuwen's avatar Pascal van Leeuwen Committed by Herbert Xu

crypto: inside-secure - Add support for the EIP196

This patch adds support for the EIP196, which is an EIP197 derivative
that has no classification hardware and a simplified record cache.

The patch has been tested with the eip196b-ie and eip197c-iewxkbc
configurations on the Xilinx VCU118 development board as well as on the
Macchiatobin board (Marvell A8K - EIP197b-ieswx), including the crypto
extra tests.

Note that this patchset applies on top of the earlier submitted
"Add support for eip197f_iewc" series.
Signed-off-by: default avatarPascal van Leeuwen <pvanleeuwen@verimatrix.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 9e5de3e0
...@@ -484,6 +484,14 @@ static int safexcel_hw_setup_cdesc_rings(struct safexcel_crypto_priv *priv) ...@@ -484,6 +484,14 @@ static int safexcel_hw_setup_cdesc_rings(struct safexcel_crypto_priv *priv)
cd_fetch_cnt = ((1 << priv->hwconfig.hwcfsize) / cd_fetch_cnt = ((1 << priv->hwconfig.hwcfsize) /
cd_size_rnd) - 1; cd_size_rnd) - 1;
} }
/*
* Since we're using command desc's way larger than formally specified,
* we need to check whether we can fit even 1 for low-end EIP196's!
*/
if (!cd_fetch_cnt) {
dev_err(priv->dev, "Unable to fit even 1 command desc!\n");
return -ENODEV;
}
for (i = 0; i < priv->config.rings; i++) { for (i = 0; i < priv->config.rings; i++) {
/* ring base address */ /* ring base address */
...@@ -608,8 +616,8 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv) ...@@ -608,8 +616,8 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
writel(EIP197_DxE_THR_CTRL_RESET_PE, writel(EIP197_DxE_THR_CTRL_RESET_PE,
EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe)); EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe));
if (priv->flags & SAFEXCEL_HW_EIP197) if (priv->flags & EIP197_PE_ARB)
/* Reset HIA input interface arbiter (EIP197 only) */ /* Reset HIA input interface arbiter (if present) */
writel(EIP197_HIA_RA_PE_CTRL_RESET, writel(EIP197_HIA_RA_PE_CTRL_RESET,
EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe)); EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe));
...@@ -756,22 +764,28 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv) ...@@ -756,22 +764,28 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
/* Clear any HIA interrupt */ /* Clear any HIA interrupt */
writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK); writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK);
if (priv->flags & SAFEXCEL_HW_EIP197) { if (priv->flags & EIP197_SIMPLE_TRC) {
writel(EIP197_STRC_CONFIG_INIT |
EIP197_STRC_CONFIG_LARGE_REC(EIP197_CS_TRC_REC_WC) |
EIP197_STRC_CONFIG_SMALL_REC(EIP197_CS_TRC_REC_WC),
priv->base + EIP197_STRC_CONFIG);
writel(EIP197_PE_EIP96_TOKEN_CTRL2_CTX_DONE,
EIP197_PE(priv) + EIP197_PE_EIP96_TOKEN_CTRL2(0));
} else if (priv->flags & SAFEXCEL_HW_EIP197) {
ret = eip197_trc_cache_init(priv); ret = eip197_trc_cache_init(priv);
if (ret) if (ret)
return ret; return ret;
}
priv->flags |= EIP197_TRC_CACHE; if (priv->flags & EIP197_ICE) {
ret = eip197_load_firmwares(priv); ret = eip197_load_firmwares(priv);
if (ret) if (ret)
return ret; return ret;
} }
safexcel_hw_setup_cdesc_rings(priv); return safexcel_hw_setup_cdesc_rings(priv) ?:
safexcel_hw_setup_rdesc_rings(priv); safexcel_hw_setup_rdesc_rings(priv) ?:
0;
return 0;
} }
/* Called with ring's lock taken */ /* Called with ring's lock taken */
...@@ -1371,7 +1385,7 @@ static int safexcel_probe_generic(void *pdev, ...@@ -1371,7 +1385,7 @@ static int safexcel_probe_generic(void *pdev,
int is_pci_dev) int is_pci_dev)
{ {
struct device *dev = priv->dev; struct device *dev = priv->dev;
u32 peid, version, mask, val, hiaopt; u32 peid, version, mask, val, hiaopt, hwopt, peopt;
int i, ret, hwctg; int i, ret, hwctg;
priv->context_pool = dmam_pool_create("safexcel-context", dev, priv->context_pool = dmam_pool_create("safexcel-context", dev,
...@@ -1433,13 +1447,16 @@ static int safexcel_probe_generic(void *pdev, ...@@ -1433,13 +1447,16 @@ static int safexcel_probe_generic(void *pdev,
*/ */
version = readl(EIP197_GLOBAL(priv) + EIP197_VERSION); version = readl(EIP197_GLOBAL(priv) + EIP197_VERSION);
if (((priv->flags & SAFEXCEL_HW_EIP197) && if (((priv->flags & SAFEXCEL_HW_EIP197) &&
(EIP197_REG_LO16(version) != EIP197_VERSION_LE)) || (EIP197_REG_LO16(version) != EIP197_VERSION_LE) &&
(EIP197_REG_LO16(version) != EIP196_VERSION_LE)) ||
((!(priv->flags & SAFEXCEL_HW_EIP197) && ((!(priv->flags & SAFEXCEL_HW_EIP197) &&
(EIP197_REG_LO16(version) != EIP97_VERSION_LE)))) { (EIP197_REG_LO16(version) != EIP97_VERSION_LE)))) {
/* /*
* We did not find the device that matched our initial probing * We did not find the device that matched our initial probing
* (or our initial probing failed) Report appropriate error. * (or our initial probing failed) Report appropriate error.
*/ */
dev_err(priv->dev, "Probing for EIP97/EIP19x failed - no such device (read %08x)\n",
version);
return -ENODEV; return -ENODEV;
} }
...@@ -1447,6 +1464,14 @@ static int safexcel_probe_generic(void *pdev, ...@@ -1447,6 +1464,14 @@ static int safexcel_probe_generic(void *pdev,
hwctg = version >> 28; hwctg = version >> 28;
peid = version & 255; peid = version & 255;
/* Detect EIP206 processing pipe */
version = readl(EIP197_PE(priv) + + EIP197_PE_VERSION(0));
if (EIP197_REG_LO16(version) != EIP206_VERSION_LE) {
dev_err(priv->dev, "EIP%d: EIP206 not detected\n", peid);
return -ENODEV;
}
priv->hwconfig.ppver = EIP197_VERSION_MASK(version);
/* Detect EIP96 packet engine and version */ /* Detect EIP96 packet engine and version */
version = readl(EIP197_PE(priv) + EIP197_PE_EIP96_VERSION(0)); version = readl(EIP197_PE(priv) + EIP197_PE_EIP96_VERSION(0));
if (EIP197_REG_LO16(version) != EIP96_VERSION_LE) { if (EIP197_REG_LO16(version) != EIP96_VERSION_LE) {
...@@ -1455,10 +1480,13 @@ static int safexcel_probe_generic(void *pdev, ...@@ -1455,10 +1480,13 @@ static int safexcel_probe_generic(void *pdev,
} }
priv->hwconfig.pever = EIP197_VERSION_MASK(version); priv->hwconfig.pever = EIP197_VERSION_MASK(version);
hwopt = readl(EIP197_GLOBAL(priv) + EIP197_OPTIONS);
hiaopt = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_OPTIONS); hiaopt = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_OPTIONS);
if (priv->flags & SAFEXCEL_HW_EIP197) { if (priv->flags & SAFEXCEL_HW_EIP197) {
/* EIP197 */ /* EIP197 */
peopt = readl(EIP197_PE(priv) + EIP197_PE_OPTIONS(0));
priv->hwconfig.hwdataw = (hiaopt >> EIP197_HWDATAW_OFFSET) & priv->hwconfig.hwdataw = (hiaopt >> EIP197_HWDATAW_OFFSET) &
EIP197_HWDATAW_MASK; EIP197_HWDATAW_MASK;
priv->hwconfig.hwcfsize = ((hiaopt >> EIP197_CFSIZE_OFFSET) & priv->hwconfig.hwcfsize = ((hiaopt >> EIP197_CFSIZE_OFFSET) &
...@@ -1471,6 +1499,15 @@ static int safexcel_probe_generic(void *pdev, ...@@ -1471,6 +1499,15 @@ static int safexcel_probe_generic(void *pdev,
EIP197_N_PES_MASK; EIP197_N_PES_MASK;
priv->hwconfig.hwnumrings = (hiaopt >> EIP197_N_RINGS_OFFSET) & priv->hwconfig.hwnumrings = (hiaopt >> EIP197_N_RINGS_OFFSET) &
EIP197_N_RINGS_MASK; EIP197_N_RINGS_MASK;
if (hiaopt & EIP197_HIA_OPT_HAS_PE_ARB)
priv->flags |= EIP197_PE_ARB;
if (EIP206_OPT_ICE_TYPE(peopt) == 1)
priv->flags |= EIP197_ICE;
/* If not a full TRC, then assume simple TRC */
if (!(hwopt & EIP197_OPT_HAS_TRC))
priv->flags |= EIP197_SIMPLE_TRC;
/* EIP197 always has SOME form of TRC */
priv->flags |= EIP197_TRC_CACHE;
} else { } else {
/* EIP97 */ /* EIP97 */
priv->hwconfig.hwdataw = (hiaopt >> EIP197_HWDATAW_OFFSET) & priv->hwconfig.hwdataw = (hiaopt >> EIP197_HWDATAW_OFFSET) &
...@@ -1492,18 +1529,24 @@ static int safexcel_probe_generic(void *pdev, ...@@ -1492,18 +1529,24 @@ static int safexcel_probe_generic(void *pdev,
break; break;
} }
priv->hwconfig.hwnumraic = i; priv->hwconfig.hwnumraic = i;
/* Low-end EIP196 may not have any ring AIC's ... */
if (!priv->hwconfig.hwnumraic) {
dev_err(priv->dev, "No ring interrupt controller present!\n");
return -ENODEV;
}
/* Get supported algorithms from EIP96 transform engine */ /* Get supported algorithms from EIP96 transform engine */
priv->hwconfig.algo_flags = readl(EIP197_PE(priv) + priv->hwconfig.algo_flags = readl(EIP197_PE(priv) +
EIP197_PE_EIP96_OPTIONS(0)); EIP197_PE_EIP96_OPTIONS(0));
/* Print single info line describing what we just detected */ /* 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", dev_info(priv->dev, "EIP%d:%x(%d,%d,%d,%d)-HIA:%x(%d,%d,%d),PE:%x/%x,alg:%08x\n",
peid, priv->hwconfig.hwver, hwctg, priv->hwconfig.hwnumpes, peid, priv->hwconfig.hwver, hwctg, priv->hwconfig.hwnumpes,
priv->hwconfig.hwnumrings, priv->hwconfig.hwnumraic, priv->hwconfig.hwnumrings, priv->hwconfig.hwnumraic,
priv->hwconfig.hiaver, priv->hwconfig.hwdataw, priv->hwconfig.hiaver, priv->hwconfig.hwdataw,
priv->hwconfig.hwcfsize, priv->hwconfig.hwrfsize, priv->hwconfig.hwcfsize, priv->hwconfig.hwrfsize,
priv->hwconfig.pever, priv->hwconfig.algo_flags); priv->hwconfig.ppver, priv->hwconfig.pever,
priv->hwconfig.algo_flags);
safexcel_configure(priv); safexcel_configure(priv);
......
...@@ -17,9 +17,11 @@ ...@@ -17,9 +17,11 @@
#define EIP197_HIA_VERSION_BE 0xca35 #define EIP197_HIA_VERSION_BE 0xca35
#define EIP197_HIA_VERSION_LE 0x35ca #define EIP197_HIA_VERSION_LE 0x35ca
#define EIP97_VERSION_LE 0x9e61 #define EIP97_VERSION_LE 0x9e61
#define EIP196_VERSION_LE 0x3bc4
#define EIP197_VERSION_LE 0x3ac5 #define EIP197_VERSION_LE 0x3ac5
#define EIP96_VERSION_LE 0x9f60 #define EIP96_VERSION_LE 0x9f60
#define EIP201_VERSION_LE 0x36c9 #define EIP201_VERSION_LE 0x36c9
#define EIP206_VERSION_LE 0x31ce
#define EIP197_REG_LO16(reg) (reg & 0xffff) #define EIP197_REG_LO16(reg) (reg & 0xffff)
#define EIP197_REG_HI16(reg) ((reg >> 16) & 0xffff) #define EIP197_REG_HI16(reg) ((reg >> 16) & 0xffff)
#define EIP197_VERSION_MASK(reg) ((reg >> 16) & 0xfff) #define EIP197_VERSION_MASK(reg) ((reg >> 16) & 0xfff)
...@@ -27,6 +29,15 @@ ...@@ -27,6 +29,15 @@
((reg >> 4) & 0xf0) | \ ((reg >> 4) & 0xf0) | \
((reg >> 12) & 0xf)) ((reg >> 12) & 0xf))
/* EIP197 HIA OPTIONS ENCODING */
#define EIP197_HIA_OPT_HAS_PE_ARB BIT(29)
/* EIP206 OPTIONS ENCODING */
#define EIP206_OPT_ICE_TYPE(n) ((n>>8)&3)
/* EIP197 OPTIONS ENCODING */
#define EIP197_OPT_HAS_TRC BIT(31)
/* Static configuration */ /* Static configuration */
#define EIP197_DEFAULT_RING_SIZE 400 #define EIP197_DEFAULT_RING_SIZE 400
#define EIP197_MAX_TOKENS 19 #define EIP197_MAX_TOKENS 19
...@@ -160,12 +171,16 @@ ...@@ -160,12 +171,16 @@
#define EIP197_PE_EIP96_FUNCTION_EN(n) (0x1004 + (0x2000 * (n))) #define EIP197_PE_EIP96_FUNCTION_EN(n) (0x1004 + (0x2000 * (n)))
#define EIP197_PE_EIP96_CONTEXT_CTRL(n) (0x1008 + (0x2000 * (n))) #define EIP197_PE_EIP96_CONTEXT_CTRL(n) (0x1008 + (0x2000 * (n)))
#define EIP197_PE_EIP96_CONTEXT_STAT(n) (0x100c + (0x2000 * (n))) #define EIP197_PE_EIP96_CONTEXT_STAT(n) (0x100c + (0x2000 * (n)))
#define EIP197_PE_EIP96_TOKEN_CTRL2(n) (0x102c + (0x2000 * (n)))
#define EIP197_PE_EIP96_FUNCTION2_EN(n) (0x1030 + (0x2000 * (n))) #define EIP197_PE_EIP96_FUNCTION2_EN(n) (0x1030 + (0x2000 * (n)))
#define EIP197_PE_EIP96_OPTIONS(n) (0x13f8 + (0x2000 * (n))) #define EIP197_PE_EIP96_OPTIONS(n) (0x13f8 + (0x2000 * (n)))
#define EIP197_PE_EIP96_VERSION(n) (0x13fc + (0x2000 * (n))) #define EIP197_PE_EIP96_VERSION(n) (0x13fc + (0x2000 * (n)))
#define EIP197_PE_OUT_DBUF_THRES(n) (0x1c00 + (0x2000 * (n))) #define EIP197_PE_OUT_DBUF_THRES(n) (0x1c00 + (0x2000 * (n)))
#define EIP197_PE_OUT_TBUF_THRES(n) (0x1d00 + (0x2000 * (n))) #define EIP197_PE_OUT_TBUF_THRES(n) (0x1d00 + (0x2000 * (n)))
#define EIP197_PE_OPTIONS(n) (0x1ff8 + (0x2000 * (n)))
#define EIP197_PE_VERSION(n) (0x1ffc + (0x2000 * (n)))
#define EIP197_MST_CTRL 0xfff4 #define EIP197_MST_CTRL 0xfff4
#define EIP197_OPTIONS 0xfff8
#define EIP197_VERSION 0xfffc #define EIP197_VERSION 0xfffc
/* EIP197-specific registers, no indirection */ /* EIP197-specific registers, no indirection */
...@@ -181,6 +196,7 @@ ...@@ -181,6 +196,7 @@
#define EIP197_TRC_ECCADMINSTAT 0xf0838 #define EIP197_TRC_ECCADMINSTAT 0xf0838
#define EIP197_TRC_ECCDATASTAT 0xf083c #define EIP197_TRC_ECCDATASTAT 0xf083c
#define EIP197_TRC_ECCDATA 0xf0840 #define EIP197_TRC_ECCDATA 0xf0840
#define EIP197_STRC_CONFIG 0xf43f0
#define EIP197_FLUE_CACHEBASE_LO(n) (0xf6000 + (32 * (n))) #define EIP197_FLUE_CACHEBASE_LO(n) (0xf6000 + (32 * (n)))
#define EIP197_FLUE_CACHEBASE_HI(n) (0xf6004 + (32 * (n))) #define EIP197_FLUE_CACHEBASE_HI(n) (0xf6004 + (32 * (n)))
#define EIP197_FLUE_CONFIG(n) (0xf6010 + (32 * (n))) #define EIP197_FLUE_CONFIG(n) (0xf6010 + (32 * (n)))
...@@ -331,6 +347,14 @@ ...@@ -331,6 +347,14 @@
#define EIP197_ADDRESS_MODE BIT(8) #define EIP197_ADDRESS_MODE BIT(8)
#define EIP197_CONTROL_MODE BIT(9) #define EIP197_CONTROL_MODE BIT(9)
/* EIP197_PE_EIP96_TOKEN_CTRL2 */
#define EIP197_PE_EIP96_TOKEN_CTRL2_CTX_DONE BIT(3)
/* EIP197_STRC_CONFIG */
#define EIP197_STRC_CONFIG_INIT BIT(31)
#define EIP197_STRC_CONFIG_LARGE_REC(s) (s<<8)
#define EIP197_STRC_CONFIG_SMALL_REC(s) (s<<0)
/* EIP197_FLUE_CONFIG */ /* EIP197_FLUE_CONFIG */
#define EIP197_FLUE_CONFIG_MAGIC 0xc7000004 #define EIP197_FLUE_CONFIG_MAGIC 0xc7000004
...@@ -472,7 +496,7 @@ struct result_data_desc { ...@@ -472,7 +496,7 @@ struct result_data_desc {
u16 application_id; u16 application_id;
u16 rsvd1; u16 rsvd1;
u32 rsvd2; u32 rsvd2[5];
} __packed; } __packed;
...@@ -731,12 +755,16 @@ struct safexcel_register_offsets { ...@@ -731,12 +755,16 @@ struct safexcel_register_offsets {
enum safexcel_flags { enum safexcel_flags {
EIP197_TRC_CACHE = BIT(0), EIP197_TRC_CACHE = BIT(0),
SAFEXCEL_HW_EIP197 = BIT(1), SAFEXCEL_HW_EIP197 = BIT(1),
EIP197_PE_ARB = BIT(2),
EIP197_ICE = BIT(3),
EIP197_SIMPLE_TRC = BIT(4),
}; };
struct safexcel_hwconfig { struct safexcel_hwconfig {
enum safexcel_eip_algorithms algo_flags; enum safexcel_eip_algorithms algo_flags;
int hwver; int hwver;
int hiaver; int hiaver;
int ppver;
int pever; int pever;
int hwdataw; int hwdataw;
int hwcfsize; int hwcfsize;
......
...@@ -180,6 +180,7 @@ struct safexcel_result_desc *safexcel_add_rdesc(struct safexcel_crypto_priv *pri ...@@ -180,6 +180,7 @@ struct safexcel_result_desc *safexcel_add_rdesc(struct safexcel_crypto_priv *pri
rdesc->first_seg = first; rdesc->first_seg = first;
rdesc->last_seg = last; rdesc->last_seg = last;
rdesc->result_size = EIP197_RD64_RESULT_SIZE;
rdesc->particle_size = len; rdesc->particle_size = len;
rdesc->data_lo = lower_32_bits(data); rdesc->data_lo = lower_32_bits(data);
rdesc->data_hi = upper_32_bits(data); rdesc->data_hi = upper_32_bits(data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment