Skip to content

Commit 118db42

Browse files
Pascal van Leeuwenherbertx
authored andcommitted
crypto: inside-secure - Add EIP97/EIP197 and endianness detection
This patch adds automatic EIP97/EIP197 detection, so it does not need to rely on any static value from the device table anymore. In particular, the static value from the table won't work for PCI devboards that cannot be further identified save from this direct hardware probing. The patch also adds automatic host xs endianness detection & correction. Signed-off-by: Pascal van Leeuwen <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent c51636a commit 118db42

File tree

2 files changed

+130
-50
lines changed

2 files changed

+130
-50
lines changed

drivers/crypto/inside-secure/safexcel.c

Lines changed: 107 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -393,29 +393,21 @@ static int safexcel_hw_setup_rdesc_rings(struct safexcel_crypto_priv *priv)
393393

394394
static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
395395
{
396-
u32 version, val;
396+
u32 val;
397397
int i, ret, pe;
398398

399399
dev_dbg(priv->dev, "HW init: using %d pipe(s) and %d ring(s)\n",
400400
priv->config.pes, priv->config.rings);
401401

402-
/* Determine endianess and configure byte swap */
403-
version = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_VERSION);
404-
val = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
405-
406-
if ((version & 0xffff) == EIP197_HIA_VERSION_BE)
407-
val |= EIP197_MST_CTRL_BYTE_SWAP;
408-
else if (((version >> 16) & 0xffff) == EIP197_HIA_VERSION_LE)
409-
val |= (EIP197_MST_CTRL_NO_BYTE_SWAP >> 24);
410-
411402
/*
412403
* For EIP197's only set maximum number of TX commands to 2^5 = 32
413404
* Skip for the EIP97 as it does not have this field.
414405
*/
415-
if (priv->version != EIP97IES_MRVL)
406+
if (priv->flags & SAFEXCEL_HW_EIP197) {
407+
val = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
416408
val |= EIP197_MST_CTRL_TX_MAX_CMD(5);
417-
418-
writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
409+
writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
410+
}
419411

420412
/* Configure wr/rd cache values */
421413
writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) |
@@ -438,7 +430,7 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
438430
writel(EIP197_DxE_THR_CTRL_RESET_PE,
439431
EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe));
440432

441-
if (priv->version != EIP97IES_MRVL)
433+
if (priv->flags & SAFEXCEL_HW_EIP197)
442434
/* Reset HIA input interface arbiter (EIP197 only) */
443435
writel(EIP197_HIA_RA_PE_CTRL_RESET,
444436
EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe));
@@ -464,7 +456,7 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
464456
EIP197_PE_IN_xBUF_THRES_MAX(7),
465457
EIP197_PE(priv) + EIP197_PE_IN_TBUF_THRES(pe));
466458

467-
if (priv->version != EIP97IES_MRVL)
459+
if (priv->flags & SAFEXCEL_HW_EIP197)
468460
/* enable HIA input interface arbiter and rings */
469461
writel(EIP197_HIA_RA_PE_CTRL_EN |
470462
GENMASK(priv->config.rings - 1, 0),
@@ -490,7 +482,7 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
490482
/* FIXME: instability issues can occur for EIP97 but disabling
491483
* it impacts performance.
492484
*/
493-
if (priv->version != EIP97IES_MRVL)
485+
if (priv->flags & SAFEXCEL_HW_EIP197)
494486
val |= EIP197_HIA_DSE_CFG_EN_SINGLE_WR;
495487
writel(val, EIP197_HIA_DSE(priv) + EIP197_HIA_DSE_CFG(pe));
496488

@@ -577,8 +569,9 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
577569
/* Clear any HIA interrupt */
578570
writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK);
579571

