mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
7.2 KiB
245 lines
7.2 KiB
/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|
/* |
|
* AMCC SoC PPC4xx Crypto Driver |
|
* |
|
* Copyright (c) 2008 Applied Micro Circuits Corporation. |
|
* All rights reserved. James Hsiao <[email protected]> |
|
* |
|
* This is the header file for AMCC Crypto offload Linux device driver for |
|
* use with Linux CryptoAPI. |
|
|
|
*/ |
|
|
|
#ifndef __CRYPTO4XX_CORE_H__ |
|
#define __CRYPTO4XX_CORE_H__ |
|
|
|
#include <linux/ratelimit.h> |
|
#include <linux/mutex.h> |
|
#include <linux/scatterlist.h> |
|
#include <crypto/internal/hash.h> |
|
#include <crypto/internal/aead.h> |
|
#include <crypto/internal/rng.h> |
|
#include <crypto/internal/skcipher.h> |
|
#include "crypto4xx_reg_def.h" |
|
#include "crypto4xx_sa.h" |
|
|
|
#define PPC460SX_SDR0_SRST 0x201 |
|
#define PPC405EX_SDR0_SRST 0x200 |
|
#define PPC460EX_SDR0_SRST 0x201 |
|
#define PPC460EX_CE_RESET 0x08000000 |
|
#define PPC460SX_CE_RESET 0x20000000 |
|
#define PPC405EX_CE_RESET 0x00000008 |
|
|
|
#define CRYPTO4XX_CRYPTO_PRIORITY 300 |
|
#define PPC4XX_NUM_PD 256 |
|
#define PPC4XX_LAST_PD (PPC4XX_NUM_PD - 1) |
|
#define PPC4XX_NUM_GD 1024 |
|
#define PPC4XX_LAST_GD (PPC4XX_NUM_GD - 1) |
|
#define PPC4XX_NUM_SD 256 |
|
#define PPC4XX_LAST_SD (PPC4XX_NUM_SD - 1) |
|
#define PPC4XX_SD_BUFFER_SIZE 2048 |
|
|
|
#define PD_ENTRY_BUSY BIT(1) |
|
#define PD_ENTRY_INUSE BIT(0) |
|
#define PD_ENTRY_FREE 0 |
|
#define ERING_WAS_FULL 0xffffffff |
|
|
|
struct crypto4xx_device; |
|
|
|
union shadow_sa_buf { |
|
struct dynamic_sa_ctl sa; |
|
|
|
/* alloc 256 bytes which is enough for any kind of dynamic sa */ |
|
u8 buf[256]; |
|
} __packed; |
|
|
|
struct pd_uinfo { |
|
struct crypto4xx_device *dev; |
|
u32 state; |
|
u32 first_gd; /* first gather discriptor |
|
used by this packet */ |
|
u32 num_gd; /* number of gather discriptor |
|
used by this packet */ |
|
u32 first_sd; /* first scatter discriptor |
|
used by this packet */ |
|
u32 num_sd; /* number of scatter discriptors |
|
used by this packet */ |
|
struct dynamic_sa_ctl *sa_va; /* shadow sa */ |
|
struct sa_state_record *sr_va; /* state record for shadow sa */ |
|
u32 sr_pa; |
|
struct scatterlist *dest_va; |
|
struct crypto_async_request *async_req; /* base crypto request |
|
for this packet */ |
|
}; |
|
|
|
struct crypto4xx_device { |
|
struct crypto4xx_core_device *core_dev; |
|
void __iomem *ce_base; |
|
void __iomem *trng_base; |
|
|
|
struct ce_pd *pdr; /* base address of packet descriptor ring */ |
|
dma_addr_t pdr_pa; /* physical address of pdr_base_register */ |
|
struct ce_gd *gdr; /* gather descriptor ring */ |
|
dma_addr_t gdr_pa; /* physical address of gdr_base_register */ |
|
struct ce_sd *sdr; /* scatter descriptor ring */ |
|
dma_addr_t sdr_pa; /* physical address of sdr_base_register */ |
|
void *scatter_buffer_va; |
|
dma_addr_t scatter_buffer_pa; |
|
|
|
union shadow_sa_buf *shadow_sa_pool; |
|
dma_addr_t shadow_sa_pool_pa; |
|
struct sa_state_record *shadow_sr_pool; |
|
dma_addr_t shadow_sr_pool_pa; |
|
u32 pdr_tail; |
|
u32 pdr_head; |
|
u32 gdr_tail; |
|
u32 gdr_head; |
|
u32 sdr_tail; |
|
u32 sdr_head; |
|
struct pd_uinfo *pdr_uinfo; |
|
struct list_head alg_list; /* List of algorithm supported |
|
by this device */ |
|
struct ratelimit_state aead_ratelimit; |
|
bool is_revb; |
|
}; |
|
|
|
struct crypto4xx_core_device { |
|
struct device *device; |
|
struct platform_device *ofdev; |
|
struct crypto4xx_device *dev; |
|
struct hwrng *trng; |
|
u32 int_status; |
|
u32 irq; |
|
struct tasklet_struct tasklet; |
|
spinlock_t lock; |
|
struct mutex rng_lock; |
|
}; |
|
|
|
struct crypto4xx_ctx { |
|
struct crypto4xx_device *dev; |
|
struct dynamic_sa_ctl *sa_in; |
|
struct dynamic_sa_ctl *sa_out; |
|
__le32 iv_nonce; |
|
u32 sa_len; |
|
union { |
|
struct crypto_sync_skcipher *cipher; |
|
struct crypto_aead *aead; |
|
} sw_cipher; |
|
}; |
|
|
|
struct crypto4xx_aead_reqctx { |
|
struct scatterlist dst[2]; |
|
}; |
|
|
|
struct crypto4xx_alg_common { |
|
u32 type; |
|
union { |
|
struct skcipher_alg cipher; |
|
struct ahash_alg hash; |
|
struct aead_alg aead; |
|
struct rng_alg rng; |
|
} u; |
|
}; |
|
|
|
struct crypto4xx_alg { |
|
struct list_head entry; |
|
struct crypto4xx_alg_common alg; |
|
struct crypto4xx_device *dev; |
|
}; |
|
|
|
int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size); |
|
void crypto4xx_free_sa(struct crypto4xx_ctx *ctx); |
|
void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx); |
|
int crypto4xx_build_pd(struct crypto_async_request *req, |
|
struct crypto4xx_ctx *ctx, |
|
struct scatterlist *src, |
|
struct scatterlist *dst, |
|
const unsigned int datalen, |
|
const __le32 *iv, const u32 iv_len, |
|
const struct dynamic_sa_ctl *sa, |
|
const unsigned int sa_len, |
|
const unsigned int assoclen, |
|
struct scatterlist *dst_tmp); |
|
int crypto4xx_setkey_aes_cbc(struct crypto_skcipher *cipher, |
|
const u8 *key, unsigned int keylen); |
|
int crypto4xx_setkey_aes_cfb(struct crypto_skcipher *cipher, |
|
const u8 *key, unsigned int keylen); |
|
int crypto4xx_setkey_aes_ctr(struct crypto_skcipher *cipher, |
|
const u8 *key, unsigned int keylen); |
|
int crypto4xx_setkey_aes_ecb(struct crypto_skcipher *cipher, |
|
const u8 *key, unsigned int keylen); |
|
int crypto4xx_setkey_aes_ofb(struct crypto_skcipher *cipher, |
|
const u8 *key, unsigned int keylen); |
|
int crypto4xx_setkey_rfc3686(struct crypto_skcipher *cipher, |
|
const u8 *key, unsigned int keylen); |
|
int crypto4xx_encrypt_ctr(struct skcipher_request *req); |
|
int crypto4xx_decrypt_ctr(struct skcipher_request *req); |
|
int crypto4xx_encrypt_iv_stream(struct skcipher_request *req); |
|
int crypto4xx_decrypt_iv_stream(struct skcipher_request *req); |
|
int crypto4xx_encrypt_iv_block(struct skcipher_request *req); |
|
int crypto4xx_decrypt_iv_block(struct skcipher_request *req); |
|
int crypto4xx_encrypt_noiv_block(struct skcipher_request *req); |
|
int crypto4xx_decrypt_noiv_block(struct skcipher_request *req); |
|
int crypto4xx_rfc3686_encrypt(struct skcipher_request *req); |
|
int crypto4xx_rfc3686_decrypt(struct skcipher_request *req); |
|
int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm); |
|
int crypto4xx_hash_digest(struct ahash_request *req); |
|
int crypto4xx_hash_final(struct ahash_request *req); |
|
int crypto4xx_hash_update(struct ahash_request *req); |
|
int crypto4xx_hash_init(struct ahash_request *req); |
|
|
|
/* |
|
* Note: Only use this function to copy items that is word aligned. |
|
*/ |
|
static inline void crypto4xx_memcpy_swab32(u32 *dst, const void *buf, |
|
size_t len) |
|
{ |
|
for (; len >= 4; buf += 4, len -= 4) |
|
*dst++ = __swab32p((u32 *) buf); |
|
|
|
if (len) { |
|
const u8 *tmp = (u8 *)buf; |
|
|
|
switch (len) { |
|
case 3: |
|
*dst = (tmp[2] << 16) | |
|
(tmp[1] << 8) | |
|
tmp[0]; |
|
break; |
|
case 2: |
|
*dst = (tmp[1] << 8) | |
|
tmp[0]; |
|
break; |
|
case 1: |
|
*dst = tmp[0]; |
|
break; |
|
default: |
|
break; |
|
} |
|
} |
|
} |
|
|
|
static inline void crypto4xx_memcpy_from_le32(u32 *dst, const void *buf, |
|
size_t len) |
|
{ |
|
crypto4xx_memcpy_swab32(dst, buf, len); |
|
} |
|
|
|
static inline void crypto4xx_memcpy_to_le32(__le32 *dst, const void *buf, |
|
size_t len) |
|
{ |
|
crypto4xx_memcpy_swab32((u32 *)dst, buf, len); |
|
} |
|
|
|
int crypto4xx_setauthsize_aead(struct crypto_aead *ciper, |
|
unsigned int authsize); |
|
int crypto4xx_setkey_aes_ccm(struct crypto_aead *cipher, |
|
const u8 *key, unsigned int keylen); |
|
int crypto4xx_encrypt_aes_ccm(struct aead_request *req); |
|
int crypto4xx_decrypt_aes_ccm(struct aead_request *req); |
|
int crypto4xx_setkey_aes_gcm(struct crypto_aead *cipher, |
|
const u8 *key, unsigned int keylen); |
|
int crypto4xx_encrypt_aes_gcm(struct aead_request *req); |
|
int crypto4xx_decrypt_aes_gcm(struct aead_request *req); |
|
|
|
#endif
|
|
|