Skip to content

Commit 59e056c

Browse files
cotequeirozherbertx
authored andcommitted
crypto: qce - allow building only hashes/ciphers
Allow the user to choose whether to build support for all algorithms (default), hashes-only, or skciphers-only. The QCE engine does not appear to scale as well as the CPU to handle multiple crypto requests. While the ipq40xx chips have 4-core CPUs, the QCE handles only 2 requests in parallel. Ipsec throughput seems to improve when disabling either family of algorithms, sharing the load with the CPU. Enabling skciphers-only appears to work best. Signed-off-by: Eneas U de Queiroz <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 8ceda88 commit 59e056c

File tree

4 files changed

+193
-125
lines changed

4 files changed

+193
-125
lines changed

drivers/crypto/Kconfig

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,17 +618,72 @@ config CRYPTO_DEV_QCE
618618
tristate "Qualcomm crypto engine accelerator"
619619
depends on ARCH_QCOM || COMPILE_TEST
620620
depends on HAS_IOMEM
621+
help
622+
This driver supports Qualcomm crypto engine accelerator
623+
hardware. To compile this driver as a module, choose M here. The
624+
module will be called qcrypto.
625+
626+
config CRYPTO_DEV_QCE_SKCIPHER
627+
bool
628+
depends on CRYPTO_DEV_QCE
621629
select CRYPTO_AES
622630
select CRYPTO_LIB_DES
623631
select CRYPTO_ECB
624632
select CRYPTO_CBC
625633
select CRYPTO_XTS
626634
select CRYPTO_CTR
627635
select CRYPTO_SKCIPHER
628-
help
629-
This driver supports Qualcomm crypto engine accelerator
630-
hardware. To compile this driver as a module, choose M here. The
631-
module will be called qcrypto.
636+
637+
config CRYPTO_DEV_QCE_SHA
638+
bool
639+
depends on CRYPTO_DEV_QCE
640+
641+
choice
642+
prompt "Algorithms enabled for QCE acceleration"
643+
default CRYPTO_DEV_QCE_ENABLE_ALL
644+
depends on CRYPTO_DEV_QCE
645+
help
646+
This option allows to choose whether to build support for all algorihtms
647+
(default), hashes-only, or skciphers-only.
648+
649+
The QCE engine does not appear to scale as well as the CPU to handle
650+
multiple crypto requests. While the ipq40xx chips have 4-core CPUs, the
651+
QCE handles only 2 requests in parallel.
652+
653+
Ipsec throughput seems to improve when disabling either family of
654+
algorithms, sharing the load with the CPU. Enabling skciphers-only
655+
appears to work best.
656+
657+
config CRYPTO_DEV_QCE_ENABLE_ALL
658+
bool "All supported algorithms"
659+
select CRYPTO_DEV_QCE_SKCIPHER
660+
select CRYPTO_DEV_QCE_SHA
661+
help
662+
Enable all supported algorithms:
663+
- AES (CBC, CTR, ECB, XTS)
664+
- 3DES (CBC, ECB)
665+
- DES (CBC, ECB)
666+
- SHA1, HMAC-SHA1
667+
- SHA256, HMAC-SHA256
668+
669+
config CRYPTO_DEV_QCE_ENABLE_SKCIPHER
670+
bool "Symmetric-key ciphers only"
671+
select CRYPTO_DEV_QCE_SKCIPHER
672+
help
673+
Enable symmetric-key ciphers only:
674+
- AES (CBC, CTR, ECB, XTS)
675+
- 3DES (ECB, CBC)
676+
- DES (ECB, CBC)
677+
678+
config CRYPTO_DEV_QCE_ENABLE_SHA
679+
bool "Hash/HMAC only"
680+
select CRYPTO_DEV_QCE_SHA
681+
help
682+
Enable hashes/HMAC algorithms only:
683+
- SHA1, HMAC-SHA1
684+
- SHA256, HMAC-SHA256
685+
686+
endchoice
632687

633688
config CRYPTO_DEV_QCOM_RNG
634689
tristate "Qualcomm Random Number Generator Driver"

drivers/crypto/qce/Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
obj-$(CONFIG_CRYPTO_DEV_QCE) += qcrypto.o
33
qcrypto-objs := core.o \
44
common.o \
5-
dma.o \
6-
sha.o \
7-
skcipher.o
5+
dma.o
6+
7+
qcrypto-$(CONFIG_CRYPTO_DEV_QCE_SHA) += sha.o
8+
qcrypto-$(CONFIG_CRYPTO_DEV_QCE_SKCIPHER) += skcipher.o

drivers/crypto/qce/common.c