580-
if (priv->version != EIP97IES_MRVL) {
572+
if (priv->flags & SAFEXCEL_HW_EIP197) {
581573
eip197_trc_cache_init(priv);
574+
priv->flags |= EIP197_TRC_CACHE;
582575

583576
ret = eip197_load_firmwares(priv);
584577
if (ret)
@@ -1083,12 +1076,12 @@ static void safexcel_configure(struct safexcel_crypto_priv *priv)
10831076
val = readl(EIP197_HIA_AIC_G(priv) + EIP197_HIA_OPTIONS);
10841077

10851078
/* Read number of PEs from the engine */
1086-
if (priv->version == EIP97IES_MRVL)
1087-
/* Narrow field width for EIP97 type engine */
1088-
mask = EIP97_N_PES_MASK;
1089-
else
1079+
if (priv->flags & SAFEXCEL_HW_EIP197)
10901080
/* Wider field width for all EIP197 type engines */
10911081
mask = EIP197_N_PES_MASK;
1082+
else
1083+
/* Narrow field width for EIP97 type engine */
1084+
mask = EIP97_N_PES_MASK;
10921085

10931086
priv->config.pes = (val >> EIP197_N_PES_OFFSET) & mask;
10941087

@@ -1108,18 +1101,7 @@ static void safexcel_init_register_offsets(struct safexcel_crypto_priv *priv)
11081101
{
11091102
struct safexcel_register_offsets *offsets = &priv->offsets;
11101103

1111-
if (priv->version == EIP97IES_MRVL) {
1112-
offsets->hia_aic = EIP97_HIA_AIC_BASE;
1113-
offsets->hia_aic_g = EIP97_HIA_AIC_G_BASE;
1114-
offsets->hia_aic_r = EIP97_HIA_AIC_R_BASE;
1115-
offsets->hia_aic_xdr = EIP97_HIA_AIC_xDR_BASE;
1116-
offsets->hia_dfe = EIP97_HIA_DFE_BASE;
1117-
offsets->hia_dfe_thr = EIP97_HIA_DFE_THR_BASE;
1118-
offsets->hia_dse = EIP97_HIA_DSE_BASE;
1119-
offsets->hia_dse_thr = EIP97_HIA_DSE_THR_BASE;
1120-
offsets->hia_gen_cfg = EIP97_HIA_GEN_CFG_BASE;
1121-
offsets->pe = EIP97_PE_BASE;
1122-
} else {
1104+
if (priv->flags & SAFEXCEL_HW_EIP197) {
11231105
offsets->hia_aic = EIP197_HIA_AIC_BASE;
11241106
offsets->hia_aic_g = EIP197_HIA_AIC_G_BASE;
11251107
offsets->hia_aic_r = EIP197_HIA_AIC_R_BASE;
@@ -1130,6 +1112,19 @@ static void safexcel_init_register_offsets(struct safexcel_crypto_priv *priv)
11301112
offsets->hia_dse_thr = EIP197_HIA_DSE_THR_BASE;
11311113
offsets->hia_gen_cfg = EIP197_HIA_GEN_CFG_BASE;
11321114
offsets->pe = EIP197_PE_BASE;
1115+
offsets->global = EIP197_GLOBAL_BASE;
1116+
} else {
1117+
offsets->hia_aic = EIP97_HIA_AIC_BASE;
1118+
offsets->hia_aic_g = EIP97_HIA_AIC_G_BASE;
1119+
offsets->hia_aic_r = EIP97_HIA_AIC_R_BASE;
1120+
offsets->hia_aic_xdr = EIP97_HIA_AIC_xDR_BASE;
1121+
offsets->hia_dfe = EIP97_HIA_DFE_BASE;
1122+
offsets->hia_dfe_thr = EIP97_HIA_DFE_THR_BASE;
1123+
offsets->hia_dse = EIP97_HIA_DSE_BASE;
1124+
offsets->hia_dse_thr = EIP97_HIA_DSE_THR_BASE;
1125+
offsets->hia_gen_cfg = EIP97_HIA_GEN_CFG_BASE;
1126+
offsets->pe = EIP97_PE_BASE;
1127+
offsets->global = EIP97_GLOBAL_BASE;
11331128
}
11341129
}
11351130

@@ -1145,32 +1140,98 @@ static int safexcel_probe_generic(void *pdev,
11451140
int is_pci_dev)
11461141
{
11471142
struct device *dev = priv->dev;
1148-
u32 peid;
1149-
int i, ret;
1143+
u32 peid, version, mask, val;
1144+
int i, ret, hwctg;
11501145

11511146
priv->context_pool = dmam_pool_create("safexcel-context", dev,
11521147
sizeof(struct safexcel_context_record),
11531148
1, 0);
11541149
if (!priv->context_pool)
11551150
return -ENOMEM;
11561151

1152+
/*
1153+
* First try the EIP97 HIA version regs
1154+
* For the EIP197, this is guaranteed to NOT return any of the test
1155+
* values
1156+
*/
1157+
version = readl(priv->base + EIP97_HIA_AIC_BASE + EIP197_HIA_VERSION);
1158+
1159+
mask = 0; /* do not swap */
1160+
if (EIP197_REG_LO16(version) == EIP197_HIA_VERSION_LE) {
1161+
priv->hwconfig.hiaver = EIP197_VERSION_MASK(version);
1162+
} else if (EIP197_REG_HI16(version) == EIP197_HIA_VERSION_BE) {
1163+
/* read back byte-swapped, so complement byte swap bits */
1164+
mask = EIP197_MST_CTRL_BYTE_SWAP_BITS;
1165+
priv->hwconfig.hiaver = EIP197_VERSION_SWAP(version);
1166+
} else {
1167+
/* So it wasn't an EIP97 ... maybe it's an EIP197? */
1168+
version = readl(priv->base + EIP197_HIA_AIC_BASE +
1169+
EIP197_HIA_VERSION);
1170+
if (EIP197_REG_LO16(version) == EIP197_HIA_VERSION_LE) {
1171+
priv->hwconfig.hiaver = EIP197_VERSION_MASK(version);
1172+
priv->flags |= SAFEXCEL_HW_EIP197;
1173+
} else if (EIP197_REG_HI16(version) ==
1174+
EIP197_HIA_VERSION_BE) {
1175+
/* read back byte-swapped, so complement swap bits */
1176+
mask = EIP197_MST_CTRL_BYTE_SWAP_BITS;
1177+
priv->hwconfig.hiaver = EIP197_VERSION_SWAP(version);
1178+
priv->flags |= SAFEXCEL_HW_EIP197;
1179+
} else {
1180+
return -ENODEV;
1181+
}
1182+
}
1183+
1184+
/* Now initialize the reg offsets based on the probing info so far */
11571185
safexcel_init_register_offsets(priv);
11581186

1187+
/*
1188+
* If the version was read byte-swapped, we need to flip the device
1189+
* swapping Keep in mind here, though, that what we write will also be
1190+
* byte-swapped ...
1191+
*/
1192+
if (mask) {
1193+
val = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
1194+
val = val ^ (mask >> 24); /* toggle byte swap bits */
1195+
writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
1196+
}
1197+
1198+
/*
1199+
* We're not done probing yet! We may fall through to here if no HIA
1200+
* was found at all. So, with the endianness presumably correct now and
1201+
* the offsets setup, *really* probe for the EIP97/EIP197.
1202+
*/
1203+
version = readl(EIP197_GLOBAL(priv) + EIP197_VERSION);
1204+
if (((priv->flags & SAFEXCEL_HW_EIP197) &&
1205+
(EIP197_REG_LO16(version) != EIP197_VERSION_LE)) ||
1206+
((!(priv->flags & SAFEXCEL_HW_EIP197) &&
1207+
(EIP197_REG_LO16(version) != EIP97_VERSION_LE)))) {
1208+
/*
1209+
* We did not find the device that matched our initial probing
1210+
* (or our initial probing failed) Report appropriate error.
1211+
*/
1212+
return -ENODEV;
1213+
}
1214+
1215+
priv->hwconfig.hwver = EIP197_VERSION_MASK(version);
1216+
hwctg = version >> 28;
1217+
peid = version & 255;
1218+
1219+
/* Detect EIP96 packet engine and version */
1220+
version = readl(EIP197_PE(priv) + EIP197_PE_EIP96_VERSION(0));
1221+
if (EIP197_REG_LO16(version) != EIP96_VERSION_LE) {
1222+
dev_err(dev, "EIP%d: EIP96 not detected.\n", peid);
1223+
return -ENODEV;
1224+
}
1225+
priv->hwconfig.pever = EIP197_VERSION_MASK(version);
1226+
11591227
/* Get supported algorithms from EIP96 transform engine */
11601228
priv->hwconfig.algo_flags = readl(EIP197_PE(priv) +
11611229
EIP197_PE_EIP96_OPTIONS(0));
11621230

1163-
if (priv->version == EIP97IES_MRVL) {
1164-
peid = 97;
1165-
} else {
1166-
priv->flags |= EIP197_TRC_CACHE;
1167-
peid = 197;
1168-
}
1169-
1170-
/* Dump some debug information important during development */
1171-
dev_dbg(priv->dev, "Inside Secure EIP%d packetengine\n", peid);
1172-
dev_dbg(priv->dev, "Supported algorithms: %08x\n",
1173-
priv->hwconfig.algo_flags);
1231+
/* Print single info line describing what we just detected */
1232+
dev_info(priv->dev, "EIP%d:%x(%d)-HIA:%x,PE:%x,alg:%08x\n", peid,
1233+
priv->hwconfig.hwver, hwctg, priv->hwconfig.hiaver,
1234+
priv->hwconfig.pever, priv->hwconfig.algo_flags);
11741235

11751236
safexcel_configure(priv);
11761237

@@ -1522,7 +1583,6 @@ static const struct pci_device_id safexcel_pci_ids[] = {
15221583
{
15231584
PCI_DEVICE_SUB(PCI_VENDOR_ID_XILINX, 0x9038,
15241585
0x16ae, 0xc522),
1525-
/* assume EIP197B for now */
15261586
.driver_data = EIP197_DEVBRD,
15271587
},
15281588
{},

drivers/crypto/inside-secure/safexcel.h

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,17 @@
1414
#include <crypto/sha.h>
1515
#include <crypto/skcipher.h>
1616

17-
#define EIP197_HIA_VERSION_LE 0xca35
18-
#define EIP197_HIA_VERSION_BE 0x35ca
17+
#define EIP197_HIA_VERSION_BE 0xca35
18+
#define EIP197_HIA_VERSION_LE 0x35ca
19+
#define EIP97_VERSION_LE 0x9e61
20+
#define EIP197_VERSION_LE 0x3ac5
21+
#define EIP96_VERSION_LE 0x9f60
22+
#define EIP197_REG_LO16(reg) (reg & 0xffff)
23+
#define EIP197_REG_HI16(reg) ((reg >> 16) & 0xffff)
24+
#define EIP197_VERSION_MASK(reg) ((reg >> 16) & 0xfff)
25+
#define EIP197_VERSION_SWAP(reg) (((reg & 0xf0) << 4) | \
26+
((reg >> 4) & 0xf0) | \
27+
((reg >> 12) & 0xf))
1928

2029
/* Static configuration */
2130
#define EIP197_DEFAULT_RING_SIZE 400
@@ -70,6 +79,7 @@
7079
#define EIP197_HIA_DSE_THR(priv) ((priv)->base + (priv)->offsets.hia_dse_thr)
7180
#define EIP197_HIA_GEN_CFG(priv) ((priv)->base + (priv)->offsets.hia_gen_cfg)
7281
#define EIP197_PE(priv) ((priv)->base + (priv)->offsets.pe)
82+
#define EIP197_GLOBAL(priv) ((priv)->base + (priv)->offsets.global)
7383

7484
/* EIP197 base offsets */
7585
#define EIP197_HIA_AIC_BASE 0x90000
@@ -82,6 +92,7 @@
8292
#define EIP197_HIA_DSE_THR_BASE 0x8d040
8393
#define EIP197_HIA_GEN_CFG_BASE 0xf0000
8494
#define EIP197_PE_BASE 0xa0000
95+
#define EIP197_GLOBAL_BASE 0xf0000
8596

8697
/* EIP97 base offsets */
8798
#define EIP97_HIA_AIC_BASE 0x0
@@ -94,6 +105,7 @@
94105
#define EIP97_HIA_DSE_THR_BASE 0xf600
95106
#define EIP97_HIA_GEN_CFG_BASE 0x10000
96107
#define EIP97_PE_BASE 0x10000
108+
#define EIP97_GLOBAL_BASE 0x10000
97109

98110
/* CDR/RDR register offsets */
99111
#define EIP197_HIA_xDR_OFF(priv, r) (EIP197_HIA_AIC_xDR(priv) + (r) * 0x1000)
@@ -146,9 +158,11 @@
146158
#define EIP197_PE_EIP96_CONTEXT_CTRL(n) (0x1008 + (0x2000 * (n)))
147159
#define EIP197_PE_EIP96_CONTEXT_STAT(n) (0x100c + (0x2000 * (n)))
148160
#define EIP197_PE_EIP96_OPTIONS(n) (0x13f8 + (0x2000 * (n)))
161+
#define EIP197_PE_EIP96_VERSION(n) (0x13fc + (0x2000 * (n)))
149162
#define EIP197_PE_OUT_DBUF_THRES(n) (0x1c00 + (0x2000 * (n)))
150163
#define EIP197_PE_OUT_TBUF_THRES(n) (0x1d00 + (0x2000 * (n)))
151164
#define EIP197_MST_CTRL 0xfff4
165+
#define EIP197_VERSION 0xfffc
152166

153167
/* EIP197-specific registers, no indirection */
154168
#define EIP197_CLASSIFICATION_RAMS 0xe0000
@@ -252,6 +266,7 @@
252266
#define EIP197_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 20)
253267
#define EIP197_MST_CTRL_BYTE_SWAP BIT(24)
254268
#define EIP197_MST_CTRL_NO_BYTE_SWAP BIT(25)
269+
#define EIP197_MST_CTRL_BYTE_SWAP_BITS GENMASK(25, 24)
255270

256271
/* EIP197_PE_IN_DBUF/TBUF_THRES */
257272
#define EIP197_PE_IN_xBUF_THRES_MIN(n) ((n) << 8)
@@ -651,14 +666,19 @@ struct safexcel_register_offsets {
651666
u32 hia_dse_thr;
652667
u32 hia_gen_cfg;
653668
u32 pe;
669+
u32 global;
654670
};
655671

656672
enum safexcel_flags {
657-
EIP197_TRC_CACHE = BIT(0),
673+
EIP197_TRC_CACHE = BIT(0),
674+
SAFEXCEL_HW_EIP197 = BIT(1),
658675
};
659676

660677
struct safexcel_hwconfig {
661678
enum safexcel_eip_algorithms algo_flags;
679+
int hwver;
680+
int hiaver;
681+
int pever;
662682
};
663683

664684
struct safexcel_crypto_priv {

0 commit comments

Comments
 (0)