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

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
Loading
Loading
Loading
Loading
+56 −13
Original line number Diff line number Diff line
@@ -484,6 +484,14 @@ static int safexcel_hw_setup_cdesc_rings(struct safexcel_crypto_priv *priv)
		cd_fetch_cnt = ((1 << priv->hwconfig.hwcfsize) /
				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++) {
		/* ring base address */
@@ -608,8 +616,8 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
		writel(EIP197_DxE_THR_CTRL_RESET_PE,
		       EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe));

		if (priv->flags & SAFEXCEL_HW_EIP197)
			/* Reset HIA input interface arbiter (EIP197 only) */
		if (priv->flags & EIP197_PE_ARB)
			/* Reset HIA input interface arbiter (if present) */
			writel(EIP197_HIA_RA_PE_CTRL_RESET,
			       EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe));

@@ -756,22 +764,28 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
	/* Clear any HIA interrupt */
	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);
		if (ret)
			return ret;
	}

		priv->flags |= EIP197_TRC_CACHE;

	if (priv->flags & EIP197_ICE) {
		ret = eip197_load_firmwares(priv);
		if (ret)
			return ret;
	}

	safexcel_hw_setup_cdesc_rings(priv);
	safexcel_hw_setup_rdesc_rings(priv);

	return 0;
	return safexcel_hw_setup_cdesc_rings(priv) ?:
	       safexcel_hw_setup_rdesc_rings(priv) ?:
	       0;
}

/* Called with ring's lock taken */
@@ -1371,7 +1385,7 @@ static int safexcel_probe_generic(void *pdev,
				  int is_pci_dev)
{
	struct device *dev = priv->dev;
	u32 peid, version, mask, val, hiaopt;
	u32 peid, version, mask, val, hiaopt, hwopt, peopt;
	int i, ret, hwctg;

	priv->context_pool = dmam_pool_create("safexcel-context", dev,
@@ -1433,13 +1447,16 @@ static int safexcel_probe_generic(void *pdev,
	 */
	version = readl(EIP197_GLOBAL(priv) + EIP197_VERSION);
	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) &&
	     (EIP197_REG_LO16(version) != EIP97_VERSION_LE)))) {
		/*
		 * We did not find the device that matched our initial probing
		 * (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;
	}

@@ -1447,6 +1464,14 @@ static int safexcel_probe_generic(void *pdev,
	hwctg = version >> 28;
	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 */
	version = readl(EIP197_PE(priv) + EIP197_PE_EIP96_VERSION(0));
	if (EIP197_REG_LO16(version) != EIP96_VERSION_LE) {
@@ -1455,10 +1480,13 @@ static int safexcel_probe_generic(void *pdev,
	}
	priv->hwconfig.pever = EIP197_VERSION_MASK(version);

	hwopt = readl(EIP197_GLOBAL(priv) + EIP197_OPTIONS);
	hiaopt = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_OPTIONS);

	if (priv->flags & SAFEXCEL_HW_EIP197) {
		/* EIP197 */
		peopt = readl(EIP197_PE(priv) + EIP197_PE_OPTIONS(0));

		priv->hwconfig.hwdataw  = (hiaopt >> EIP197_HWDATAW_OFFSET) &
					  EIP197_HWDATAW_MASK;
		priv->hwconfig.hwcfsize = ((hiaopt >> EIP197_CFSIZE_OFFSET) &
@@ -1471,6 +1499,15 @@ static int safexcel_probe_generic(void *pdev,
					  EIP197_N_PES_MASK;
		priv->hwconfig.hwnumrings = (hiaopt >> EIP197_N_RINGS_OFFSET) &
					    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 {
		/* EIP97 */
		priv->hwconfig.hwdataw  = (hiaopt >> EIP197_HWDATAW_OFFSET) &
@@ -1492,18 +1529,24 @@ static int safexcel_probe_generic(void *pdev,
			break;
	}
	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 */
	priv->hwconfig.algo_flags = readl(EIP197_PE(priv) +
				    EIP197_PE_EIP96_OPTIONS(0));

	/* 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,
		 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);
		 priv->hwconfig.ppver, priv->hwconfig.pever,
		 priv->hwconfig.algo_flags);

	safexcel_configure(priv);

+29 −1
Original line number Diff line number Diff line
@@ -17,9 +17,11 @@
#define EIP197_HIA_VERSION_BE			0xca35
#define EIP197_HIA_VERSION_LE			0x35ca
#define EIP97_VERSION_LE			0x9e61
#define EIP196_VERSION_LE			0x3bc4
#define EIP197_VERSION_LE			0x3ac5
#define EIP96_VERSION_LE			0x9f60
#define EIP201_VERSION_LE			0x36c9
#define EIP206_VERSION_LE			0x31ce
#define EIP197_REG_LO16(reg)			(reg & 0xffff)
#define EIP197_REG_HI16(reg)			((reg >> 16) & 0xffff)
#define EIP197_VERSION_MASK(reg)		((reg >> 16) & 0xfff)
@@ -27,6 +29,15 @@
						((reg >> 4) & 0xf0) | \
						((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 */
#define EIP197_DEFAULT_RING_SIZE		400
#define EIP197_MAX_TOKENS			19
@@ -160,12 +171,16 @@
#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_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_OPTIONS(n)		(0x13f8 + (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_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_OPTIONS				0xfff8
#define EIP197_VERSION				0xfffc

/* EIP197-specific registers, no indirection */
@@ -181,6 +196,7 @@
#define EIP197_TRC_ECCADMINSTAT			0xf0838
#define EIP197_TRC_ECCDATASTAT			0xf083c
#define EIP197_TRC_ECCDATA			0xf0840
#define EIP197_STRC_CONFIG			0xf43f0
#define EIP197_FLUE_CACHEBASE_LO(n)		(0xf6000 + (32 * (n)))
#define EIP197_FLUE_CACHEBASE_HI(n)		(0xf6004 + (32 * (n)))
#define EIP197_FLUE_CONFIG(n)			(0xf6010 + (32 * (n)))
@@ -331,6 +347,14 @@
#define EIP197_ADDRESS_MODE			BIT(8)
#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 */
#define EIP197_FLUE_CONFIG_MAGIC		0xc7000004

@@ -472,7 +496,7 @@ struct result_data_desc {
	u16 application_id;
	u16 rsvd1;

	u32 rsvd2;
	u32 rsvd2[5];
} __packed;


@@ -731,12 +755,16 @@ struct safexcel_register_offsets {
enum safexcel_flags {
	EIP197_TRC_CACHE	= BIT(0),
	SAFEXCEL_HW_EIP197	= BIT(1),
	EIP197_PE_ARB		= BIT(2),
	EIP197_ICE		= BIT(3),
	EIP197_SIMPLE_TRC	= BIT(4),
};

struct safexcel_hwconfig {
	enum safexcel_eip_algorithms algo_flags;
	int hwver;
	int hiaver;
	int ppver;
	int pever;
	int hwdataw;
	int hwcfsize;
+1 −0
Original line number Diff line number Diff line
@@ -180,6 +180,7 @@ struct safexcel_result_desc *safexcel_add_rdesc(struct safexcel_crypto_priv *pri

	rdesc->first_seg = first;
	rdesc->last_seg = last;
	rdesc->result_size = EIP197_RD64_RESULT_SIZE;
	rdesc->particle_size = len;
	rdesc->data_lo = lower_32_bits(data);
	rdesc->data_hi = upper_32_bits(data);