Lines changed: 126 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -45,52 +45,56 @@ qce_clear_array(struct qce_device *qce, u32 offset, unsigned int len)
4545
qce_write(qce, offset + i * sizeof(u32), 0);
4646
}
4747

48-
static u32 qce_encr_cfg(unsigned long flags, u32 aes_key_size)
48+
static u32 qce_config_reg(struct qce_device *qce, int little)
4949
{
50-
u32 cfg = 0;
50+
u32 beats = (qce->burst_size >> 3) - 1;
51+
u32 pipe_pair = qce->pipe_pair_id;
52+
u32 config;
5153

52-
if (IS_AES(flags)) {
53-
if (aes_key_size == AES_KEYSIZE_128)
54-
cfg |= ENCR_KEY_SZ_AES128 << ENCR_KEY_SZ_SHIFT;
55-
else if (aes_key_size == AES_KEYSIZE_256)
56-
cfg |= ENCR_KEY_SZ_AES256 << ENCR_KEY_SZ_SHIFT;
57-
}
54+
config = (beats << REQ_SIZE_SHIFT) & REQ_SIZE_MASK;
55+
config |= BIT(MASK_DOUT_INTR_SHIFT) | BIT(MASK_DIN_INTR_SHIFT) |
56+
BIT(MASK_OP_DONE_INTR_SHIFT) | BIT(MASK_ERR_INTR_SHIFT);
57+
config |= (pipe_pair << PIPE_SET_SELECT_SHIFT) & PIPE_SET_SELECT_MASK;
58+
config &= ~HIGH_SPD_EN_N_SHIFT;
5859

59-
if (IS_AES(flags))
60-
cfg |= ENCR_ALG_AES << ENCR_ALG_SHIFT;
61-
else if (IS_DES(flags) || IS_3DES(flags))
62-
cfg |= ENCR_ALG_DES << ENCR_ALG_SHIFT;
60+
if (little)
61+
config |= BIT(LITTLE_ENDIAN_MODE_SHIFT);
6362

64-
if (IS_DES(flags))
65-
cfg |= ENCR_KEY_SZ_DES << ENCR_KEY_SZ_SHIFT;
63+
return config;
64+
}
6665

