Skip to content

Commit e052f18

Browse files
committed
driver:aes: add dma support for AES encryption and decryption
Add optional config SECURE_DMA_SUPPOR for secure. Add XDMA support for AES encrytion and decryption. Signed-off-by: Li Bin <bin.li@microchip.com>
1 parent 84ac2b3 commit e052f18

File tree

3 files changed

+88
-5
lines changed

3 files changed

+88
-5
lines changed

Config.in.secure

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ config SECURE
1313
menu "Secure Mode Options"
1414
depends on SECURE
1515

16+
config SECURE_DMA_SUPPORT
17+
bool "Support DMA transfer"
18+
default n
19+
depends on XDMAC
20+
1621
choice
1722
prompt "Key Size"
1823
default AES_KEY_SIZE_256

driver/at91_aes.c

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
#include "debug.h"
1010
#include "board.h"
1111
#include "string.h"
12-
12+
#ifdef CONFIG_SECURE_DMA_SUPPORT
13+
#include "xdmac.h"
14+
#include "div.h"
15+
#endif
1316
#define swab32(x) ( \
1417
(((x) & 0x000000ffUL) << 24) | \
1518
(((x) & 0x0000ff00UL) << 8) | \
@@ -81,8 +84,11 @@ static inline int at91_aes_set_opmode(at91_aes_operation_t operation,
8184
unsigned int *data_width,
8285
unsigned int *chunk_size)
8386
{
87+
#ifdef CONFIG_SECURE_DMA_SUPPORT
88+
unsigned int mr = AES_MR_CKEY_PASSWD | AES_MR_SMOD_IDATAR0_START;
89+
#else
8490
unsigned int mr = AES_MR_CKEY_PASSWD | AES_MR_SMOD_AUTO_START;
85-
91+
#endif
8692
switch (operation) {
8793
case AT91_AES_OP_DECRYPT:
8894
mr |= AES_MR_CIPHER_DECRYPT;
@@ -216,7 +222,7 @@ static inline int at91_aes_set_key(at91_aes_key_size_t key_size,
216222
return 0;
217223
}
218224

219-
225+
#if !defined (CONFIG_SECURE_DMA_SUPPORT)
220226
static void at91_aes_compute_pio_long(unsigned int chunk_size,
221227
unsigned int num_blocks,
222228
unsigned int is_mac,
@@ -310,6 +316,59 @@ static void at91_aes_compute_pio(unsigned int data_width,
310316
break;
311317
}
312318
}
319+
#endif
320+
321+
#ifdef CONFIG_SECURE_DMA_SUPPORT
322+
static int at91_aes_compute_dma(unsigned int data_width,
323+
unsigned int chunk_size,
324+
unsigned int num_blocks,
325+
unsigned int is_mac,
326+
const void *input,
327+
void *output)
328+
{
329+
struct xdmac_hwcfg hwcfg_in, hwcfg_out;
330+
struct xdmac_cfg cfg;
331+
struct xdmac_transfer_cfg transfer_cfg_in, transfer_cfg_out;
332+
int ret;
333+
334+
cfg.data_width = (data_width == 4) ? DMA_DATA_WIDTH_WORD :\
335+
((data_width == 2) ? DMA_DATA_WIDTH_HALF_WORD : DMA_DATA_WIDTH_BYTE);
336+
cfg.chunk_size = (chunk_size == 4) ? DMA_CHUNK_SIZE_4 :\
337+
((chunk_size == 2) ? DMA_CHUNK_SIZE_2 : DMA_CHUNK_SIZE_1);
338+
/* Configure DMA for AES transfer */
339+
hwcfg_in.cid = 0;
340+
hwcfg_in.txif = AES_XDMA_TXIF;
341+
hwcfg_in.src_is_periph = 0;
342+
hwcfg_in.dst_is_periph = 1;
343+
cfg.incr_saddr = 1;
344+
cfg.incr_daddr = 0;
345+
transfer_cfg_in.saddr = (void *)input;
346+
transfer_cfg_in.daddr = (void *)(AT91C_BASE_AES + AES_IDATAR0);
347+
transfer_cfg_in.len = div(num_blocks, 1 << cfg.data_width);
348+
xdmac_configure_transfer(&hwcfg_in, &cfg);
349+
350+
/* Configure DMA for AES receive */
351+
hwcfg_out.cid = 1;
352+
hwcfg_out.rxif = AES_XDMA_RXIF;
353+
hwcfg_out.src_is_periph = 1;
354+
hwcfg_out.dst_is_periph = 0;
355+
cfg.incr_saddr = 0;
356+
cfg.incr_daddr = 1;
357+
transfer_cfg_out.saddr = (void *)(AT91C_BASE_AES + AES_ODATAR0);
358+
transfer_cfg_out.daddr = (void *)output;
359+
transfer_cfg_out.len = div(num_blocks, 1 << cfg.data_width);
360+
xdmac_configure_transfer(&hwcfg_out, &cfg);
361+
362+
xdmac_transfer_start(&hwcfg_in, &transfer_cfg_in);
363+
xdmac_transfer_start(&hwcfg_out, &transfer_cfg_out);
364+
365+
ret = xdmac_transfer_wait_for_completion(&hwcfg_out);
366+
367+
xdmac_transfer_stop(&hwcfg_in);
368+
xdmac_transfer_stop(&hwcfg_out);
369+
return ret;
370+
}
371+
#endif
313372

314373
static inline unsigned int at91_aes_length2blocks(unsigned int data_length,
315374
unsigned int block_size)
@@ -346,10 +405,13 @@ static inline unsigned int at91_aes_length2blocks(unsigned int data_length,
346405
return (data_length >> shift) + ((data_length & mask) ? 1 : 0);
347406
}
348407

408+
349409
static int at91_aes_process(const at91_aes_params_t *params)
350410
{
351411
unsigned int data_width, chunk_size;
412+
#if !defined (CONFIG_SECURE_DMA_SUPPORT)
352413
unsigned int block_size, num_blocks;
414+
#endif
353415
unsigned int is_mac = (params->operation == AT91_AES_OP_MAC);
354416

355417
/* Reset AES */
@@ -367,12 +429,15 @@ static int at91_aes_process(const at91_aes_params_t *params)
367429

368430

369431
aes_writel(AES_IER, AES_INT_DATRDY);
370-
432+
#ifdef CONFIG_SECURE_DMA_SUPPORT
433+
at91_aes_compute_dma(data_width, chunk_size, params->data_length,
434+
is_mac, params->input, params->output);
435+
#else
371436
block_size = data_width * chunk_size;
372437
num_blocks = at91_aes_length2blocks(params->data_length, block_size);
373438
at91_aes_compute_pio(data_width, chunk_size, num_blocks,
374439
is_mac, params->input, params->output);
375-
440+
#endif
376441
if (is_mac) {
377442
unsigned int reg, i;
378443

include/arch/at91_aes.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,17 @@
101101
#define AES_INT_WOR_RD_ACCESS (0x5UL << 12)
102102
#define AES_INT_TAGRDY (0x1UL << 16) /* GCM Tag Ready */
103103

104+
#if defined(CONFIG_SAMA7G5) || defined(CONFIG_SAMA7D65)
105+
#define AES_XDMA_TXIF 1
106+
#define AES_XDMA_RXIF 2
107+
#endif
108+
#if defined(CONFIG_SAM9X60) || defined(CONFIG_SAM9X7)
109+
#define AES_XDMA_TXIF 32
110+
#define AES_XDMA_RXIF 33
111+
#endif
112+
#if defined(CONFIG_SAMA5D2)
113+
#define AES_XDMA_TXIF 26
114+
#define AES_XDMA_RXIF 27
115+
#endif
116+
104117
#endif /* #ifndef __AT91_AES_H__ */

0 commit comments

Comments
 (0)