You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
crypto: ccree - introduce CryptoCell driver
Introduce basic low level Arm TrustZone CryptoCell HW support. This first patch doesn't actually register any Crypto API transformations, these will follow up in the next patch. This first revision supports the CC 712 REE component. Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
committed by
Herbert Xu
parent
e294ca1cca
commit
4c3f97276e
@@ -730,4 +730,31 @@ config CRYPTO_DEV_ARTPEC6
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
||||
config CRYPTO_DEV_CCREE
|
||||
tristate "Support for ARM TrustZone CryptoCell family of security processors"
|
||||
depends on CRYPTO && CRYPTO_HW && OF && HAS_DMA
|
||||
default n
|
||||
select CRYPTO_HASH
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_DES
|
||||
select CRYPTO_AEAD
|
||||
select CRYPTO_AUTHENC
|
||||
select CRYPTO_SHA1
|
||||
select CRYPTO_MD5
|
||||
select CRYPTO_SHA256
|
||||
select CRYPTO_SHA512
|
||||
select CRYPTO_HMAC
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_CBC
|
||||
select CRYPTO_ECB
|
||||
select CRYPTO_CTR
|
||||
select CRYPTO_XTS
|
||||
help
|
||||
Say 'Y' to enable a driver for the Arm TrustZone CryptoCell
|
||||
family of processors. Currently only the CryptoCell 712 REE
|
||||
is supported.
|
||||
Choose this if you wish to use hardware acceleration of
|
||||
cryptographic operations on the system REE.
|
||||
If unsure say Y.
|
||||
|
||||
endif # CRYPTO_HW
|
||||
|
||||
@@ -6,6 +6,7 @@ obj-$(CONFIG_CRYPTO_DEV_ATMEL_ECC) += atmel-ecc.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_BFIN_CRC) += bfin_crc.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_CAVIUM_ZIP) += cavium/
|
||||
obj-$(CONFIG_CRYPTO_DEV_CCP) += ccp/
|
||||
obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/
|
||||
obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chelsio/
|
||||
obj-$(CONFIG_CRYPTO_DEV_CPT) += cavium/cpt/
|
||||
obj-$(CONFIG_CRYPTO_DEV_NITROX) += cavium/nitrox/
|
||||
|
||||
6
drivers/crypto/ccree/Makefile
Normal file
6
drivers/crypto/ccree/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_CRYPTO_DEV_CCREE) := ccree.o
|
||||
ccree-y := cc_driver.o cc_buffer_mgr.o cc_request_mgr.o cc_ivgen.o cc_sram_mgr.o
|
||||
ccree-$(CONFIG_DEBUG_FS) += cc_debugfs.o
|
||||
ccree-$(CONFIG_PM) += cc_pm.o
|
||||
387
drivers/crypto/ccree/cc_buffer_mgr.c
Normal file
387
drivers/crypto/ccree/cc_buffer_mgr.c
Normal file
@@ -0,0 +1,387 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#include <crypto/authenc.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <linux/dmapool.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include "cc_buffer_mgr.h"
|
||||
#include "cc_lli_defs.h"
|
||||
|
||||
enum dma_buffer_type {
|
||||
DMA_NULL_TYPE = -1,
|
||||
DMA_SGL_TYPE = 1,
|
||||
DMA_BUFF_TYPE = 2,
|
||||
};
|
||||
|
||||
struct buff_mgr_handle {
|
||||
struct dma_pool *mlli_buffs_pool;
|
||||
};
|
||||
|
||||
union buffer_array_entry {
|
||||
struct scatterlist *sgl;
|
||||
dma_addr_t buffer_dma;
|
||||
};
|
||||
|
||||
struct buffer_array {
|
||||
unsigned int num_of_buffers;
|
||||
union buffer_array_entry entry[MAX_NUM_OF_BUFFERS_IN_MLLI];
|
||||
unsigned int offset[MAX_NUM_OF_BUFFERS_IN_MLLI];
|
||||
int nents[MAX_NUM_OF_BUFFERS_IN_MLLI];
|
||||
int total_data_len[MAX_NUM_OF_BUFFERS_IN_MLLI];
|
||||
enum dma_buffer_type type[MAX_NUM_OF_BUFFERS_IN_MLLI];
|
||||
bool is_last[MAX_NUM_OF_BUFFERS_IN_MLLI];
|
||||
u32 *mlli_nents[MAX_NUM_OF_BUFFERS_IN_MLLI];
|
||||
};
|
||||
|
||||
static inline char *cc_dma_buf_type(enum cc_req_dma_buf_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case CC_DMA_BUF_NULL:
|
||||
return "BUF_NULL";
|
||||
case CC_DMA_BUF_DLLI:
|
||||
return "BUF_DLLI";
|
||||
case CC_DMA_BUF_MLLI:
|
||||
return "BUF_MLLI";
|
||||
default:
|
||||
return "BUF_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cc_get_sgl_nents() - Get scatterlist number of entries.
|
||||
*
|
||||
* @sg_list: SG list
|
||||
* @nbytes: [IN] Total SGL data bytes.
|
||||
* @lbytes: [OUT] Returns the amount of bytes at the last entry
|
||||
*/
|
||||
static unsigned int cc_get_sgl_nents(struct device *dev,
|
||||
struct scatterlist *sg_list,
|
||||
unsigned int nbytes, u32 *lbytes,
|
||||
bool *is_chained)
|
||||
{
|
||||
unsigned int nents = 0;
|
||||
|
||||
while (nbytes && sg_list) {
|
||||
if (sg_list->length) {
|
||||
nents++;
|
||||
/* get the number of bytes in the last entry */
|
||||
*lbytes = nbytes;
|
||||
nbytes -= (sg_list->length > nbytes) ?
|
||||
nbytes : sg_list->length;
|
||||
sg_list = sg_next(sg_list);
|
||||
} else {
|
||||
sg_list = (struct scatterlist *)sg_page(sg_list);
|
||||
if (is_chained)
|
||||
*is_chained = true;
|
||||
}
|
||||
}
|
||||
dev_dbg(dev, "nents %d last bytes %d\n", nents, *lbytes);
|
||||
return nents;
|
||||
}
|
||||
|
||||
/**
|
||||
* cc_zero_sgl() - Zero scatter scatter list data.
|
||||
*
|
||||
* @sgl:
|
||||
*/
|
||||
void cc_zero_sgl(struct scatterlist *sgl, u32 data_len)
|
||||
{
|
||||
struct scatterlist *current_sg = sgl;
|
||||
int sg_index = 0;
|
||||
|
||||
while (sg_index <= data_len) {
|
||||
if (!current_sg) {
|
||||
/* reached the end of the sgl --> just return back */
|
||||
return;
|
||||
}
|
||||
memset(sg_virt(current_sg), 0, current_sg->length);
|
||||
sg_index += current_sg->length;
|
||||
current_sg = sg_next(current_sg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cc_copy_sg_portion() - Copy scatter list data,
|
||||
* from to_skip to end, to dest and vice versa
|
||||
*
|
||||
* @dest:
|
||||
* @sg:
|
||||
* @to_skip:
|
||||
* @end:
|
||||
* @direct:
|
||||
*/
|
||||
void cc_copy_sg_portion(struct device *dev, u8 *dest, struct scatterlist *sg,
|
||||
u32 to_skip, u32 end, enum cc_sg_cpy_direct direct)
|
||||
{
|
||||
u32 nents, lbytes;
|
||||
|
||||
nents = cc_get_sgl_nents(dev, sg, end, &lbytes, NULL);
|
||||
sg_copy_buffer(sg, nents, (void *)dest, (end - to_skip + 1), to_skip,
|
||||
(direct == CC_SG_TO_BUF));
|
||||
}
|
||||
|
||||
static int cc_render_buff_to_mlli(struct device *dev, dma_addr_t buff_dma,
|
||||
u32 buff_size, u32 *curr_nents,
|
||||
u32 **mlli_entry_pp)
|
||||
{
|
||||
u32 *mlli_entry_p = *mlli_entry_pp;
|
||||
u32 new_nents;
|
||||
|
||||
/* Verify there is no memory overflow*/
|
||||
new_nents = (*curr_nents + buff_size / CC_MAX_MLLI_ENTRY_SIZE + 1);
|
||||
if (new_nents > MAX_NUM_OF_TOTAL_MLLI_ENTRIES)
|
||||
return -ENOMEM;
|
||||
|
||||
/*handle buffer longer than 64 kbytes */
|
||||
while (buff_size > CC_MAX_MLLI_ENTRY_SIZE) {
|
||||
cc_lli_set_addr(mlli_entry_p, buff_dma);
|
||||
cc_lli_set_size(mlli_entry_p, CC_MAX_MLLI_ENTRY_SIZE);
|
||||
dev_dbg(dev, "entry[%d]: single_buff=0x%08X size=%08X\n",
|
||||
*curr_nents, mlli_entry_p[LLI_WORD0_OFFSET],
|
||||
mlli_entry_p[LLI_WORD1_OFFSET]);
|
||||
buff_dma += CC_MAX_MLLI_ENTRY_SIZE;
|
||||
buff_size -= CC_MAX_MLLI_ENTRY_SIZE;
|
||||
mlli_entry_p = mlli_entry_p + 2;
|
||||
(*curr_nents)++;
|
||||
}
|
||||
/*Last entry */
|
||||
cc_lli_set_addr(mlli_entry_p, buff_dma);
|
||||
cc_lli_set_size(mlli_entry_p, buff_size);
|
||||
dev_dbg(dev, "entry[%d]: single_buff=0x%08X size=%08X\n",
|
||||
*curr_nents, mlli_entry_p[LLI_WORD0_OFFSET],
|
||||
mlli_entry_p[LLI_WORD1_OFFSET]);
|
||||
mlli_entry_p = mlli_entry_p + 2;
|
||||
*mlli_entry_pp = mlli_entry_p;
|
||||
(*curr_nents)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cc_render_sg_to_mlli(struct device *dev, struct scatterlist *sgl,
|
||||
u32 sgl_data_len, u32 sgl_offset,
|
||||
u32 *curr_nents, u32 **mlli_entry_pp)
|
||||
{
|
||||
struct scatterlist *curr_sgl = sgl;
|
||||
u32 *mlli_entry_p = *mlli_entry_pp;
|
||||
s32 rc = 0;
|
||||
|
||||
for ( ; (curr_sgl && sgl_data_len);
|
||||
curr_sgl = sg_next(curr_sgl)) {
|
||||
u32 entry_data_len =
|
||||
(sgl_data_len > sg_dma_len(curr_sgl) - sgl_offset) ?
|
||||
sg_dma_len(curr_sgl) - sgl_offset :
|
||||
sgl_data_len;
|
||||
sgl_data_len -= entry_data_len;
|
||||
rc = cc_render_buff_to_mlli(dev, sg_dma_address(curr_sgl) +
|
||||
sgl_offset, entry_data_len,
|
||||
curr_nents, &mlli_entry_p);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
sgl_offset = 0;
|
||||
}
|
||||
*mlli_entry_pp = mlli_entry_p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cc_generate_mlli(struct device *dev, struct buffer_array *sg_data,
|
||||
struct mlli_params *mlli_params, gfp_t flags)
|
||||
{
|
||||
u32 *mlli_p;
|
||||
u32 total_nents = 0, prev_total_nents = 0;
|
||||
int rc = 0, i;
|
||||
|
||||
dev_dbg(dev, "NUM of SG's = %d\n", sg_data->num_of_buffers);
|
||||
|
||||
/* Allocate memory from the pointed pool */
|
||||
mlli_params->mlli_virt_addr =
|
||||
dma_pool_alloc(mlli_params->curr_pool, flags,
|
||||
&mlli_params->mlli_dma_addr);
|
||||
if (!mlli_params->mlli_virt_addr) {
|
||||
dev_err(dev, "dma_pool_alloc() failed\n");
|
||||
rc = -ENOMEM;
|
||||
goto build_mlli_exit;
|
||||
}
|
||||
/* Point to start of MLLI */
|
||||
mlli_p = (u32 *)mlli_params->mlli_virt_addr;
|
||||
/* go over all SG's and link it to one MLLI table */
|
||||
for (i = 0; i < sg_data->num_of_buffers; i++) {
|
||||
union buffer_array_entry *entry = &sg_data->entry[i];
|
||||
u32 tot_len = sg_data->total_data_len[i];
|
||||
u32 offset = sg_data->offset[i];
|
||||
|
||||
if (sg_data->type[i] == DMA_SGL_TYPE)
|
||||
rc = cc_render_sg_to_mlli(dev, entry->sgl, tot_len,
|
||||
offset, &total_nents,
|
||||
&mlli_p);
|
||||
else /*DMA_BUFF_TYPE*/
|
||||
rc = cc_render_buff_to_mlli(dev, entry->buffer_dma,
|
||||
tot_len, &total_nents,
|
||||
&mlli_p);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* set last bit in the current table */
|
||||
if (sg_data->mlli_nents[i]) {
|
||||
/*Calculate the current MLLI table length for the
|
||||
*length field in the descriptor
|
||||
*/
|
||||
*sg_data->mlli_nents[i] +=
|
||||
(total_nents - prev_total_nents);
|
||||
prev_total_nents = total_nents;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set MLLI size for the bypass operation */
|
||||
mlli_params->mlli_len = (total_nents * LLI_ENTRY_BYTE_SIZE);
|
||||
|
||||
dev_dbg(dev, "MLLI params: virt_addr=%pK dma_addr=%pad mlli_len=0x%X\n",
|
||||
mlli_params->mlli_virt_addr, &mlli_params->mlli_dma_addr,
|
||||
mlli_params->mlli_len);
|
||||
|
||||
build_mlli_exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void cc_add_sg_entry(struct device *dev, struct buffer_array *sgl_data,
|
||||
unsigned int nents, struct scatterlist *sgl,
|
||||
unsigned int data_len, unsigned int data_offset,
|
||||
bool is_last_table, u32 *mlli_nents)
|
||||
{
|
||||
unsigned int index = sgl_data->num_of_buffers;
|
||||
|
||||
dev_dbg(dev, "index=%u nents=%u sgl=%pK data_len=0x%08X is_last=%d\n",
|
||||
index, nents, sgl, data_len, is_last_table);
|
||||
sgl_data->nents[index] = nents;
|
||||
sgl_data->entry[index].sgl = sgl;
|
||||
sgl_data->offset[index] = data_offset;
|
||||
sgl_data->total_data_len[index] = data_len;
|
||||
sgl_data->type[index] = DMA_SGL_TYPE;
|
||||
sgl_data->is_last[index] = is_last_table;
|
||||
sgl_data->mlli_nents[index] = mlli_nents;
|
||||
if (sgl_data->mlli_nents[index])
|
||||
*sgl_data->mlli_nents[index] = 0;
|
||||
sgl_data->num_of_buffers++;
|
||||
}
|
||||
|
||||
static int cc_dma_map_sg(struct device *dev, struct scatterlist *sg, u32 nents,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
u32 i, j;
|
||||
struct scatterlist *l_sg = sg;
|
||||
|
||||
for (i = 0; i < nents; i++) {
|
||||
if (!l_sg)
|
||||
break;
|
||||
if (dma_map_sg(dev, l_sg, 1, direction) != 1) {
|
||||
dev_err(dev, "dma_map_page() sg buffer failed\n");
|
||||
goto err;
|
||||
}
|
||||
l_sg = sg_next(l_sg);
|
||||
}
|
||||
return nents;
|
||||
|
||||
err:
|
||||
/* Restore mapped parts */
|
||||
for (j = 0; j < i; j++) {
|
||||
if (!sg)
|
||||
break;
|
||||
dma_unmap_sg(dev, sg, 1, direction);
|
||||
sg = sg_next(sg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cc_map_sg(struct device *dev, struct scatterlist *sg,
|
||||
unsigned int nbytes, int direction, u32 *nents,
|
||||
u32 max_sg_nents, u32 *lbytes, u32 *mapped_nents)
|
||||
{
|
||||
bool is_chained = false;
|
||||
|
||||
if (sg_is_last(sg)) {
|
||||
/* One entry only case -set to DLLI */
|
||||
if (dma_map_sg(dev, sg, 1, direction) != 1) {
|
||||
dev_err(dev, "dma_map_sg() single buffer failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
dev_dbg(dev, "Mapped sg: dma_address=%pad page=%p addr=%pK offset=%u length=%u\n",
|
||||
&sg_dma_address(sg), sg_page(sg), sg_virt(sg),
|
||||
sg->offset, sg->length);
|
||||
*lbytes = nbytes;
|
||||
*nents = 1;
|
||||
*mapped_nents = 1;
|
||||
} else { /*sg_is_last*/
|
||||
*nents = cc_get_sgl_nents(dev, sg, nbytes, lbytes,
|
||||
&is_chained);
|
||||
if (*nents > max_sg_nents) {
|
||||
*nents = 0;
|
||||
dev_err(dev, "Too many fragments. current %d max %d\n",
|
||||
*nents, max_sg_nents);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!is_chained) {
|
||||
/* In case of mmu the number of mapped nents might
|
||||
* be changed from the original sgl nents
|
||||
*/
|
||||
*mapped_nents = dma_map_sg(dev, sg, *nents, direction);
|
||||
if (*mapped_nents == 0) {
|
||||
*nents = 0;
|
||||
dev_err(dev, "dma_map_sg() sg buffer failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
/*In this case the driver maps entry by entry so it
|
||||
* must have the same nents before and after map
|
||||
*/
|
||||
*mapped_nents = cc_dma_map_sg(dev, sg, *nents,
|
||||
direction);
|
||||
if (*mapped_nents != *nents) {
|
||||
*nents = *mapped_nents;
|
||||
dev_err(dev, "dma_map_sg() sg buffer failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cc_buffer_mgr_init(struct cc_drvdata *drvdata)
|
||||
{
|
||||
struct buff_mgr_handle *buff_mgr_handle;
|
||||
struct device *dev = drvdata_to_dev(drvdata);
|
||||
|
||||
buff_mgr_handle = kmalloc(sizeof(*buff_mgr_handle), GFP_KERNEL);
|
||||
if (!buff_mgr_handle)
|
||||
return -ENOMEM;
|
||||
|
||||
drvdata->buff_mgr_handle = buff_mgr_handle;
|
||||
|
||||
buff_mgr_handle->mlli_buffs_pool =
|
||||
dma_pool_create("dx_single_mlli_tables", dev,
|
||||
MAX_NUM_OF_TOTAL_MLLI_ENTRIES *
|
||||
LLI_ENTRY_BYTE_SIZE,
|
||||
MLLI_TABLE_MIN_ALIGNMENT, 0);
|
||||
|
||||
if (!buff_mgr_handle->mlli_buffs_pool)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cc_buffer_mgr_fini(drvdata);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int cc_buffer_mgr_fini(struct cc_drvdata *drvdata)
|
||||
{
|
||||
struct buff_mgr_handle *buff_mgr_handle = drvdata->buff_mgr_handle;
|
||||
|
||||
if (buff_mgr_handle) {
|
||||
dma_pool_destroy(buff_mgr_handle->mlli_buffs_pool);
|
||||
kfree(drvdata->buff_mgr_handle);
|
||||
drvdata->buff_mgr_handle = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
59
drivers/crypto/ccree/cc_buffer_mgr.h
Normal file
59
drivers/crypto/ccree/cc_buffer_mgr.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
/* \file cc_buffer_mgr.h
|
||||
* Buffer Manager
|
||||
*/
|
||||
|
||||
#ifndef __CC_BUFFER_MGR_H__
|
||||
#define __CC_BUFFER_MGR_H__
|
||||
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
#include "cc_driver.h"
|
||||
|
||||
enum cc_req_dma_buf_type {
|
||||
CC_DMA_BUF_NULL = 0,
|
||||
CC_DMA_BUF_DLLI,
|
||||
CC_DMA_BUF_MLLI
|
||||
};
|
||||
|
||||
enum cc_sg_cpy_direct {
|
||||
CC_SG_TO_BUF = 0,
|
||||
CC_SG_FROM_BUF = 1
|
||||
};
|
||||
|
||||
struct cc_mlli {
|
||||
cc_sram_addr_t sram_addr;
|
||||
unsigned int nents; //sg nents
|
||||
unsigned int mlli_nents; //mlli nents might be different than the above
|
||||
};
|
||||
|
||||
struct mlli_params {
|
||||
struct dma_pool *curr_pool;
|
||||
u8 *mlli_virt_addr;
|
||||
dma_addr_t mlli_dma_addr;
|
||||
u32 mlli_len;
|
||||
};
|
||||
|
||||
int cc_buffer_mgr_init(struct cc_drvdata *drvdata);
|
||||
|
||||
int cc_buffer_mgr_fini(struct cc_drvdata *drvdata);
|
||||
|
||||
int cc_map_hash_request_final(struct cc_drvdata *drvdata, void *ctx,
|
||||
struct scatterlist *src, unsigned int nbytes,
|
||||
bool do_update, gfp_t flags);
|
||||
|
||||
int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx,
|
||||
struct scatterlist *src, unsigned int nbytes,
|
||||
unsigned int block_size, gfp_t flags);
|
||||
|
||||
void cc_unmap_hash_request(struct device *dev, void *ctx,
|
||||
struct scatterlist *src, bool do_revert);
|
||||
|
||||
void cc_copy_sg_portion(struct device *dev, u8 *dest, struct scatterlist *sg,
|
||||
u32 to_skip, u32 end, enum cc_sg_cpy_direct direct);
|
||||
|
||||
void cc_zero_sgl(struct scatterlist *sgl, u32 data_len);
|
||||
|
||||
#endif /*__BUFFER_MGR_H__*/
|
||||
169
drivers/crypto/ccree/cc_crypto_ctx.h
Normal file
169
drivers/crypto/ccree/cc_crypto_ctx.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#ifndef _CC_CRYPTO_CTX_H_
|
||||
#define _CC_CRYPTO_CTX_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* context size */
|
||||
#ifndef CC_CTX_SIZE_LOG2
|
||||
#if (CC_DEV_SHA_MAX > 256)
|
||||
#define CC_CTX_SIZE_LOG2 8
|
||||
#else
|
||||
#define CC_CTX_SIZE_LOG2 7
|
||||
#endif
|
||||
#endif
|
||||
#define CC_CTX_SIZE BIT(CC_CTX_SIZE_LOG2)
|
||||
#define CC_DRV_CTX_SIZE_WORDS (CC_CTX_SIZE >> 2)
|
||||
|
||||
#define CC_DRV_DES_IV_SIZE 8
|
||||
#define CC_DRV_DES_BLOCK_SIZE 8
|
||||
|
||||
#define CC_DRV_DES_ONE_KEY_SIZE 8
|
||||
#define CC_DRV_DES_DOUBLE_KEY_SIZE 16
|
||||
#define CC_DRV_DES_TRIPLE_KEY_SIZE 24
|
||||
#define CC_DRV_DES_KEY_SIZE_MAX CC_DRV_DES_TRIPLE_KEY_SIZE
|
||||
|
||||
#define CC_AES_IV_SIZE 16
|
||||
#define CC_AES_IV_SIZE_WORDS (CC_AES_IV_SIZE >> 2)
|
||||
|
||||
#define CC_AES_BLOCK_SIZE 16
|
||||
#define CC_AES_BLOCK_SIZE_WORDS 4
|
||||
|
||||
#define CC_AES_128_BIT_KEY_SIZE 16
|
||||
#define CC_AES_128_BIT_KEY_SIZE_WORDS (CC_AES_128_BIT_KEY_SIZE >> 2)
|
||||
#define CC_AES_192_BIT_KEY_SIZE 24
|
||||
#define CC_AES_192_BIT_KEY_SIZE_WORDS (CC_AES_192_BIT_KEY_SIZE >> 2)
|
||||
#define CC_AES_256_BIT_KEY_SIZE 32
|
||||
#define CC_AES_256_BIT_KEY_SIZE_WORDS (CC_AES_256_BIT_KEY_SIZE >> 2)
|
||||
#define CC_AES_KEY_SIZE_MAX CC_AES_256_BIT_KEY_SIZE
|
||||
#define CC_AES_KEY_SIZE_WORDS_MAX (CC_AES_KEY_SIZE_MAX >> 2)
|
||||
|
||||
#define CC_MD5_DIGEST_SIZE 16
|
||||
#define CC_SHA1_DIGEST_SIZE 20
|
||||
#define CC_SHA224_DIGEST_SIZE 28
|
||||
#define CC_SHA256_DIGEST_SIZE 32
|
||||
#define CC_SHA256_DIGEST_SIZE_IN_WORDS 8
|
||||
#define CC_SHA384_DIGEST_SIZE 48
|
||||
#define CC_SHA512_DIGEST_SIZE 64
|
||||
|
||||
#define CC_SHA1_BLOCK_SIZE 64
|
||||
#define CC_SHA1_BLOCK_SIZE_IN_WORDS 16
|
||||
#define CC_MD5_BLOCK_SIZE 64
|
||||
#define CC_MD5_BLOCK_SIZE_IN_WORDS 16
|
||||
#define CC_SHA224_BLOCK_SIZE 64
|
||||
#define CC_SHA256_BLOCK_SIZE 64
|
||||
#define CC_SHA256_BLOCK_SIZE_IN_WORDS 16
|
||||
#define CC_SHA1_224_256_BLOCK_SIZE 64
|
||||
#define CC_SHA384_BLOCK_SIZE 128
|
||||
#define CC_SHA512_BLOCK_SIZE 128
|
||||
|
||||
#if (CC_DEV_SHA_MAX > 256)
|
||||
#define CC_DIGEST_SIZE_MAX CC_SHA512_DIGEST_SIZE
|
||||
#define CC_HASH_BLOCK_SIZE_MAX CC_SHA512_BLOCK_SIZE /*1024b*/
|
||||
#else /* Only up to SHA256 */
|
||||
#define CC_DIGEST_SIZE_MAX CC_SHA256_DIGEST_SIZE
|
||||
#define CC_HASH_BLOCK_SIZE_MAX CC_SHA256_BLOCK_SIZE /*512b*/
|
||||
#endif
|
||||
|
||||
#define CC_HMAC_BLOCK_SIZE_MAX CC_HASH_BLOCK_SIZE_MAX
|
||||
|
||||
#define CC_DRV_ALG_MAX_BLOCK_SIZE CC_HASH_BLOCK_SIZE_MAX
|
||||
|
||||
enum drv_engine_type {
|
||||
DRV_ENGINE_NULL = 0,
|
||||
DRV_ENGINE_AES = 1,
|
||||
DRV_ENGINE_DES = 2,
|
||||
DRV_ENGINE_HASH = 3,
|
||||
DRV_ENGINE_RC4 = 4,
|
||||
DRV_ENGINE_DOUT = 5,
|
||||
DRV_ENGINE_RESERVE32B = S32_MAX,
|
||||
};
|
||||
|
||||
enum drv_crypto_alg {
|
||||
DRV_CRYPTO_ALG_NULL = -1,
|
||||
DRV_CRYPTO_ALG_AES = 0,
|
||||
DRV_CRYPTO_ALG_DES = 1,
|
||||
DRV_CRYPTO_ALG_HASH = 2,
|
||||
DRV_CRYPTO_ALG_C2 = 3,
|
||||
DRV_CRYPTO_ALG_HMAC = 4,
|
||||
DRV_CRYPTO_ALG_AEAD = 5,
|
||||
DRV_CRYPTO_ALG_BYPASS = 6,
|
||||
DRV_CRYPTO_ALG_NUM = 7,
|
||||
DRV_CRYPTO_ALG_RESERVE32B = S32_MAX
|
||||
};
|
||||
|
||||
enum drv_crypto_direction {
|
||||
DRV_CRYPTO_DIRECTION_NULL = -1,
|
||||
DRV_CRYPTO_DIRECTION_ENCRYPT = 0,
|
||||
DRV_CRYPTO_DIRECTION_DECRYPT = 1,
|
||||
DRV_CRYPTO_DIRECTION_DECRYPT_ENCRYPT = 3,
|
||||
DRV_CRYPTO_DIRECTION_RESERVE32B = S32_MAX
|
||||
};
|
||||
|
||||
enum drv_cipher_mode {
|
||||
DRV_CIPHER_NULL_MODE = -1,
|
||||
DRV_CIPHER_ECB = 0,
|
||||
DRV_CIPHER_CBC = 1,
|
||||
DRV_CIPHER_CTR = 2,
|
||||
DRV_CIPHER_CBC_MAC = 3,
|
||||
DRV_CIPHER_XTS = 4,
|
||||
DRV_CIPHER_XCBC_MAC = 5,
|
||||
DRV_CIPHER_OFB = 6,
|
||||
DRV_CIPHER_CMAC = 7,
|
||||
DRV_CIPHER_CCM = 8,
|
||||
DRV_CIPHER_CBC_CTS = 11,
|
||||
DRV_CIPHER_GCTR = 12,
|
||||
DRV_CIPHER_ESSIV = 13,
|
||||
DRV_CIPHER_BITLOCKER = 14,
|
||||
DRV_CIPHER_RESERVE32B = S32_MAX
|
||||
};
|
||||
|
||||
enum drv_hash_mode {
|
||||
DRV_HASH_NULL = -1,
|
||||
DRV_HASH_SHA1 = 0,
|
||||
DRV_HASH_SHA256 = 1,
|
||||
DRV_HASH_SHA224 = 2,
|
||||
DRV_HASH_SHA512 = 3,
|
||||
DRV_HASH_SHA384 = 4,
|
||||
DRV_HASH_MD5 = 5,
|
||||
DRV_HASH_CBC_MAC = 6,
|
||||
DRV_HASH_XCBC_MAC = 7,
|
||||
DRV_HASH_CMAC = 8,
|
||||
DRV_HASH_MODE_NUM = 9,
|
||||
DRV_HASH_RESERVE32B = S32_MAX
|
||||
};
|
||||
|
||||
enum drv_hash_hw_mode {
|
||||
DRV_HASH_HW_MD5 = 0,
|
||||
DRV_HASH_HW_SHA1 = 1,
|
||||
DRV_HASH_HW_SHA256 = 2,
|
||||
DRV_HASH_HW_SHA224 = 10,
|
||||
DRV_HASH_HW_SHA512 = 4,
|
||||
DRV_HASH_HW_SHA384 = 12,
|
||||
DRV_HASH_HW_GHASH = 6,
|
||||
DRV_HASH_HW_RESERVE32B = S32_MAX
|
||||
};
|
||||
|
||||
/* drv_crypto_key_type[1:0] is mapped to cipher_do[1:0] */
|
||||
/* drv_crypto_key_type[2] is mapped to cipher_config2 */
|
||||
enum drv_crypto_key_type {
|
||||
DRV_NULL_KEY = -1,
|
||||
DRV_USER_KEY = 0, /* 0x000 */
|
||||
DRV_ROOT_KEY = 1, /* 0x001 */
|
||||
DRV_PROVISIONING_KEY = 2, /* 0x010 */
|
||||
DRV_SESSION_KEY = 3, /* 0x011 */
|
||||
DRV_APPLET_KEY = 4, /* NA */
|
||||
DRV_PLATFORM_KEY = 5, /* 0x101 */
|
||||
DRV_CUSTOMER_KEY = 6, /* 0x110 */
|
||||
DRV_END_OF_KEYS = S32_MAX,
|
||||
};
|
||||
|
||||
enum drv_crypto_padding_type {
|
||||
DRV_PADDING_NONE = 0,
|
||||
DRV_PADDING_PKCS7 = 1,
|
||||
DRV_PADDING_RESERVE32B = S32_MAX
|
||||
};
|
||||
|
||||
#endif /* _CC_CRYPTO_CTX_H_ */
|
||||
101
drivers/crypto/ccree/cc_debugfs.c
Normal file
101
drivers/crypto/ccree/cc_debugfs.c
Normal file
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/stringify.h>
|
||||
#include "cc_driver.h"
|
||||
#include "cc_crypto_ctx.h"
|
||||
#include "cc_debugfs.h"
|
||||
|
||||
struct cc_debugfs_ctx {
|
||||
struct dentry *dir;
|
||||
};
|
||||
|
||||
#define CC_DEBUG_REG(_X) { \
|
||||
.name = __stringify(_X),\
|
||||
.offset = CC_REG(_X) \
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a global var for the dentry of the
|
||||
* debugfs ccree/ dir. It is not tied down to
|
||||
* a specific instance of ccree, hence it is
|
||||
* global.
|
||||
*/
|
||||
static struct dentry *cc_debugfs_dir;
|
||||
|
||||
static struct debugfs_reg32 debug_regs[] = {
|
||||
CC_DEBUG_REG(HOST_SIGNATURE),
|
||||
CC_DEBUG_REG(HOST_IRR),
|
||||
CC_DEBUG_REG(HOST_POWER_DOWN_EN),
|
||||
CC_DEBUG_REG(AXIM_MON_ERR),
|
||||
CC_DEBUG_REG(DSCRPTR_QUEUE_CONTENT),
|
||||
CC_DEBUG_REG(HOST_IMR),
|
||||
CC_DEBUG_REG(AXIM_CFG),
|
||||
CC_DEBUG_REG(AXIM_CACHE_PARAMS),
|
||||
CC_DEBUG_REG(HOST_VERSION),
|
||||
CC_DEBUG_REG(GPR_HOST),
|
||||
CC_DEBUG_REG(AXIM_MON_COMP),
|
||||
};
|
||||
|
||||
int __init cc_debugfs_global_init(void)
|
||||
{
|
||||
cc_debugfs_dir = debugfs_create_dir("ccree", NULL);
|
||||
|
||||
return !cc_debugfs_dir;
|
||||
}
|
||||
|
||||
void __exit cc_debugfs_global_fini(void)
|
||||
{
|
||||
debugfs_remove(cc_debugfs_dir);
|
||||
}
|
||||
|
||||
int cc_debugfs_init(struct cc_drvdata *drvdata)
|
||||
{
|
||||
struct device *dev = drvdata_to_dev(drvdata);
|
||||
struct cc_debugfs_ctx *ctx;
|
||||
struct debugfs_regset32 *regset;
|
||||
struct dentry *file;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
|
||||
if (!regset)
|
||||
return -ENOMEM;
|
||||
|
||||
regset->regs = debug_regs;
|
||||
regset->nregs = ARRAY_SIZE(debug_regs);
|
||||
regset->base = drvdata->cc_base;
|
||||
|
||||
ctx->dir = debugfs_create_dir(drvdata->plat_dev->name, cc_debugfs_dir);
|
||||
if (!ctx->dir)
|
||||
return -ENFILE;
|
||||
|
||||
file = debugfs_create_regset32("regs", 0400, ctx->dir, regset);
|
||||
if (!file) {
|
||||
debugfs_remove(ctx->dir);
|
||||
return -ENFILE;
|
||||
}
|
||||
|
||||
file = debugfs_create_bool("coherent", 0400, ctx->dir,
|
||||
&drvdata->coherent);
|
||||
|
||||
if (!file) {
|
||||
debugfs_remove_recursive(ctx->dir);
|
||||
return -ENFILE;
|
||||
}
|
||||
|
||||
drvdata->debugfs = ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cc_debugfs_fini(struct cc_drvdata *drvdata)
|
||||
{
|
||||
struct cc_debugfs_ctx *ctx = (struct cc_debugfs_ctx *)drvdata->debugfs;
|
||||
|
||||
debugfs_remove_recursive(ctx->dir);
|
||||
}
|
||||
32
drivers/crypto/ccree/cc_debugfs.h
Normal file
32
drivers/crypto/ccree/cc_debugfs.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#ifndef __CC_DEBUGFS_H__
|
||||
#define __CC_DEBUGFS_H__
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
int cc_debugfs_global_init(void);
|
||||
void cc_debugfs_global_fini(void);
|
||||
|
||||
int cc_debugfs_init(struct cc_drvdata *drvdata);
|
||||
void cc_debugfs_fini(struct cc_drvdata *drvdata);
|
||||
|
||||
#else
|
||||
|
||||
static inline int cc_debugfs_global_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cc_debugfs_global_fini(void) {}
|
||||
|
||||
static inline int cc_debugfs_init(struct cc_drvdata *drvdata)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cc_debugfs_fini(struct cc_drvdata *drvdata) {}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*__CC_SYSFS_H__*/
|
||||
417
drivers/crypto/ccree/cc_driver.c
Normal file
417
drivers/crypto/ccree/cc_driver.c
Normal file
@@ -0,0 +1,417 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include "cc_driver.h"
|
||||
#include "cc_request_mgr.h"
|
||||
#include "cc_buffer_mgr.h"
|
||||
#include "cc_debugfs.h"
|
||||
#include "cc_ivgen.h"
|
||||
#include "cc_sram_mgr.h"
|
||||
#include "cc_pm.h"
|
||||
|
||||
bool cc_dump_desc;
|
||||
module_param_named(dump_desc, cc_dump_desc, bool, 0600);
|
||||
MODULE_PARM_DESC(cc_dump_desc, "Dump descriptors to kernel log as debugging aid");
|
||||
|
||||
bool cc_dump_bytes;
|
||||
module_param_named(dump_bytes, cc_dump_bytes, bool, 0600);
|
||||
MODULE_PARM_DESC(cc_dump_bytes, "Dump buffers to kernel log as debugging aid");
|
||||
|
||||
void __dump_byte_array(const char *name, const u8 *buf, size_t len)
|
||||
{
|
||||
char prefix[64];
|
||||
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
snprintf(prefix, sizeof(prefix), "%s[%zu]: ", name, len);
|
||||
|
||||
print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_ADDRESS, 16, 1, buf,
|
||||
len, false);
|
||||
}
|
||||
|
||||
static irqreturn_t cc_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct cc_drvdata *drvdata = (struct cc_drvdata *)dev_id;
|
||||
struct device *dev = drvdata_to_dev(drvdata);
|
||||
u32 irr;
|
||||
u32 imr;
|
||||
|
||||
/* STAT_OP_TYPE_GENERIC STAT_PHASE_0: Interrupt */
|
||||
|
||||
/* read the interrupt status */
|
||||
irr = cc_ioread(drvdata, CC_REG(HOST_IRR));
|
||||
dev_dbg(dev, "Got IRR=0x%08X\n", irr);
|
||||
if (irr == 0) { /* Probably shared interrupt line */
|
||||
dev_err(dev, "Got interrupt with empty IRR\n");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
imr = cc_ioread(drvdata, CC_REG(HOST_IMR));
|
||||
|
||||
/* clear interrupt - must be before processing events */
|
||||
cc_iowrite(drvdata, CC_REG(HOST_ICR), irr);
|
||||
|
||||
drvdata->irq = irr;
|
||||
/* Completion interrupt - most probable */
|
||||
if (irr & CC_COMP_IRQ_MASK) {
|
||||
/* Mask AXI completion interrupt - will be unmasked in
|
||||
* Deferred service handler
|
||||
*/
|
||||
cc_iowrite(drvdata, CC_REG(HOST_IMR), imr | CC_COMP_IRQ_MASK);
|
||||
irr &= ~CC_COMP_IRQ_MASK;
|
||||
complete_request(drvdata);
|
||||
}
|
||||
|
||||
/* AXI error interrupt */
|
||||
if (irr & CC_AXI_ERR_IRQ_MASK) {
|
||||
u32 axi_err;
|
||||
|
||||
/* Read the AXI error ID */
|
||||
axi_err = cc_ioread(drvdata, CC_REG(AXIM_MON_ERR));
|
||||
dev_dbg(dev, "AXI completion error: axim_mon_err=0x%08X\n",
|
||||
axi_err);
|
||||
|
||||
irr &= ~CC_AXI_ERR_IRQ_MASK;
|
||||
}
|
||||
|
||||
if (irr) {
|
||||
dev_dbg(dev, "IRR includes unknown cause bits (0x%08X)\n",
|
||||
irr);
|
||||
/* Just warning */
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int init_cc_regs(struct cc_drvdata *drvdata, bool is_probe)
|
||||
{
|
||||
unsigned int val, cache_params;
|
||||
struct device *dev = drvdata_to_dev(drvdata);
|
||||
|
||||
/* Unmask all AXI interrupt sources AXI_CFG1 register */
|
||||
val = cc_ioread(drvdata, CC_REG(AXIM_CFG));
|
||||
cc_iowrite(drvdata, CC_REG(AXIM_CFG), val & ~CC_AXI_IRQ_MASK);
|
||||
dev_dbg(dev, "AXIM_CFG=0x%08X\n",
|
||||
cc_ioread(drvdata, CC_REG(AXIM_CFG)));
|
||||
|
||||
/* Clear all pending interrupts */
|
||||
val = cc_ioread(drvdata, CC_REG(HOST_IRR));
|
||||
dev_dbg(dev, "IRR=0x%08X\n", val);
|
||||
cc_iowrite(drvdata, CC_REG(HOST_ICR), val);
|
||||
|
||||
/* Unmask relevant interrupt cause */
|
||||
val = (unsigned int)(~(CC_COMP_IRQ_MASK | CC_AXI_ERR_IRQ_MASK |
|
||||
CC_GPR0_IRQ_MASK));
|
||||
cc_iowrite(drvdata, CC_REG(HOST_IMR), val);
|
||||
|
||||
cache_params = (drvdata->coherent ? CC_COHERENT_CACHE_PARAMS : 0x0);
|
||||
|
||||
val = cc_ioread(drvdata, CC_REG(AXIM_CACHE_PARAMS));
|
||||
|
||||
if (is_probe)
|
||||
dev_info(dev, "Cache params previous: 0x%08X\n", val);
|
||||
|
||||
cc_iowrite(drvdata, CC_REG(AXIM_CACHE_PARAMS), cache_params);
|
||||
val = cc_ioread(drvdata, CC_REG(AXIM_CACHE_PARAMS));
|
||||
|
||||
if (is_probe)
|
||||
dev_info(dev, "Cache params current: 0x%08X (expect: 0x%08X)\n",
|
||||
val, cache_params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_cc_resources(struct platform_device *plat_dev)
|
||||
{
|
||||
struct resource *req_mem_cc_regs = NULL;
|
||||
struct cc_drvdata *new_drvdata;
|
||||
struct device *dev = &plat_dev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
u32 signature_val;
|
||||
u64 dma_mask;
|
||||
int rc = 0;
|
||||
|
||||
new_drvdata = devm_kzalloc(dev, sizeof(*new_drvdata), GFP_KERNEL);
|
||||
if (!new_drvdata)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(plat_dev, new_drvdata);
|
||||
new_drvdata->plat_dev = plat_dev;
|
||||
|
||||
new_drvdata->clk = of_clk_get(np, 0);
|
||||
new_drvdata->coherent = of_dma_is_coherent(np);
|
||||
|
||||
/* Get device resources */
|
||||
/* First CC registers space */
|
||||
req_mem_cc_regs = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
|
||||
/* Map registers space */
|
||||
new_drvdata->cc_base = devm_ioremap_resource(dev, req_mem_cc_regs);
|
||||
if (IS_ERR(new_drvdata->cc_base)) {
|
||||
dev_err(dev, "Failed to ioremap registers");
|
||||
return PTR_ERR(new_drvdata->cc_base);
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Got MEM resource (%s): %pR\n", req_mem_cc_regs->name,
|
||||
req_mem_cc_regs);
|
||||
dev_dbg(dev, "CC registers mapped from %pa to 0x%p\n",
|
||||
&req_mem_cc_regs->start, new_drvdata->cc_base);
|
||||
|
||||
/* Then IRQ */
|
||||
new_drvdata->irq = platform_get_irq(plat_dev, 0);
|
||||
if (new_drvdata->irq < 0) {
|
||||
dev_err(dev, "Failed getting IRQ resource\n");
|
||||
return new_drvdata->irq;
|
||||
}
|
||||
|
||||
rc = devm_request_irq(dev, new_drvdata->irq, cc_isr,
|
||||
IRQF_SHARED, "ccree", new_drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "Could not register to interrupt %d\n",
|
||||
new_drvdata->irq);
|
||||
return rc;
|
||||
}
|
||||
dev_dbg(dev, "Registered to IRQ: %d\n", new_drvdata->irq);
|
||||
|
||||
init_completion(&new_drvdata->hw_queue_avail);
|
||||
|
||||
if (!plat_dev->dev.dma_mask)
|
||||
plat_dev->dev.dma_mask = &plat_dev->dev.coherent_dma_mask;
|
||||
|
||||
dma_mask = DMA_BIT_MASK(DMA_BIT_MASK_LEN);
|
||||
while (dma_mask > 0x7fffffffUL) {
|
||||
if (dma_supported(&plat_dev->dev, dma_mask)) {
|
||||
rc = dma_set_coherent_mask(&plat_dev->dev, dma_mask);
|
||||
if (!rc)
|
||||
break;
|
||||
}
|
||||
dma_mask >>= 1;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
dev_err(dev, "Failed in dma_set_mask, mask=%pad\n", &dma_mask);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cc_clk_on(new_drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "Failed to enable clock");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Verify correct mapping */
|
||||
signature_val = cc_ioread(new_drvdata, CC_REG(HOST_SIGNATURE));
|
||||
if (signature_val != CC_DEV_SIGNATURE) {
|
||||
dev_err(dev, "Invalid CC signature: SIGNATURE=0x%08X != expected=0x%08X\n",
|
||||
signature_val, (u32)CC_DEV_SIGNATURE);
|
||||
rc = -EINVAL;
|
||||
goto post_clk_err;
|
||||
}
|
||||
dev_dbg(dev, "CC SIGNATURE=0x%08X\n", signature_val);
|
||||
|
||||
/* Display HW versions */
|
||||
dev_info(dev, "ARM CryptoCell %s Driver: HW version 0x%08X, Driver version %s\n",
|
||||
CC_DEV_NAME_STR,
|
||||
cc_ioread(new_drvdata, CC_REG(HOST_VERSION)),
|
||||
DRV_MODULE_VERSION);
|
||||
|
||||
rc = init_cc_regs(new_drvdata, true);
|
||||
if (rc) {
|
||||
dev_err(dev, "init_cc_regs failed\n");
|
||||
goto post_clk_err;
|
||||
}
|
||||
|
||||
rc = cc_debugfs_init(new_drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "Failed registering debugfs interface\n");
|
||||
goto post_regs_err;
|
||||
}
|
||||
|
||||
rc = cc_sram_mgr_init(new_drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "cc_sram_mgr_init failed\n");
|
||||
goto post_debugfs_err;
|
||||
}
|
||||
|
||||
new_drvdata->mlli_sram_addr =
|
||||
cc_sram_alloc(new_drvdata, MAX_MLLI_BUFF_SIZE);
|
||||
if (new_drvdata->mlli_sram_addr == NULL_SRAM_ADDR) {
|
||||
dev_err(dev, "Failed to alloc MLLI Sram buffer\n");
|
||||
rc = -ENOMEM;
|
||||
goto post_sram_mgr_err;
|
||||
}
|
||||
|
||||
rc = cc_req_mgr_init(new_drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "cc_req_mgr_init failed\n");
|
||||
goto post_sram_mgr_err;
|
||||
}
|
||||
|
||||
rc = cc_buffer_mgr_init(new_drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "buffer_mgr_init failed\n");
|
||||
goto post_req_mgr_err;
|
||||
}
|
||||
|
||||
rc = cc_pm_init(new_drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "ssi_power_mgr_init failed\n");
|
||||
goto post_buf_mgr_err;
|
||||
}
|
||||
|
||||
rc = cc_ivgen_init(new_drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "cc_ivgen_init failed\n");
|
||||
goto post_power_mgr_err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
post_power_mgr_err:
|
||||
cc_pm_fini(new_drvdata);
|
||||
post_buf_mgr_err:
|
||||
cc_buffer_mgr_fini(new_drvdata);
|
||||
post_req_mgr_err:
|
||||
cc_req_mgr_fini(new_drvdata);
|
||||
post_sram_mgr_err:
|
||||
cc_sram_mgr_fini(new_drvdata);
|
||||
post_debugfs_err:
|
||||
cc_debugfs_fini(new_drvdata);
|
||||
post_regs_err:
|
||||
fini_cc_regs(new_drvdata);
|
||||
post_clk_err:
|
||||
cc_clk_off(new_drvdata);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void fini_cc_regs(struct cc_drvdata *drvdata)
|
||||
{
|
||||
/* Mask all interrupts */
|
||||
cc_iowrite(drvdata, CC_REG(HOST_IMR), 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static void cleanup_cc_resources(struct platform_device *plat_dev)
|
||||
{
|
||||
struct cc_drvdata *drvdata =
|
||||
(struct cc_drvdata *)platform_get_drvdata(plat_dev);
|
||||
|
||||
cc_ivgen_fini(drvdata);
|
||||
cc_pm_fini(drvdata);
|
||||
cc_buffer_mgr_fini(drvdata);
|
||||
cc_req_mgr_fini(drvdata);
|
||||
cc_sram_mgr_fini(drvdata);
|
||||
cc_debugfs_fini(drvdata);
|
||||
fini_cc_regs(drvdata);
|
||||
cc_clk_off(drvdata);
|
||||
}
|
||||
|
||||
int cc_clk_on(struct cc_drvdata *drvdata)
|
||||
{
|
||||
struct clk *clk = drvdata->clk;
|
||||
int rc;
|
||||
|
||||
if (IS_ERR(clk))
|
||||
/* Not all devices have a clock associated with CCREE */
|
||||
return 0;
|
||||
|
||||
rc = clk_prepare_enable(clk);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cc_clk_off(struct cc_drvdata *drvdata)
|
||||
{
|
||||
struct clk *clk = drvdata->clk;
|
||||
|
||||
if (IS_ERR(clk))
|
||||
/* Not all devices have a clock associated with CCREE */
|
||||
return;
|
||||
|
||||
clk_disable_unprepare(clk);
|
||||
}
|
||||
|
||||
static int ccree_probe(struct platform_device *plat_dev)
|
||||
{
|
||||
int rc;
|
||||
struct device *dev = &plat_dev->dev;
|
||||
|
||||
/* Map registers space */
|
||||
rc = init_cc_resources(plat_dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
dev_info(dev, "ARM ccree device initialized\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ccree_remove(struct platform_device *plat_dev)
|
||||
{
|
||||
struct device *dev = &plat_dev->dev;
|
||||
|
||||
dev_dbg(dev, "Releasing ccree resources...\n");
|
||||
|
||||
cleanup_cc_resources(plat_dev);
|
||||
|
||||
dev_info(dev, "ARM ccree device terminated\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id arm_ccree_dev_of_match[] = {
|
||||
{.compatible = "arm,cryptocell-712-ree"},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, arm_ccree_dev_of_match);
|
||||
|
||||
static struct platform_driver ccree_driver = {
|
||||
.driver = {
|
||||
.name = "ccree",
|
||||
.of_match_table = arm_ccree_dev_of_match,
|
||||
#ifdef CONFIG_PM
|
||||
.pm = &ccree_pm,
|
||||
#endif
|
||||
},
|
||||
.probe = ccree_probe,
|
||||
.remove = ccree_remove,
|
||||
};
|
||||
|
||||
static int __init ccree_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cc_debugfs_global_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return platform_driver_register(&ccree_driver);
|
||||
}
|
||||
module_init(ccree_init);
|
||||
|
||||
static void __exit ccree_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ccree_driver);
|
||||
cc_debugfs_global_fini();
|
||||
}
|
||||
module_exit(ccree_exit);
|
||||
|
||||
/* Module description */
|
||||
MODULE_DESCRIPTION("ARM TrustZone CryptoCell REE Driver");
|
||||
MODULE_VERSION(DRV_MODULE_VERSION);
|
||||
MODULE_AUTHOR("ARM");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
185
drivers/crypto/ccree/cc_driver.h
Normal file
185
drivers/crypto/ccree/cc_driver.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
/* \file cc_driver.h
|
||||
* ARM CryptoCell Linux Crypto Driver
|
||||
*/
|
||||
|
||||
#ifndef __CC_DRIVER_H__
|
||||
#define __CC_DRIVER_H__
|
||||
|
||||
#ifdef COMP_IN_WQ
|
||||
#include <linux/workqueue.h>
|
||||
#else
|
||||
#include <linux/interrupt.h>
|
||||
#endif
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <crypto/aead.h>
|
||||
#include <crypto/authenc.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/skcipher.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/* Registers definitions from shared/hw/ree_include */
|
||||
#include "cc_host_regs.h"
|
||||
#define CC_DEV_SHA_MAX 512
|
||||
#include "cc_crypto_ctx.h"
|
||||
#include "cc_hw_queue_defs.h"
|
||||
#include "cc_sram_mgr.h"
|
||||
|
||||
extern bool cc_dump_desc;
|
||||
extern bool cc_dump_bytes;
|
||||
|
||||
#define DRV_MODULE_VERSION "3.0"
|
||||
|
||||
#define CC_DEV_NAME_STR "ccree"
|
||||
#define CC_COHERENT_CACHE_PARAMS 0xEEE
|
||||
|
||||
/* Maximum DMA mask supported by IP */
|
||||
#define DMA_BIT_MASK_LEN 48
|
||||
|
||||
#define CC_DEV_SIGNATURE 0xDCC71200UL
|
||||
|
||||
#define CC_AXI_IRQ_MASK ((1 << CC_AXIM_CFG_BRESPMASK_BIT_SHIFT) | \
|
||||
(1 << CC_AXIM_CFG_RRESPMASK_BIT_SHIFT) | \
|
||||
(1 << CC_AXIM_CFG_INFLTMASK_BIT_SHIFT) | \
|
||||
(1 << CC_AXIM_CFG_COMPMASK_BIT_SHIFT))
|
||||
|
||||
#define CC_AXI_ERR_IRQ_MASK BIT(CC_HOST_IRR_AXI_ERR_INT_BIT_SHIFT)
|
||||
|
||||
#define CC_COMP_IRQ_MASK BIT(CC_HOST_IRR_AXIM_COMP_INT_BIT_SHIFT)
|
||||
|
||||
#define AXIM_MON_COMP_VALUE GENMASK(CC_AXIM_MON_COMP_VALUE_BIT_SIZE + \
|
||||
CC_AXIM_MON_COMP_VALUE_BIT_SHIFT, \
|
||||
CC_AXIM_MON_COMP_VALUE_BIT_SHIFT)
|
||||
|
||||
/* Register name mangling macro */
|
||||
#define CC_REG(reg_name) CC_ ## reg_name ## _REG_OFFSET
|
||||
|
||||
/* TEE FIPS status interrupt */
|
||||
#define CC_GPR0_IRQ_MASK BIT(CC_HOST_IRR_GPR0_BIT_SHIFT)
|
||||
|
||||
#define CC_CRA_PRIO 400
|
||||
|
||||
#define MIN_HW_QUEUE_SIZE 50 /* Minimum size required for proper function */
|
||||
|
||||
#define MAX_REQUEST_QUEUE_SIZE 4096
|
||||
#define MAX_MLLI_BUFF_SIZE 2080
|
||||
#define MAX_ICV_NENTS_SUPPORTED 2
|
||||
|
||||
/* Definitions for HW descriptors DIN/DOUT fields */
|
||||
#define NS_BIT 1
|
||||
#define AXI_ID 0
|
||||
/* AXI_ID is not actually the AXI ID of the transaction but the value of AXI_ID
|
||||
* field in the HW descriptor. The DMA engine +8 that value.
|
||||
*/
|
||||
|
||||
#define CC_MAX_IVGEN_DMA_ADDRESSES 3
|
||||
struct cc_crypto_req {
|
||||
void (*user_cb)(struct device *dev, void *req, int err);
|
||||
void *user_arg;
|
||||
dma_addr_t ivgen_dma_addr[CC_MAX_IVGEN_DMA_ADDRESSES];
|
||||
/* For the first 'ivgen_dma_addr_len' addresses of this array,
|
||||
* generated IV would be placed in it by send_request().
|
||||
* Same generated IV for all addresses!
|
||||
*/
|
||||
/* Amount of 'ivgen_dma_addr' elements to be filled. */
|
||||
unsigned int ivgen_dma_addr_len;
|
||||
/* The generated IV size required, 8/16 B allowed. */
|
||||
unsigned int ivgen_size;
|
||||
struct completion seq_compl; /* request completion */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cc_drvdata - driver private data context
|
||||
* @cc_base: virt address of the CC registers
|
||||
* @irq: device IRQ number
|
||||
* @irq_mask: Interrupt mask shadow (1 for masked interrupts)
|
||||
* @fw_ver: SeP loaded firmware version
|
||||
*/
|
||||
struct cc_drvdata {
|
||||
void __iomem *cc_base;
|
||||
int irq;
|
||||
u32 irq_mask;
|
||||
u32 fw_ver;
|
||||
struct completion hw_queue_avail; /* wait for HW queue availability */
|
||||
struct platform_device *plat_dev;
|
||||
cc_sram_addr_t mlli_sram_addr;
|
||||
void *buff_mgr_handle;
|
||||
void *request_mgr_handle;
|
||||
void *ivgen_handle;
|
||||
void *sram_mgr_handle;
|
||||
void *debugfs;
|
||||
struct clk *clk;
|
||||
bool coherent;
|
||||
};
|
||||
|
||||
struct cc_crypto_alg {
|
||||
struct list_head entry;
|
||||
int cipher_mode;
|
||||
int flow_mode; /* Note: currently, refers to the cipher mode only. */
|
||||
int auth_mode;
|
||||
struct cc_drvdata *drvdata;
|
||||
struct crypto_alg crypto_alg;
|
||||
};
|
||||
|
||||
struct cc_alg_template {
|
||||
char name[CRYPTO_MAX_ALG_NAME];
|
||||
char driver_name[CRYPTO_MAX_ALG_NAME];
|
||||
unsigned int blocksize;
|
||||
u32 type;
|
||||
union {
|
||||
struct skcipher_alg skcipher;
|
||||
struct aead_alg aead;
|
||||
} template_u;
|
||||
int cipher_mode;
|
||||
int flow_mode; /* Note: currently, refers to the cipher mode only. */
|
||||
int auth_mode;
|
||||
struct cc_drvdata *drvdata;
|
||||
};
|
||||
|
||||
struct async_gen_req_ctx {
|
||||
dma_addr_t iv_dma_addr;
|
||||
enum drv_crypto_direction op_type;
|
||||
};
|
||||
|
||||
static inline struct device *drvdata_to_dev(struct cc_drvdata *drvdata)
|
||||
{
|
||||
return &drvdata->plat_dev->dev;
|
||||
}
|
||||
|
||||
void __dump_byte_array(const char *name, const u8 *buf, size_t len);
|
||||
static inline void dump_byte_array(const char *name, const u8 *the_array,
|
||||
size_t size)
|
||||
{
|
||||
if (cc_dump_bytes)
|
||||
__dump_byte_array(name, the_array, size);
|
||||
}
|
||||
|
||||
int init_cc_regs(struct cc_drvdata *drvdata, bool is_probe);
|
||||
void fini_cc_regs(struct cc_drvdata *drvdata);
|
||||
int cc_clk_on(struct cc_drvdata *drvdata);
|
||||
void cc_clk_off(struct cc_drvdata *drvdata);
|
||||
|
||||
static inline void cc_iowrite(struct cc_drvdata *drvdata, u32 reg, u32 val)
|
||||
{
|
||||
iowrite32(val, (drvdata->cc_base + reg));
|
||||
}
|
||||
|
||||
static inline u32 cc_ioread(struct cc_drvdata *drvdata, u32 reg)
|
||||
{
|
||||
return ioread32(drvdata->cc_base + reg);
|
||||
}
|
||||
|
||||
static inline gfp_t cc_gfp_flags(struct crypto_async_request *req)
|
||||
{
|
||||
return (req->flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
|
||||
GFP_KERNEL : GFP_ATOMIC;
|
||||
}
|
||||
|
||||
#endif /*__CC_DRIVER_H__*/
|
||||
142
drivers/crypto/ccree/cc_host_regs.h
Normal file
142
drivers/crypto/ccree/cc_host_regs.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#ifndef __CC_HOST_H__
|
||||
#define __CC_HOST_H__
|
||||
|
||||
// --------------------------------------
|
||||
// BLOCK: HOST_P
|
||||
// --------------------------------------
|
||||
#define CC_HOST_IRR_REG_OFFSET 0xA00UL
|
||||
#define CC_HOST_IRR_DSCRPTR_COMPLETION_LOW_INT_BIT_SHIFT 0x2UL
|
||||
#define CC_HOST_IRR_DSCRPTR_COMPLETION_LOW_INT_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IRR_AXI_ERR_INT_BIT_SHIFT 0x8UL
|
||||
#define CC_HOST_IRR_AXI_ERR_INT_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IRR_GPR0_BIT_SHIFT 0xBUL
|
||||
#define CC_HOST_IRR_GPR0_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IRR_DSCRPTR_WATERMARK_INT_BIT_SHIFT 0x13UL
|
||||
#define CC_HOST_IRR_DSCRPTR_WATERMARK_INT_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IRR_AXIM_COMP_INT_BIT_SHIFT 0x17UL
|
||||
#define CC_HOST_IRR_AXIM_COMP_INT_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IMR_REG_OFFSET 0xA04UL
|
||||
#define CC_HOST_IMR_NOT_USED_MASK_BIT_SHIFT 0x1UL
|
||||
#define CC_HOST_IMR_NOT_USED_MASK_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IMR_DSCRPTR_COMPLETION_MASK_BIT_SHIFT 0x2UL
|
||||
#define CC_HOST_IMR_DSCRPTR_COMPLETION_MASK_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IMR_AXI_ERR_MASK_BIT_SHIFT 0x8UL
|
||||
#define CC_HOST_IMR_AXI_ERR_MASK_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IMR_GPR0_BIT_SHIFT 0xBUL
|
||||
#define CC_HOST_IMR_GPR0_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IMR_DSCRPTR_WATERMARK_MASK0_BIT_SHIFT 0x13UL
|
||||
#define CC_HOST_IMR_DSCRPTR_WATERMARK_MASK0_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_IMR_AXIM_COMP_INT_MASK_BIT_SHIFT 0x17UL
|
||||
#define CC_HOST_IMR_AXIM_COMP_INT_MASK_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_ICR_REG_OFFSET 0xA08UL
|
||||
#define CC_HOST_ICR_DSCRPTR_COMPLETION_BIT_SHIFT 0x2UL
|
||||
#define CC_HOST_ICR_DSCRPTR_COMPLETION_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_ICR_AXI_ERR_CLEAR_BIT_SHIFT 0x8UL
|
||||
#define CC_HOST_ICR_AXI_ERR_CLEAR_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_ICR_GPR_INT_CLEAR_BIT_SHIFT 0xBUL
|
||||
#define CC_HOST_ICR_GPR_INT_CLEAR_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_ICR_DSCRPTR_WATERMARK_QUEUE0_CLEAR_BIT_SHIFT 0x13UL
|
||||
#define CC_HOST_ICR_DSCRPTR_WATERMARK_QUEUE0_CLEAR_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SHIFT 0x17UL
|
||||
#define CC_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_SIGNATURE_REG_OFFSET 0xA24UL
|
||||
#define CC_HOST_SIGNATURE_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_HOST_SIGNATURE_VALUE_BIT_SIZE 0x20UL
|
||||
#define CC_HOST_BOOT_REG_OFFSET 0xA28UL
|
||||
#define CC_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SHIFT 0x0UL
|
||||
#define CC_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SHIFT 0x1UL
|
||||
#define CC_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SHIFT 0x2UL
|
||||
#define CC_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SHIFT 0x3UL
|
||||
#define CC_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SHIFT 0x5UL
|
||||
#define CC_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SHIFT 0x6UL
|
||||
#define CC_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SIZE 0x3UL
|
||||
#define CC_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SHIFT 0x9UL
|
||||
#define CC_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SHIFT 0xAUL
|
||||
#define CC_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SHIFT 0xBUL
|
||||
#define CC_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SHIFT 0xCUL
|
||||
#define CC_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SHIFT 0xDUL
|
||||
#define CC_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SHIFT 0xEUL
|
||||
#define CC_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SHIFT 0xFUL
|
||||
#define CC_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SHIFT 0x10UL
|
||||
#define CC_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SHIFT 0x11UL
|
||||
#define CC_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SHIFT 0x12UL
|
||||
#define CC_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SHIFT 0x13UL
|
||||
#define CC_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SHIFT 0x14UL
|
||||
#define CC_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SHIFT 0x15UL
|
||||
#define CC_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SHIFT 0x16UL
|
||||
#define CC_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SHIFT 0x17UL
|
||||
#define CC_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SHIFT 0x18UL
|
||||
#define CC_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SHIFT 0x19UL
|
||||
#define CC_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SHIFT 0x1AUL
|
||||
#define CC_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SHIFT 0x1BUL
|
||||
#define CC_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SHIFT 0x1CUL
|
||||
#define CC_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SHIFT 0x1DUL
|
||||
#define CC_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SHIFT 0x1EUL
|
||||
#define CC_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_VERSION_REG_OFFSET 0xA40UL
|
||||
#define CC_HOST_VERSION_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_HOST_VERSION_VALUE_BIT_SIZE 0x20UL
|
||||
#define CC_HOST_KFDE0_VALID_REG_OFFSET 0xA60UL
|
||||
#define CC_HOST_KFDE0_VALID_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_HOST_KFDE0_VALID_VALUE_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_KFDE1_VALID_REG_OFFSET 0xA64UL
|
||||
#define CC_HOST_KFDE1_VALID_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_HOST_KFDE1_VALID_VALUE_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_KFDE2_VALID_REG_OFFSET 0xA68UL
|
||||
#define CC_HOST_KFDE2_VALID_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_HOST_KFDE2_VALID_VALUE_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_KFDE3_VALID_REG_OFFSET 0xA6CUL
|
||||
#define CC_HOST_KFDE3_VALID_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_HOST_KFDE3_VALID_VALUE_BIT_SIZE 0x1UL
|
||||
#define CC_HOST_GPR0_REG_OFFSET 0xA70UL
|
||||
#define CC_HOST_GPR0_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_HOST_GPR0_VALUE_BIT_SIZE 0x20UL
|
||||
#define CC_GPR_HOST_REG_OFFSET 0xA74UL
|
||||
#define CC_GPR_HOST_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_GPR_HOST_VALUE_BIT_SIZE 0x20UL
|
||||
#define CC_HOST_POWER_DOWN_EN_REG_OFFSET 0xA78UL
|
||||
#define CC_HOST_POWER_DOWN_EN_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_HOST_POWER_DOWN_EN_VALUE_BIT_SIZE 0x1UL
|
||||
// --------------------------------------
|
||||
// BLOCK: HOST_SRAM
|
||||
// --------------------------------------
|
||||
#define CC_SRAM_DATA_REG_OFFSET 0xF00UL
|
||||
#define CC_SRAM_DATA_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_SRAM_DATA_VALUE_BIT_SIZE 0x20UL
|
||||
#define CC_SRAM_ADDR_REG_OFFSET 0xF04UL
|
||||
#define CC_SRAM_ADDR_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_SRAM_ADDR_VALUE_BIT_SIZE 0xFUL
|
||||
#define CC_SRAM_DATA_READY_REG_OFFSET 0xF08UL
|
||||
#define CC_SRAM_DATA_READY_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_SRAM_DATA_READY_VALUE_BIT_SIZE 0x1UL
|
||||
|
||||
#endif //__CC_HOST_H__
|
||||
590
drivers/crypto/ccree/cc_hw_queue_defs.h
Normal file
590
drivers/crypto/ccree/cc_hw_queue_defs.h
Normal file
File diff suppressed because it is too large
Load Diff
279
drivers/crypto/ccree/cc_ivgen.c
Normal file
279
drivers/crypto/ccree/cc_ivgen.c
Normal file
@@ -0,0 +1,279 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#include <crypto/ctr.h>
|
||||
#include "cc_driver.h"
|
||||
#include "cc_ivgen.h"
|
||||
#include "cc_request_mgr.h"
|
||||
#include "cc_sram_mgr.h"
|
||||
#include "cc_buffer_mgr.h"
|
||||
|
||||
/* The max. size of pool *MUST* be <= SRAM total size */
|
||||
#define CC_IVPOOL_SIZE 1024
|
||||
/* The first 32B fraction of pool are dedicated to the
|
||||
* next encryption "key" & "IV" for pool regeneration
|
||||
*/
|
||||
#define CC_IVPOOL_META_SIZE (CC_AES_IV_SIZE + AES_KEYSIZE_128)
|
||||
#define CC_IVPOOL_GEN_SEQ_LEN 4
|
||||
|
||||
/**
|
||||
* struct cc_ivgen_ctx -IV pool generation context
|
||||
* @pool: the start address of the iv-pool resides in internal RAM
|
||||
* @ctr_key_dma: address of pool's encryption key material in internal RAM
|
||||
* @ctr_iv_dma: address of pool's counter iv in internal RAM
|
||||
* @next_iv_ofs: the offset to the next available IV in pool
|
||||
* @pool_meta: virt. address of the initial enc. key/IV
|
||||
* @pool_meta_dma: phys. address of the initial enc. key/IV
|
||||
*/
|
||||
struct cc_ivgen_ctx {
|
||||
cc_sram_addr_t pool;
|
||||
cc_sram_addr_t ctr_key;
|
||||
cc_sram_addr_t ctr_iv;
|
||||
u32 next_iv_ofs;
|
||||
u8 *pool_meta;
|
||||
dma_addr_t pool_meta_dma;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Generates CC_IVPOOL_SIZE of random bytes by
|
||||
* encrypting 0's using AES128-CTR.
|
||||
*
|
||||
* \param ivgen iv-pool context
|
||||
* \param iv_seq IN/OUT array to the descriptors sequence
|
||||
* \param iv_seq_len IN/OUT pointer to the sequence length
|
||||
*/
|
||||
static int cc_gen_iv_pool(struct cc_ivgen_ctx *ivgen_ctx,
|
||||
struct cc_hw_desc iv_seq[], unsigned int *iv_seq_len)
|
||||
{
|
||||
unsigned int idx = *iv_seq_len;
|
||||
|
||||
if ((*iv_seq_len + CC_IVPOOL_GEN_SEQ_LEN) > CC_IVPOOL_SEQ_LEN) {
|
||||
/* The sequence will be longer than allowed */
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Setup key */
|
||||
hw_desc_init(&iv_seq[idx]);
|
||||
set_din_sram(&iv_seq[idx], ivgen_ctx->ctr_key, AES_KEYSIZE_128);
|
||||
set_setup_mode(&iv_seq[idx], SETUP_LOAD_KEY0);
|
||||
set_cipher_config0(&iv_seq[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
|
||||
set_flow_mode(&iv_seq[idx], S_DIN_to_AES);
|
||||
set_key_size_aes(&iv_seq[idx], CC_AES_128_BIT_KEY_SIZE);
|
||||
set_cipher_mode(&iv_seq[idx], DRV_CIPHER_CTR);
|
||||
idx++;
|
||||
|
||||
/* Setup cipher state */
|
||||
hw_desc_init(&iv_seq[idx]);
|
||||
set_din_sram(&iv_seq[idx], ivgen_ctx->ctr_iv, CC_AES_IV_SIZE);
|
||||
set_cipher_config0(&iv_seq[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
|
||||
set_flow_mode(&iv_seq[idx], S_DIN_to_AES);
|
||||
set_setup_mode(&iv_seq[idx], SETUP_LOAD_STATE1);
|
||||
set_key_size_aes(&iv_seq[idx], CC_AES_128_BIT_KEY_SIZE);
|
||||
set_cipher_mode(&iv_seq[idx], DRV_CIPHER_CTR);
|
||||
idx++;
|
||||
|
||||
/* Perform dummy encrypt to skip first block */
|
||||
hw_desc_init(&iv_seq[idx]);
|
||||
set_din_const(&iv_seq[idx], 0, CC_AES_IV_SIZE);
|
||||
set_dout_sram(&iv_seq[idx], ivgen_ctx->pool, CC_AES_IV_SIZE);
|
||||
set_flow_mode(&iv_seq[idx], DIN_AES_DOUT);
|
||||
idx++;
|
||||
|
||||
/* Generate IV pool */
|
||||
hw_desc_init(&iv_seq[idx]);
|
||||
set_din_const(&iv_seq[idx], 0, CC_IVPOOL_SIZE);
|
||||
set_dout_sram(&iv_seq[idx], ivgen_ctx->pool, CC_IVPOOL_SIZE);
|
||||
set_flow_mode(&iv_seq[idx], DIN_AES_DOUT);
|
||||
idx++;
|
||||
|
||||
*iv_seq_len = idx; /* Update sequence length */
|
||||
|
||||
/* queue ordering assures pool readiness */
|
||||
ivgen_ctx->next_iv_ofs = CC_IVPOOL_META_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Generates the initial pool in SRAM.
|
||||
* This function should be invoked when resuming driver.
|
||||
*
|
||||
* \param drvdata
|
||||
*
|
||||
* \return int Zero for success, negative value otherwise.
|
||||
*/
|
||||
int cc_init_iv_sram(struct cc_drvdata *drvdata)
|
||||
{
|
||||
struct cc_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle;
|
||||
struct cc_hw_desc iv_seq[CC_IVPOOL_SEQ_LEN];
|
||||
unsigned int iv_seq_len = 0;
|
||||
int rc;
|
||||
|
||||
/* Generate initial enc. key/iv */
|
||||
get_random_bytes(ivgen_ctx->pool_meta, CC_IVPOOL_META_SIZE);
|
||||
|
||||
/* The first 32B reserved for the enc. Key/IV */
|
||||
ivgen_ctx->ctr_key = ivgen_ctx->pool;
|
||||
ivgen_ctx->ctr_iv = ivgen_ctx->pool + AES_KEYSIZE_128;
|
||||
|
||||
/* Copy initial enc. key and IV to SRAM at a single descriptor */
|
||||
hw_desc_init(&iv_seq[iv_seq_len]);
|
||||
set_din_type(&iv_seq[iv_seq_len], DMA_DLLI, ivgen_ctx->pool_meta_dma,
|
||||
CC_IVPOOL_META_SIZE, NS_BIT);
|
||||
set_dout_sram(&iv_seq[iv_seq_len], ivgen_ctx->pool,
|
||||
CC_IVPOOL_META_SIZE);
|
||||
set_flow_mode(&iv_seq[iv_seq_len], BYPASS);
|
||||
iv_seq_len++;
|
||||
|
||||
/* Generate initial pool */
|
||||
rc = cc_gen_iv_pool(ivgen_ctx, iv_seq, &iv_seq_len);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Fire-and-forget */
|
||||
return send_request_init(drvdata, iv_seq, iv_seq_len);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Free iv-pool and ivgen context.
|
||||
*
|
||||
* \param drvdata
|
||||
*/
|
||||
void cc_ivgen_fini(struct cc_drvdata *drvdata)
|
||||
{
|
||||
struct cc_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle;
|
||||
struct device *device = &drvdata->plat_dev->dev;
|
||||
|
||||
if (!ivgen_ctx)
|
||||
return;
|
||||
|
||||
if (ivgen_ctx->pool_meta) {
|
||||
memset(ivgen_ctx->pool_meta, 0, CC_IVPOOL_META_SIZE);
|
||||
dma_free_coherent(device, CC_IVPOOL_META_SIZE,
|
||||
ivgen_ctx->pool_meta,
|
||||
ivgen_ctx->pool_meta_dma);
|
||||
}
|
||||
|
||||
ivgen_ctx->pool = NULL_SRAM_ADDR;
|
||||
|
||||
/* release "this" context */
|
||||
kfree(ivgen_ctx);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Allocates iv-pool and maps resources.
|
||||
* This function generates the first IV pool.
|
||||
*
|
||||
* \param drvdata Driver's private context
|
||||
*
|
||||
* \return int Zero for success, negative value otherwise.
|
||||
*/
|
||||
int cc_ivgen_init(struct cc_drvdata *drvdata)
|
||||
{
|
||||
struct cc_ivgen_ctx *ivgen_ctx;
|
||||
struct device *device = &drvdata->plat_dev->dev;
|
||||
int rc;
|
||||
|
||||
/* Allocate "this" context */
|
||||
ivgen_ctx = kzalloc(sizeof(*ivgen_ctx), GFP_KERNEL);
|
||||
if (!ivgen_ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Allocate pool's header for initial enc. key/IV */
|
||||
ivgen_ctx->pool_meta = dma_alloc_coherent(device, CC_IVPOOL_META_SIZE,
|
||||
&ivgen_ctx->pool_meta_dma,
|
||||
GFP_KERNEL);
|
||||
if (!ivgen_ctx->pool_meta) {
|
||||
dev_err(device, "Not enough memory to allocate DMA of pool_meta (%u B)\n",
|
||||
CC_IVPOOL_META_SIZE);
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
/* Allocate IV pool in SRAM */
|
||||
ivgen_ctx->pool = cc_sram_alloc(drvdata, CC_IVPOOL_SIZE);
|
||||
if (ivgen_ctx->pool == NULL_SRAM_ADDR) {
|
||||
dev_err(device, "SRAM pool exhausted\n");
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
drvdata->ivgen_handle = ivgen_ctx;
|
||||
|
||||
return cc_init_iv_sram(drvdata);
|
||||
|
||||
out:
|
||||
cc_ivgen_fini(drvdata);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Acquires 16 Bytes IV from the iv-pool
|
||||
*
|
||||
* \param drvdata Driver private context
|
||||
* \param iv_out_dma Array of physical IV out addresses
|
||||
* \param iv_out_dma_len Length of iv_out_dma array (additional elements
|
||||
* of iv_out_dma array are ignore)
|
||||
* \param iv_out_size May be 8 or 16 bytes long
|
||||
* \param iv_seq IN/OUT array to the descriptors sequence
|
||||
* \param iv_seq_len IN/OUT pointer to the sequence length
|
||||
*
|
||||
* \return int Zero for success, negative value otherwise.
|
||||
*/
|
||||
int cc_get_iv(struct cc_drvdata *drvdata, dma_addr_t iv_out_dma[],
|
||||
unsigned int iv_out_dma_len, unsigned int iv_out_size,
|
||||
struct cc_hw_desc iv_seq[], unsigned int *iv_seq_len)
|
||||
{
|
||||
struct cc_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle;
|
||||
unsigned int idx = *iv_seq_len;
|
||||
struct device *dev = drvdata_to_dev(drvdata);
|
||||
unsigned int t;
|
||||
|
||||
if (iv_out_size != CC_AES_IV_SIZE &&
|
||||
iv_out_size != CTR_RFC3686_IV_SIZE) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((iv_out_dma_len + 1) > CC_IVPOOL_SEQ_LEN) {
|
||||
/* The sequence will be longer than allowed */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check that number of generated IV is limited to max dma address
|
||||
* iv buffer size
|
||||
*/
|
||||
if (iv_out_dma_len > CC_MAX_IVGEN_DMA_ADDRESSES) {
|
||||
/* The sequence will be longer than allowed */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (t = 0; t < iv_out_dma_len; t++) {
|
||||
/* Acquire IV from pool */
|
||||
hw_desc_init(&iv_seq[idx]);
|
||||
set_din_sram(&iv_seq[idx], (ivgen_ctx->pool +
|
||||
ivgen_ctx->next_iv_ofs),
|
||||
iv_out_size);
|
||||
set_dout_dlli(&iv_seq[idx], iv_out_dma[t], iv_out_size,
|
||||
NS_BIT, 0);
|
||||
set_flow_mode(&iv_seq[idx], BYPASS);
|
||||
idx++;
|
||||
}
|
||||
|
||||
/* Bypass operation is proceeded by crypto sequence, hence must
|
||||
* assure bypass-write-transaction by a memory barrier
|
||||
*/
|
||||
hw_desc_init(&iv_seq[idx]);
|
||||
set_din_no_dma(&iv_seq[idx], 0, 0xfffff0);
|
||||
set_dout_no_dma(&iv_seq[idx], 0, 0, 1);
|
||||
idx++;
|
||||
|
||||
*iv_seq_len = idx; /* update seq length */
|
||||
|
||||
/* Update iv index */
|
||||
ivgen_ctx->next_iv_ofs += iv_out_size;
|
||||
|
||||
if ((CC_IVPOOL_SIZE - ivgen_ctx->next_iv_ofs) < CC_AES_IV_SIZE) {
|
||||
dev_dbg(dev, "Pool exhausted, regenerating iv-pool\n");
|
||||
/* pool is drained -regenerate it! */
|
||||
return cc_gen_iv_pool(ivgen_ctx, iv_seq, iv_seq_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
55
drivers/crypto/ccree/cc_ivgen.h
Normal file
55
drivers/crypto/ccree/cc_ivgen.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#ifndef __CC_IVGEN_H__
|
||||
#define __CC_IVGEN_H__
|
||||
|
||||
#include "cc_hw_queue_defs.h"
|
||||
|
||||
#define CC_IVPOOL_SEQ_LEN 8
|
||||
|
||||
/*!
|
||||
* Allocates iv-pool and maps resources.
|
||||
* This function generates the first IV pool.
|
||||
*
|
||||
* \param drvdata Driver's private context
|
||||
*
|
||||
* \return int Zero for success, negative value otherwise.
|
||||
*/
|
||||
int cc_ivgen_init(struct cc_drvdata *drvdata);
|
||||
|
||||
/*!
|
||||
* Free iv-pool and ivgen context.
|
||||
*
|
||||
* \param drvdata
|
||||
*/
|
||||
void cc_ivgen_fini(struct cc_drvdata *drvdata);
|
||||
|
||||
/*!
|
||||
* Generates the initial pool in SRAM.
|
||||
* This function should be invoked when resuming DX driver.
|
||||
*
|
||||
* \param drvdata
|
||||
*
|
||||
* \return int Zero for success, negative value otherwise.
|
||||
*/
|
||||
int cc_init_iv_sram(struct cc_drvdata *drvdata);
|
||||
|
||||
/*!
|
||||
* Acquires 16 Bytes IV from the iv-pool
|
||||
*
|
||||
* \param drvdata Driver private context
|
||||
* \param iv_out_dma Array of physical IV out addresses
|
||||
* \param iv_out_dma_len Length of iv_out_dma array (additional elements of
|
||||
* iv_out_dma array are ignore)
|
||||
* \param iv_out_size May be 8 or 16 bytes long
|
||||
* \param iv_seq IN/OUT array to the descriptors sequence
|
||||
* \param iv_seq_len IN/OUT pointer to the sequence length
|
||||
*
|
||||
* \return int Zero for success, negative value otherwise.
|
||||
*/
|
||||
int cc_get_iv(struct cc_drvdata *drvdata, dma_addr_t iv_out_dma[],
|
||||
unsigned int iv_out_dma_len, unsigned int iv_out_size,
|
||||
struct cc_hw_desc iv_seq[], unsigned int *iv_seq_len);
|
||||
|
||||
#endif /*__CC_IVGEN_H__*/
|
||||
167
drivers/crypto/ccree/cc_kernel_regs.h
Normal file
167
drivers/crypto/ccree/cc_kernel_regs.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#ifndef __CC_CRYS_KERNEL_H__
|
||||
#define __CC_CRYS_KERNEL_H__
|
||||
|
||||
// --------------------------------------
|
||||
// BLOCK: DSCRPTR
|
||||
// --------------------------------------
|
||||
#define CC_DSCRPTR_COMPLETION_COUNTER_REG_OFFSET 0xE00UL
|
||||
#define CC_DSCRPTR_COMPLETION_COUNTER_COMPLETION_COUNTER_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_COMPLETION_COUNTER_COMPLETION_COUNTER_BIT_SIZE 0x6UL
|
||||
#define CC_DSCRPTR_COMPLETION_COUNTER_OVERFLOW_COUNTER_BIT_SHIFT 0x6UL
|
||||
#define CC_DSCRPTR_COMPLETION_COUNTER_OVERFLOW_COUNTER_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_SW_RESET_REG_OFFSET 0xE40UL
|
||||
#define CC_DSCRPTR_SW_RESET_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_SW_RESET_VALUE_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_REG_OFFSET 0xE60UL
|
||||
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_NUM_OF_DSCRPTR_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_NUM_OF_DSCRPTR_BIT_SIZE 0xAUL
|
||||
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_DSCRPTR_SRAM_SIZE_BIT_SHIFT 0xAUL
|
||||
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_DSCRPTR_SRAM_SIZE_BIT_SIZE 0xCUL
|
||||
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_SRAM_SIZE_BIT_SHIFT 0x16UL
|
||||
#define CC_DSCRPTR_QUEUE_SRAM_SIZE_SRAM_SIZE_BIT_SIZE 0x3UL
|
||||
#define CC_DSCRPTR_SINGLE_ADDR_EN_REG_OFFSET 0xE64UL
|
||||
#define CC_DSCRPTR_SINGLE_ADDR_EN_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_SINGLE_ADDR_EN_VALUE_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_MEASURE_CNTR_REG_OFFSET 0xE68UL
|
||||
#define CC_DSCRPTR_MEASURE_CNTR_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_MEASURE_CNTR_VALUE_BIT_SIZE 0x20UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD0_REG_OFFSET 0xE80UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD0_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD0_VALUE_BIT_SIZE 0x20UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_REG_OFFSET 0xE84UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_DIN_DMA_MODE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_DIN_DMA_MODE_BIT_SIZE 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SHIFT 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SIZE 0x18UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_NS_BIT_BIT_SHIFT 0x1AUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_NS_BIT_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_DIN_CONST_VALUE_BIT_SHIFT 0x1BUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_DIN_CONST_VALUE_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_NOT_LAST_BIT_SHIFT 0x1CUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_NOT_LAST_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_LOCK_QUEUE_BIT_SHIFT 0x1DUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_LOCK_QUEUE_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_NOT_USED_BIT_SHIFT 0x1EUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD1_NOT_USED_BIT_SIZE 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD2_REG_OFFSET 0xE88UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD2_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD2_VALUE_BIT_SIZE 0x20UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_REG_OFFSET 0xE8CUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_DMA_MODE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_DMA_MODE_BIT_SIZE 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_SIZE_BIT_SHIFT 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_SIZE_BIT_SIZE 0x18UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_NS_BIT_BIT_SHIFT 0x1AUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_NS_BIT_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_LAST_IND_BIT_SHIFT 0x1BUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_DOUT_LAST_IND_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_HASH_XOR_BIT_BIT_SHIFT 0x1DUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_HASH_XOR_BIT_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_NOT_USED_BIT_SHIFT 0x1EUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_NOT_USED_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_QUEUE_LAST_IND_BIT_SHIFT 0x1FUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD3_QUEUE_LAST_IND_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_REG_OFFSET 0xE90UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_DATA_FLOW_MODE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_DATA_FLOW_MODE_BIT_SIZE 0x6UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_AES_SEL_N_HASH_BIT_SHIFT 0x6UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_AES_SEL_N_HASH_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_AES_XOR_CRYPTO_KEY_BIT_SHIFT 0x7UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_AES_XOR_CRYPTO_KEY_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_ACK_NEEDED_BIT_SHIFT 0x8UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_ACK_NEEDED_BIT_SIZE 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_MODE_BIT_SHIFT 0xAUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_MODE_BIT_SIZE 0x4UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CMAC_SIZE0_BIT_SHIFT 0xEUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CMAC_SIZE0_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_DO_BIT_SHIFT 0xFUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_DO_BIT_SIZE 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF0_BIT_SHIFT 0x11UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF0_BIT_SIZE 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF1_BIT_SHIFT 0x13UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF1_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF2_BIT_SHIFT 0x14UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF2_BIT_SIZE 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_KEY_SIZE_BIT_SHIFT 0x16UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_KEY_SIZE_BIT_SIZE 0x2UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_SETUP_OPERATION_BIT_SHIFT 0x18UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_SETUP_OPERATION_BIT_SIZE 0x4UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_DIN_SRAM_ENDIANNESS_BIT_SHIFT 0x1CUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_DIN_SRAM_ENDIANNESS_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_DOUT_SRAM_ENDIANNESS_BIT_SHIFT 0x1DUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_DOUT_SRAM_ENDIANNESS_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_WORD_SWAP_BIT_SHIFT 0x1EUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_WORD_SWAP_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_BYTES_SWAP_BIT_SHIFT 0x1FUL
|
||||
#define CC_DSCRPTR_QUEUE_WORD4_BYTES_SWAP_BIT_SIZE 0x1UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD5_REG_OFFSET 0xE94UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD5_DIN_ADDR_HIGH_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD5_DIN_ADDR_HIGH_BIT_SIZE 0x10UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD5_DOUT_ADDR_HIGH_BIT_SHIFT 0x10UL
|
||||
#define CC_DSCRPTR_QUEUE_WORD5_DOUT_ADDR_HIGH_BIT_SIZE 0x10UL
|
||||
#define CC_DSCRPTR_QUEUE_WATERMARK_REG_OFFSET 0xE98UL
|
||||
#define CC_DSCRPTR_QUEUE_WATERMARK_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_QUEUE_WATERMARK_VALUE_BIT_SIZE 0xAUL
|
||||
#define CC_DSCRPTR_QUEUE_CONTENT_REG_OFFSET 0xE9CUL
|
||||
#define CC_DSCRPTR_QUEUE_CONTENT_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_DSCRPTR_QUEUE_CONTENT_VALUE_BIT_SIZE 0xAUL
|
||||
// --------------------------------------
|
||||
// BLOCK: AXI_P
|
||||
// --------------------------------------
|
||||
#define CC_AXIM_MON_INFLIGHT_REG_OFFSET 0xB00UL
|
||||
#define CC_AXIM_MON_INFLIGHT_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_AXIM_MON_INFLIGHT_VALUE_BIT_SIZE 0x8UL
|
||||
#define CC_AXIM_MON_INFLIGHTLAST_REG_OFFSET 0xB40UL
|
||||
#define CC_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SIZE 0x8UL
|
||||
#define CC_AXIM_MON_COMP_REG_OFFSET 0xB80UL
|
||||
#define CC_AXIM_MON_COMP_VALUE_BIT_SHIFT 0x0UL
|
||||
#define CC_AXIM_MON_COMP_VALUE_BIT_SIZE 0x10UL
|
||||
#define CC_AXIM_MON_ERR_REG_OFFSET 0xBC4UL
|
||||
#define CC_AXIM_MON_ERR_BRESP_BIT_SHIFT 0x0UL
|
||||
#define CC_AXIM_MON_ERR_BRESP_BIT_SIZE 0x2UL
|
||||
#define CC_AXIM_MON_ERR_BID_BIT_SHIFT 0x2UL
|
||||
#define CC_AXIM_MON_ERR_BID_BIT_SIZE 0x4UL
|
||||
#define CC_AXIM_MON_ERR_RRESP_BIT_SHIFT 0x10UL
|
||||
#define CC_AXIM_MON_ERR_RRESP_BIT_SIZE 0x2UL
|
||||
#define CC_AXIM_MON_ERR_RID_BIT_SHIFT 0x12UL
|
||||
#define CC_AXIM_MON_ERR_RID_BIT_SIZE 0x4UL
|
||||
#define CC_AXIM_CFG_REG_OFFSET 0xBE8UL
|
||||
#define CC_AXIM_CFG_BRESPMASK_BIT_SHIFT 0x4UL
|
||||
#define CC_AXIM_CFG_BRESPMASK_BIT_SIZE 0x1UL
|
||||
#define CC_AXIM_CFG_RRESPMASK_BIT_SHIFT 0x5UL
|
||||
#define CC_AXIM_CFG_RRESPMASK_BIT_SIZE 0x1UL
|
||||
#define CC_AXIM_CFG_INFLTMASK_BIT_SHIFT 0x6UL
|
||||
#define CC_AXIM_CFG_INFLTMASK_BIT_SIZE 0x1UL
|
||||
#define CC_AXIM_CFG_COMPMASK_BIT_SHIFT 0x7UL
|
||||
#define CC_AXIM_CFG_COMPMASK_BIT_SIZE 0x1UL
|
||||
#define CC_AXIM_ACE_CONST_REG_OFFSET 0xBECUL
|
||||
#define CC_AXIM_ACE_CONST_ARDOMAIN_BIT_SHIFT 0x0UL
|
||||
#define CC_AXIM_ACE_CONST_ARDOMAIN_BIT_SIZE 0x2UL
|
||||
#define CC_AXIM_ACE_CONST_AWDOMAIN_BIT_SHIFT 0x2UL
|
||||
#define CC_AXIM_ACE_CONST_AWDOMAIN_BIT_SIZE 0x2UL
|
||||
#define CC_AXIM_ACE_CONST_ARBAR_BIT_SHIFT 0x4UL
|
||||
#define CC_AXIM_ACE_CONST_ARBAR_BIT_SIZE 0x2UL
|
||||
#define CC_AXIM_ACE_CONST_AWBAR_BIT_SHIFT 0x6UL
|
||||
#define CC_AXIM_ACE_CONST_AWBAR_BIT_SIZE 0x2UL
|
||||
#define CC_AXIM_ACE_CONST_ARSNOOP_BIT_SHIFT 0x8UL
|
||||
#define CC_AXIM_ACE_CONST_ARSNOOP_BIT_SIZE 0x4UL
|
||||
#define CC_AXIM_ACE_CONST_AWSNOOP_NOT_ALIGNED_BIT_SHIFT 0xCUL
|
||||
#define CC_AXIM_ACE_CONST_AWSNOOP_NOT_ALIGNED_BIT_SIZE 0x3UL
|
||||
#define CC_AXIM_ACE_CONST_AWSNOOP_ALIGNED_BIT_SHIFT 0xFUL
|
||||
#define CC_AXIM_ACE_CONST_AWSNOOP_ALIGNED_BIT_SIZE 0x3UL
|
||||
#define CC_AXIM_ACE_CONST_AWADDR_NOT_MASKED_BIT_SHIFT 0x12UL
|
||||
#define CC_AXIM_ACE_CONST_AWADDR_NOT_MASKED_BIT_SIZE 0x7UL
|
||||
#define CC_AXIM_ACE_CONST_AWLEN_VAL_BIT_SHIFT 0x19UL
|
||||
#define CC_AXIM_ACE_CONST_AWLEN_VAL_BIT_SIZE 0x4UL
|
||||
#define CC_AXIM_CACHE_PARAMS_REG_OFFSET 0xBF0UL
|
||||
#define CC_AXIM_CACHE_PARAMS_AWCACHE_LAST_BIT_SHIFT 0x0UL
|
||||
#define CC_AXIM_CACHE_PARAMS_AWCACHE_LAST_BIT_SIZE 0x4UL
|
||||
#define CC_AXIM_CACHE_PARAMS_AWCACHE_BIT_SHIFT 0x4UL
|
||||
#define CC_AXIM_CACHE_PARAMS_AWCACHE_BIT_SIZE 0x4UL
|
||||
#define CC_AXIM_CACHE_PARAMS_ARCACHE_BIT_SHIFT 0x8UL
|
||||
#define CC_AXIM_CACHE_PARAMS_ARCACHE_BIT_SIZE 0x4UL
|
||||
#endif // __CC_CRYS_KERNEL_H__
|
||||
59
drivers/crypto/ccree/cc_lli_defs.h
Normal file
59
drivers/crypto/ccree/cc_lli_defs.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#ifndef _CC_LLI_DEFS_H_
|
||||
#define _CC_LLI_DEFS_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* Max DLLI size
|
||||
* AKA CC_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SIZE
|
||||
*/
|
||||
#define DLLI_SIZE_BIT_SIZE 0x18
|
||||
|
||||
#define CC_MAX_MLLI_ENTRY_SIZE 0xFFFF
|
||||
|
||||
#define LLI_MAX_NUM_OF_DATA_ENTRIES 128
|
||||
#define LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES 4
|
||||
#define MLLI_TABLE_MIN_ALIGNMENT 4 /* 32 bit alignment */
|
||||
#define MAX_NUM_OF_BUFFERS_IN_MLLI 4
|
||||
#define MAX_NUM_OF_TOTAL_MLLI_ENTRIES \
|
||||
(2 * LLI_MAX_NUM_OF_DATA_ENTRIES + \
|
||||
LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES)
|
||||
|
||||
/* Size of entry */
|
||||
#define LLI_ENTRY_WORD_SIZE 2
|
||||
#define LLI_ENTRY_BYTE_SIZE (LLI_ENTRY_WORD_SIZE * sizeof(u32))
|
||||
|
||||
/* Word0[31:0] = ADDR[31:0] */
|
||||
#define LLI_WORD0_OFFSET 0
|
||||
#define LLI_LADDR_BIT_OFFSET 0
|
||||
#define LLI_LADDR_BIT_SIZE 32
|
||||
/* Word1[31:16] = ADDR[47:32]; Word1[15:0] = SIZE */
|
||||
#define LLI_WORD1_OFFSET 1
|
||||
#define LLI_SIZE_BIT_OFFSET 0
|
||||
#define LLI_SIZE_BIT_SIZE 16
|
||||
#define LLI_HADDR_BIT_OFFSET 16
|
||||
#define LLI_HADDR_BIT_SIZE 16
|
||||
|
||||
#define LLI_SIZE_MASK GENMASK((LLI_SIZE_BIT_SIZE - 1), LLI_SIZE_BIT_OFFSET)
|
||||
#define LLI_HADDR_MASK GENMASK( \
|
||||
(LLI_HADDR_BIT_OFFSET + LLI_HADDR_BIT_SIZE - 1),\
|
||||
LLI_HADDR_BIT_OFFSET)
|
||||
|
||||
static inline void cc_lli_set_addr(u32 *lli_p, dma_addr_t addr)
|
||||
{
|
||||
lli_p[LLI_WORD0_OFFSET] = (addr & U32_MAX);
|
||||
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||
lli_p[LLI_WORD1_OFFSET] &= ~LLI_HADDR_MASK;
|
||||
lli_p[LLI_WORD1_OFFSET] |= FIELD_PREP(LLI_HADDR_MASK, (addr >> 32));
|
||||
#endif /* CONFIG_ARCH_DMA_ADDR_T_64BIT */
|
||||
}
|
||||
|
||||
static inline void cc_lli_set_size(u32 *lli_p, u16 size)
|
||||
{
|
||||
lli_p[LLI_WORD1_OFFSET] &= ~LLI_SIZE_MASK;
|
||||
lli_p[LLI_WORD1_OFFSET] |= FIELD_PREP(LLI_SIZE_MASK, size);
|
||||
}
|
||||
|
||||
#endif /*_CC_LLI_DEFS_H_*/
|
||||
118
drivers/crypto/ccree/cc_pm.c
Normal file
118
drivers/crypto/ccree/cc_pm.c
Normal file
@@ -0,0 +1,118 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include "cc_driver.h"
|
||||
#include "cc_buffer_mgr.h"
|
||||
#include "cc_request_mgr.h"
|
||||
#include "cc_sram_mgr.h"
|
||||
#include "cc_ivgen.h"
|
||||
#include "cc_pm.h"
|
||||
|
||||
#define POWER_DOWN_ENABLE 0x01
|
||||
#define POWER_DOWN_DISABLE 0x00
|
||||
|
||||
const struct dev_pm_ops ccree_pm = {
|
||||
SET_RUNTIME_PM_OPS(cc_pm_suspend, cc_pm_resume, NULL)
|
||||
};
|
||||
|
||||
int cc_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
|
||||
int rc;
|
||||
|
||||
dev_dbg(dev, "set HOST_POWER_DOWN_EN\n");
|
||||
cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_ENABLE);
|
||||
rc = cc_suspend_req_queue(drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "cc_suspend_req_queue (%x)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
fini_cc_regs(drvdata);
|
||||
cc_clk_off(drvdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cc_pm_resume(struct device *dev)
|
||||
{
|
||||
int rc;
|
||||
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
|
||||
|
||||
dev_dbg(dev, "unset HOST_POWER_DOWN_EN\n");
|
||||
cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_DISABLE);
|
||||
|
||||
rc = cc_clk_on(drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "failed getting clock back on. We're toast.\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = init_cc_regs(drvdata, false);
|
||||
if (rc) {
|
||||
dev_err(dev, "init_cc_regs (%x)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = cc_resume_req_queue(drvdata);
|
||||
if (rc) {
|
||||
dev_err(dev, "cc_resume_req_queue (%x)\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
cc_init_iv_sram(drvdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cc_pm_get(struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
|
||||
|
||||
if (cc_req_queue_suspended(drvdata))
|
||||
rc = pm_runtime_get_sync(dev);
|
||||
else
|
||||
pm_runtime_get_noresume(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cc_pm_put_suspend(struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
|
||||
|
||||
if (!cc_req_queue_suspended(drvdata)) {
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
rc = pm_runtime_put_autosuspend(dev);
|
||||
} else {
|
||||
/* Something wrong happens*/
|
||||
dev_err(dev, "request to suspend already suspended queue");
|
||||
rc = -EBUSY;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cc_pm_init(struct cc_drvdata *drvdata)
|
||||
{
|
||||
int rc = 0;
|
||||
struct device *dev = drvdata_to_dev(drvdata);
|
||||
|
||||
/* must be before the enabling to avoid resdundent suspending */
|
||||
pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
/* activate the PM module */
|
||||
rc = pm_runtime_set_active(dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
/* enable the PM module*/
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void cc_pm_fini(struct cc_drvdata *drvdata)
|
||||
{
|
||||
pm_runtime_disable(drvdata_to_dev(drvdata));
|
||||
}
|
||||
56
drivers/crypto/ccree/cc_pm.h
Normal file
56
drivers/crypto/ccree/cc_pm.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
/* \file cc_pm.h
|
||||
*/
|
||||
|
||||
#ifndef __CC_POWER_MGR_H__
|
||||
#define __CC_POWER_MGR_H__
|
||||
|
||||
#include "cc_driver.h"
|
||||
|
||||
#define CC_SUSPEND_TIMEOUT 3000
|
||||
|
||||
#if defined(CONFIG_PM)
|
||||
|
||||
extern const struct dev_pm_ops ccree_pm;
|
||||
|
||||
int cc_pm_init(struct cc_drvdata *drvdata);
|
||||
void cc_pm_fini(struct cc_drvdata *drvdata);
|
||||
int cc_pm_suspend(struct device *dev);
|
||||
int cc_pm_resume(struct device *dev);
|
||||
int cc_pm_get(struct device *dev);
|
||||
int cc_pm_put_suspend(struct device *dev);
|
||||
|
||||
#else
|
||||
|
||||
static inline int cc_pm_init(struct cc_drvdata *drvdata)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cc_pm_fini(struct cc_drvdata *drvdata) {}
|
||||
|
||||
static inline int cc_pm_suspend(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cc_pm_resume(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cc_pm_get(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cc_pm_put_suspend(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*__POWER_MGR_H__*/
|
||||
712
drivers/crypto/ccree/cc_request_mgr.c
Normal file
712
drivers/crypto/ccree/cc_request_mgr.c
Normal file
File diff suppressed because it is too large
Load Diff
51
drivers/crypto/ccree/cc_request_mgr.h
Normal file
51
drivers/crypto/ccree/cc_request_mgr.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */
|
||||
|
||||
/* \file cc_request_mgr.h
|
||||
* Request Manager
|
||||
*/
|
||||
|
||||
#ifndef __REQUEST_MGR_H__
|
||||
#define __REQUEST_MGR_H__
|
||||
|
||||
#include "cc_hw_queue_defs.h"
|
||||
|
||||
int cc_req_mgr_init(struct cc_drvdata *drvdata);
|
||||
|
||||
/*!
|
||||
* Enqueue caller request to crypto hardware.
|
||||
*
|
||||
* \param drvdata
|
||||
* \param cc_req The request to enqueue
|
||||
* \param desc The crypto sequence
|
||||
* \param len The crypto sequence length
|
||||
* \param is_dout If "true": completion is handled by the caller
|
||||
* If "false": this function adds a dummy descriptor completion
|
||||
* and waits upon completion signal.
|
||||
*
|
||||
* \return int Returns -EINPROGRESS or error
|
||||
*/
|
||||
int cc_send_request(struct cc_drvdata *drvdata, struct cc_crypto_req *cc_req,
|
||||
struct cc_hw_desc *desc, unsigned int len,
|
||||
struct crypto_async_request *req);
|
||||
|
||||
int cc_send_sync_request(struct cc_drvdata *drvdata,
|
||||
struct cc_crypto_req *cc_req, struct cc_hw_desc *desc,
|
||||
unsigned int len);
|
||||
|
||||
int send_request_init(struct cc_drvdata *drvdata, struct cc_hw_desc *desc,
|
||||
unsigned int len);
|
||||
|
||||
void complete_request(struct cc_drvdata *drvdata);
|
||||
|
||||
void cc_req_mgr_fini(struct cc_drvdata *drvdata);
|
||||
|
||||
#if defined(CONFIG_PM)
|
||||
int cc_resume_req_queue(struct cc_drvdata *drvdata);
|
||||
|
||||
int cc_suspend_req_queue(struct cc_drvdata *drvdata);
|
||||
|
||||
bool cc_req_queue_suspended(struct cc_drvdata *drvdata);
|
||||
#endif
|
||||
|
||||
#endif /*__REQUEST_MGR_H__*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user