67-
if (IS_3DES(flags))
68-
cfg |= ENCR_KEY_SZ_3DES << ENCR_KEY_SZ_SHIFT;
66+
void qce_cpu_to_be32p_array(__be32 *dst, const u8 *src, unsigned int len)
67+
{
68+
__be32 *d = dst;
69+
const u8 *s = src;
70+
unsigned int n;
6971

70-
switch (flags & QCE_MODE_MASK) {
71-
case QCE_MODE_ECB:
72-
cfg |= ENCR_MODE_ECB << ENCR_MODE_SHIFT;
73-
break;
74-
case QCE_MODE_CBC:
75-
cfg |= ENCR_MODE_CBC << ENCR_MODE_SHIFT;
76-
break;
77-
case QCE_MODE_CTR:
78-
cfg |= ENCR_MODE_CTR << ENCR_MODE_SHIFT;
79-
break;
80-
case QCE_MODE_XTS:
81-
cfg |= ENCR_MODE_XTS << ENCR_MODE_SHIFT;
82-
break;
83-
case QCE_MODE_CCM:
84-
cfg |= ENCR_MODE_CCM << ENCR_MODE_SHIFT;
85-
cfg |= LAST_CCM_XFR << LAST_CCM_SHIFT;
86-
break;
87-
default:
88-
return ~0;
72+
n = len / sizeof(u32);
73+
for (; n > 0; n--) {
74+
*d = cpu_to_be32p((const __u32 *) s);
75+
s += sizeof(__u32);
76+
d++;
8977
}
78+
}
9079

91-
return cfg;
80+
static void qce_setup_config(struct qce_device *qce)
81+
{
82+
u32 config;
83+
84+
/* get big endianness */
85+
config = qce_config_reg(qce, 0);
86+
87+
/* clear status */
88+
qce_write(qce, REG_STATUS, 0);
89+
qce_write(qce, REG_CONFIG, config);
90+
}
91+
92+
static inline void qce_crypto_go(struct qce_device *qce)
93+
{
94+
qce_write(qce, REG_GOPROC, BIT(GO_SHIFT) | BIT(RESULTS_DUMP_SHIFT));
9295
}
9396

97+
#ifdef CONFIG_CRYPTO_DEV_QCE_SHA
9498
static u32 qce_auth_cfg(unsigned long flags, u32 key_size)
9599
{
96100
u32 cfg = 0;
@@ -137,88 +141,6 @@ static u32 qce_auth_cfg(unsigned long flags, u32 key_size)
137141
return cfg;
138142
}
139143

140-
static u32 qce_config_reg(struct qce_device *qce, int little)
141-
{
142-
u32 beats = (qce->burst_size >> 3) - 1;
143-
u32 pipe_pair = qce->pipe_pair_id;
144-
u32 config;
145-
146-
config = (beats << REQ_SIZE_SHIFT) & REQ_SIZE_MASK;
147-
config |= BIT(MASK_DOUT_INTR_SHIFT) | BIT(MASK_DIN_INTR_SHIFT) |
148-
BIT(MASK_OP_DONE_INTR_SHIFT) | BIT(MASK_ERR_INTR_SHIFT);
149-
config |= (pipe_pair << PIPE_SET_SELECT_SHIFT) & PIPE_SET_SELECT_MASK;
150-
config &= ~HIGH_SPD_EN_N_SHIFT;
151-
152-
if (little)
153-
config |= BIT(LITTLE_ENDIAN_MODE_SHIFT);
154-
155-
return config;
156-
}
157-
158-
void qce_cpu_to_be32p_array(__be32 *dst, const u8 *src, unsigned int len)
159-
{
160-
__be32 *d = dst;
161-
const u8 *s = src;
162-
unsigned int n;
163-
164-
n = len / sizeof(u32);
165-
for (; n > 0; n--) {
166-
*d = cpu_to_be32p((const __u32 *) s);
167-
s += sizeof(__u32);
168-
d++;
169-
}
170-
}
171-
172-
static void qce_xts_swapiv(__be32 *dst, const u8 *src, unsigned int ivsize)
173-
{
174-
u8 swap[QCE_AES_IV_LENGTH];
175-
u32 i, j;
176-
177-
if (ivsize > QCE_AES_IV_LENGTH)
178-
return;
179-
180-
memset(swap, 0, QCE_AES_IV_LENGTH);
181-
182-
for (i = (QCE_AES_IV_LENGTH - ivsize), j = ivsize - 1;
183-
i < QCE_AES_IV_LENGTH; i++, j--)
184-
swap[i] = src[j];
185-
186-
qce_cpu_to_be32p_array(dst, swap, QCE_AES_IV_LENGTH);
187-
}
188-
189-
static void qce_xtskey(struct qce_device *qce, const u8 *enckey,
190-
unsigned int enckeylen, unsigned int cryptlen)
191-
{
192-
u32 xtskey[QCE_MAX_CIPHER_KEY_SIZE / sizeof(u32)] = {0};
193-
unsigned int xtsklen = enckeylen / (2 * sizeof(u32));
194-
unsigned int xtsdusize;
195-
196-
qce_cpu_to_be32p_array((__be32 *)xtskey, enckey + enckeylen / 2,
197-
enckeylen / 2);
198-
qce_write_array(qce, REG_ENCR_XTS_KEY0, xtskey, xtsklen);
199-
200-
/* xts du size 512B */
201-
xtsdusize = min_t(u32, QCE_SECTOR_SIZE, cryptlen);
202-
qce_write(qce, REG_ENCR_XTS_DU_SIZE, xtsdusize);
203-
}
204-
205-
static void qce_setup_config(struct qce_device *qce)
206-
{
207-
u32 config;
208-
209-
/* get big endianness */
210-
config = qce_config_reg(qce, 0);
211-
212-
/* clear status */
213-
qce_write(qce, REG_STATUS, 0);
214-
qce_write(qce, REG_CONFIG, config);
215-
}
216-
217-
static inline void qce_crypto_go(struct qce_device *qce)
218-
{
219-
qce_write(qce, REG_GOPROC, BIT(GO_SHIFT) | BIT(RESULTS_DUMP_SHIFT));
220-
}
221-
222144
static int qce_setup_regs_ahash(struct crypto_async_request *async_req,
223145
u32 totallen, u32 offset)
224146
{
@@ -303,6 +225,87 @@ static int qce_setup_regs_ahash(struct crypto_async_request *async_req,
303225

304226
return 0;
305227
}
228+
#endif
229+
230+
#ifdef CONFIG_CRYPTO_DEV_QCE_SKCIPHER
231+
static u32 qce_encr_cfg(unsigned long flags, u32 aes_key_size)
232+
{
233+
u32 cfg = 0;
234+
235+
if (IS_AES(flags)) {
236+
if (aes_key_size == AES_KEYSIZE_128)
237+
cfg |= ENCR_KEY_SZ_AES128 << ENCR_KEY_SZ_SHIFT;
238+
else if (aes_key_size == AES_KEYSIZE_256)
239+
cfg |= ENCR_KEY_SZ_AES256 << ENCR_KEY_SZ_SHIFT;
240+
}
241+
242+
if (IS_AES(flags))
243+
cfg |= ENCR_ALG_AES << ENCR_ALG_SHIFT;
244+
else if (IS_DES(flags) || IS_3DES(flags))
245+
cfg |= ENCR_ALG_DES << ENCR_ALG_SHIFT;
246+
247+
if (IS_DES(flags))
248+
cfg |= ENCR_KEY_SZ_DES << ENCR_KEY_SZ_SHIFT;
249+
250+
if (IS_3DES(flags))
251+
cfg |= ENCR_KEY_SZ_3DES << ENCR_KEY_SZ_SHIFT;
252+
253+
switch (flags & QCE_MODE_MASK) {
254+
case QCE_MODE_ECB:
255+
cfg |= ENCR_MODE_ECB << ENCR_MODE_SHIFT;
256+
break;
257+
case QCE_MODE_CBC:
258+
cfg |= ENCR_MODE_CBC << ENCR_MODE_SHIFT;
259+
break;
260+
case QCE_MODE_CTR:
261+
cfg |= ENCR_MODE_CTR << ENCR_MODE_SHIFT;
262+
break;
263+
case QCE_MODE_XTS:
264+
cfg |= ENCR_MODE_XTS << ENCR_MODE_SHIFT;
265+
break;
266+
case QCE_MODE_CCM:
267+
cfg |= ENCR_MODE_CCM << ENCR_MODE_SHIFT;
268+
cfg |= LAST_CCM_XFR << LAST_CCM_SHIFT;
269+
break;
270+
default:
271+
return ~0;
272+
}
273+
274+
return cfg;
275+
}
276+
277+
static void qce_xts_swapiv(__be32 *dst, const u8 *src, unsigned int ivsize)
278+
{
279+
u8 swap[QCE_AES_IV_LENGTH];
280+
u32 i, j;
281+
282+
if (ivsize > QCE_AES_IV_LENGTH)
283+
return;
284+
285+
memset(swap, 0, QCE_AES_IV_LENGTH);
286+
287+
for (i = (QCE_AES_IV_LENGTH - ivsize), j = ivsize - 1;
288+
i < QCE_AES_IV_LENGTH; i++, j--)
289+
swap[i] = src[j];
290+
291+
qce_cpu_to_be32p_array(dst, swap, QCE_AES_IV_LENGTH);
292+
}
293+
294+
static void qce_xtskey(struct qce_device *qce, const u8 *enckey,
295+
unsigned int enckeylen, unsigned int cryptlen)
296+
{
297+
u32 xtskey[QCE_MAX_CIPHER_KEY_SIZE / sizeof(u32)] = {0};
298+
unsigned int xtsklen = enckeylen / (2 * sizeof(u32));
299+
unsigned int xtsdusize;
300+
301+
qce_cpu_to_be32p_array((__be32 *)xtskey, enckey + enckeylen / 2,
302+
enckeylen / 2);
303+
qce_write_array(qce, REG_ENCR_XTS_KEY0, xtskey, xtsklen);
304+
305+
/* xts du size 512B */
306+
xtsdusize = min_t(u32, QCE_SECTOR_SIZE, cryptlen);
307+
qce_write(qce, REG_ENCR_XTS_DU_SIZE, xtsdusize);
308+
}
306309

307310
static int qce_setup_regs_skcipher(struct crypto_async_request *async_req,
308311
u32 totallen, u32 offset)
@@ -384,15 +387,20 @@ static int qce_setup_regs_skcipher(struct crypto_async_request *async_req,
384387

385388
return 0;
386389
}
390+
#endif
387391

388392
int qce_start(struct crypto_async_request *async_req, u32 type, u32 totallen,
389393
u32 offset)
390394
{
391395
switch (type) {
396+
#ifdef CONFIG_CRYPTO_DEV_QCE_SKCIPHER
392397
case CRYPTO_ALG_TYPE_SKCIPHER:
393398
return qce_setup_regs_skcipher(async_req, totallen, offset);
399+
#endif
400+
#ifdef CONFIG_CRYPTO_DEV_QCE_SHA
394401
case CRYPTO_ALG_TYPE_AHASH:
395402
return qce_setup_regs_ahash(async_req, totallen, offset);
403+
#endif
396404
default:
397405
return -EINVAL;
398406
}

drivers/crypto/qce/core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@
2222
#define QCE_QUEUE_LENGTH 1
2323

2424
static const struct qce_algo_ops *qce_ops[] = {
25+
#ifdef CONFIG_CRYPTO_DEV_QCE_SKCIPHER
2526
&skcipher_ops,
27+
#endif
28+
#ifdef CONFIG_CRYPTO_DEV_QCE_SHA
2629
&ahash_ops,
30+
#endif
2731
};
2832

2933
static void qce_unregister_algs(struct qce_device *qce)

0 commit comments

Comments
 (0)