162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 262306a36Sopenharmony_ci#ifndef __ASPEED_HACE_H__ 362306a36Sopenharmony_ci#define __ASPEED_HACE_H__ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <crypto/aes.h> 662306a36Sopenharmony_ci#include <crypto/engine.h> 762306a36Sopenharmony_ci#include <crypto/hash.h> 862306a36Sopenharmony_ci#include <crypto/sha2.h> 962306a36Sopenharmony_ci#include <linux/bits.h> 1062306a36Sopenharmony_ci#include <linux/compiler_attributes.h> 1162306a36Sopenharmony_ci#include <linux/interrupt.h> 1262306a36Sopenharmony_ci#include <linux/types.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/***************************** 1562306a36Sopenharmony_ci * * 1662306a36Sopenharmony_ci * HACE register definitions * 1762306a36Sopenharmony_ci * * 1862306a36Sopenharmony_ci * ***************************/ 1962306a36Sopenharmony_ci#define ASPEED_HACE_SRC 0x00 /* Crypto Data Source Base Address Register */ 2062306a36Sopenharmony_ci#define ASPEED_HACE_DEST 0x04 /* Crypto Data Destination Base Address Register */ 2162306a36Sopenharmony_ci#define ASPEED_HACE_CONTEXT 0x08 /* Crypto Context Buffer Base Address Register */ 2262306a36Sopenharmony_ci#define ASPEED_HACE_DATA_LEN 0x0C /* Crypto Data Length Register */ 2362306a36Sopenharmony_ci#define ASPEED_HACE_CMD 0x10 /* Crypto Engine Command Register */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* G5 */ 2662306a36Sopenharmony_ci#define ASPEED_HACE_TAG 0x18 /* HACE Tag Register */ 2762306a36Sopenharmony_ci/* G6 */ 2862306a36Sopenharmony_ci#define ASPEED_HACE_GCM_ADD_LEN 0x14 /* Crypto AES-GCM Additional Data Length Register */ 2962306a36Sopenharmony_ci#define ASPEED_HACE_GCM_TAG_BASE_ADDR 0x18 /* Crypto AES-GCM Tag Write Buff Base Address Reg */ 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#define ASPEED_HACE_STS 0x1C /* HACE Status Register */ 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define ASPEED_HACE_HASH_SRC 0x20 /* Hash Data Source Base Address Register */ 3462306a36Sopenharmony_ci#define ASPEED_HACE_HASH_DIGEST_BUFF 0x24 /* Hash Digest Write Buffer Base Address Register */ 3562306a36Sopenharmony_ci#define ASPEED_HACE_HASH_KEY_BUFF 0x28 /* Hash HMAC Key Buffer Base Address Register */ 3662306a36Sopenharmony_ci#define ASPEED_HACE_HASH_DATA_LEN 0x2C /* Hash Data Length Register */ 3762306a36Sopenharmony_ci#define ASPEED_HACE_HASH_CMD 0x30 /* Hash Engine Command Register */ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* crypto cmd */ 4062306a36Sopenharmony_ci#define HACE_CMD_SINGLE_DES 0 4162306a36Sopenharmony_ci#define HACE_CMD_TRIPLE_DES BIT(17) 4262306a36Sopenharmony_ci#define HACE_CMD_AES_SELECT 0 4362306a36Sopenharmony_ci#define HACE_CMD_DES_SELECT BIT(16) 4462306a36Sopenharmony_ci#define HACE_CMD_ISR_EN BIT(12) 4562306a36Sopenharmony_ci#define HACE_CMD_CONTEXT_SAVE_ENABLE (0) 4662306a36Sopenharmony_ci#define HACE_CMD_CONTEXT_SAVE_DISABLE BIT(9) 4762306a36Sopenharmony_ci#define HACE_CMD_AES (0) 4862306a36Sopenharmony_ci#define HACE_CMD_DES (0) 4962306a36Sopenharmony_ci#define HACE_CMD_RC4 BIT(8) 5062306a36Sopenharmony_ci#define HACE_CMD_DECRYPT (0) 5162306a36Sopenharmony_ci#define HACE_CMD_ENCRYPT BIT(7) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#define HACE_CMD_ECB (0x0 << 4) 5462306a36Sopenharmony_ci#define HACE_CMD_CBC (0x1 << 4) 5562306a36Sopenharmony_ci#define HACE_CMD_CFB (0x2 << 4) 5662306a36Sopenharmony_ci#define HACE_CMD_OFB (0x3 << 4) 5762306a36Sopenharmony_ci#define HACE_CMD_CTR (0x4 << 4) 5862306a36Sopenharmony_ci#define HACE_CMD_OP_MODE_MASK (0x7 << 4) 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#define HACE_CMD_AES128 (0x0 << 2) 6162306a36Sopenharmony_ci#define HACE_CMD_AES192 (0x1 << 2) 6262306a36Sopenharmony_ci#define HACE_CMD_AES256 (0x2 << 2) 6362306a36Sopenharmony_ci#define HACE_CMD_OP_CASCADE (0x3) 6462306a36Sopenharmony_ci#define HACE_CMD_OP_INDEPENDENT (0x1) 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* G5 */ 6762306a36Sopenharmony_ci#define HACE_CMD_RI_WO_DATA_ENABLE (0) 6862306a36Sopenharmony_ci#define HACE_CMD_RI_WO_DATA_DISABLE BIT(11) 6962306a36Sopenharmony_ci#define HACE_CMD_CONTEXT_LOAD_ENABLE (0) 7062306a36Sopenharmony_ci#define HACE_CMD_CONTEXT_LOAD_DISABLE BIT(10) 7162306a36Sopenharmony_ci/* G6 */ 7262306a36Sopenharmony_ci#define HACE_CMD_AES_KEY_FROM_OTP BIT(24) 7362306a36Sopenharmony_ci#define HACE_CMD_GHASH_TAG_XOR_EN BIT(23) 7462306a36Sopenharmony_ci#define HACE_CMD_GHASH_PAD_LEN_INV BIT(22) 7562306a36Sopenharmony_ci#define HACE_CMD_GCM_TAG_ADDR_SEL BIT(21) 7662306a36Sopenharmony_ci#define HACE_CMD_MBUS_REQ_SYNC_EN BIT(20) 7762306a36Sopenharmony_ci#define HACE_CMD_DES_SG_CTRL BIT(19) 7862306a36Sopenharmony_ci#define HACE_CMD_SRC_SG_CTRL BIT(18) 7962306a36Sopenharmony_ci#define HACE_CMD_CTR_IV_AES_96 (0x1 << 14) 8062306a36Sopenharmony_ci#define HACE_CMD_CTR_IV_DES_32 (0x1 << 14) 8162306a36Sopenharmony_ci#define HACE_CMD_CTR_IV_AES_64 (0x2 << 14) 8262306a36Sopenharmony_ci#define HACE_CMD_CTR_IV_AES_32 (0x3 << 14) 8362306a36Sopenharmony_ci#define HACE_CMD_AES_KEY_HW_EXP BIT(13) 8462306a36Sopenharmony_ci#define HACE_CMD_GCM (0x5 << 4) 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* interrupt status reg */ 8762306a36Sopenharmony_ci#define HACE_CRYPTO_ISR BIT(12) 8862306a36Sopenharmony_ci#define HACE_HASH_ISR BIT(9) 8962306a36Sopenharmony_ci#define HACE_HASH_BUSY BIT(0) 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci/* hash cmd reg */ 9262306a36Sopenharmony_ci#define HASH_CMD_MBUS_REQ_SYNC_EN BIT(20) 9362306a36Sopenharmony_ci#define HASH_CMD_HASH_SRC_SG_CTRL BIT(18) 9462306a36Sopenharmony_ci#define HASH_CMD_SHA512_224 (0x3 << 10) 9562306a36Sopenharmony_ci#define HASH_CMD_SHA512_256 (0x2 << 10) 9662306a36Sopenharmony_ci#define HASH_CMD_SHA384 (0x1 << 10) 9762306a36Sopenharmony_ci#define HASH_CMD_SHA512 (0) 9862306a36Sopenharmony_ci#define HASH_CMD_INT_ENABLE BIT(9) 9962306a36Sopenharmony_ci#define HASH_CMD_HMAC (0x1 << 7) 10062306a36Sopenharmony_ci#define HASH_CMD_ACC_MODE (0x2 << 7) 10162306a36Sopenharmony_ci#define HASH_CMD_HMAC_KEY (0x3 << 7) 10262306a36Sopenharmony_ci#define HASH_CMD_SHA1 (0x2 << 4) 10362306a36Sopenharmony_ci#define HASH_CMD_SHA224 (0x4 << 4) 10462306a36Sopenharmony_ci#define HASH_CMD_SHA256 (0x5 << 4) 10562306a36Sopenharmony_ci#define HASH_CMD_SHA512_SER (0x6 << 4) 10662306a36Sopenharmony_ci#define HASH_CMD_SHA_SWAP (0x2 << 2) 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#define HASH_SG_LAST_LIST BIT(31) 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci#define CRYPTO_FLAGS_BUSY BIT(1) 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci#define SHA_OP_UPDATE 1 11362306a36Sopenharmony_ci#define SHA_OP_FINAL 2 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci#define SHA_FLAGS_SHA1 BIT(0) 11662306a36Sopenharmony_ci#define SHA_FLAGS_SHA224 BIT(1) 11762306a36Sopenharmony_ci#define SHA_FLAGS_SHA256 BIT(2) 11862306a36Sopenharmony_ci#define SHA_FLAGS_SHA384 BIT(3) 11962306a36Sopenharmony_ci#define SHA_FLAGS_SHA512 BIT(4) 12062306a36Sopenharmony_ci#define SHA_FLAGS_SHA512_224 BIT(5) 12162306a36Sopenharmony_ci#define SHA_FLAGS_SHA512_256 BIT(6) 12262306a36Sopenharmony_ci#define SHA_FLAGS_HMAC BIT(8) 12362306a36Sopenharmony_ci#define SHA_FLAGS_FINUP BIT(9) 12462306a36Sopenharmony_ci#define SHA_FLAGS_MASK (0xff) 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci#define ASPEED_CRYPTO_SRC_DMA_BUF_LEN 0xa000 12762306a36Sopenharmony_ci#define ASPEED_CRYPTO_DST_DMA_BUF_LEN 0xa000 12862306a36Sopenharmony_ci#define ASPEED_CRYPTO_GCM_TAG_OFFSET 0x9ff0 12962306a36Sopenharmony_ci#define ASPEED_HASH_SRC_DMA_BUF_LEN 0xa000 13062306a36Sopenharmony_ci#define ASPEED_HASH_QUEUE_LENGTH 50 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#define HACE_CMD_IV_REQUIRE (HACE_CMD_CBC | HACE_CMD_CFB | \ 13362306a36Sopenharmony_ci HACE_CMD_OFB | HACE_CMD_CTR) 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistruct aspeed_hace_dev; 13662306a36Sopenharmony_cistruct scatterlist; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_citypedef int (*aspeed_hace_fn_t)(struct aspeed_hace_dev *); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistruct aspeed_sg_list { 14162306a36Sopenharmony_ci __le32 len; 14262306a36Sopenharmony_ci __le32 phy_addr; 14362306a36Sopenharmony_ci}; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistruct aspeed_engine_hash { 14662306a36Sopenharmony_ci struct tasklet_struct done_task; 14762306a36Sopenharmony_ci unsigned long flags; 14862306a36Sopenharmony_ci struct ahash_request *req; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci /* input buffer */ 15162306a36Sopenharmony_ci void *ahash_src_addr; 15262306a36Sopenharmony_ci dma_addr_t ahash_src_dma_addr; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci dma_addr_t src_dma; 15562306a36Sopenharmony_ci dma_addr_t digest_dma; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci size_t src_length; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci /* callback func */ 16062306a36Sopenharmony_ci aspeed_hace_fn_t resume; 16162306a36Sopenharmony_ci aspeed_hace_fn_t dma_prepare; 16262306a36Sopenharmony_ci}; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cistruct aspeed_sha_hmac_ctx { 16562306a36Sopenharmony_ci struct crypto_shash *shash; 16662306a36Sopenharmony_ci u8 ipad[SHA512_BLOCK_SIZE]; 16762306a36Sopenharmony_ci u8 opad[SHA512_BLOCK_SIZE]; 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistruct aspeed_sham_ctx { 17162306a36Sopenharmony_ci struct aspeed_hace_dev *hace_dev; 17262306a36Sopenharmony_ci unsigned long flags; /* hmac flag */ 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci struct aspeed_sha_hmac_ctx base[]; 17562306a36Sopenharmony_ci}; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistruct aspeed_sham_reqctx { 17862306a36Sopenharmony_ci unsigned long flags; /* final update flag should no use*/ 17962306a36Sopenharmony_ci unsigned long op; /* final or update */ 18062306a36Sopenharmony_ci u32 cmd; /* trigger cmd */ 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci /* walk state */ 18362306a36Sopenharmony_ci struct scatterlist *src_sg; 18462306a36Sopenharmony_ci int src_nents; 18562306a36Sopenharmony_ci unsigned int offset; /* offset in current sg */ 18662306a36Sopenharmony_ci unsigned int total; /* per update length */ 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci size_t digsize; 18962306a36Sopenharmony_ci size_t block_size; 19062306a36Sopenharmony_ci size_t ivsize; 19162306a36Sopenharmony_ci const __be32 *sha_iv; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci /* remain data buffer */ 19462306a36Sopenharmony_ci u8 buffer[SHA512_BLOCK_SIZE * 2]; 19562306a36Sopenharmony_ci dma_addr_t buffer_dma_addr; 19662306a36Sopenharmony_ci size_t bufcnt; /* buffer counter */ 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci /* output buffer */ 19962306a36Sopenharmony_ci u8 digest[SHA512_DIGEST_SIZE] __aligned(64); 20062306a36Sopenharmony_ci dma_addr_t digest_dma_addr; 20162306a36Sopenharmony_ci u64 digcnt[2]; 20262306a36Sopenharmony_ci}; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistruct aspeed_engine_crypto { 20562306a36Sopenharmony_ci struct tasklet_struct done_task; 20662306a36Sopenharmony_ci unsigned long flags; 20762306a36Sopenharmony_ci struct skcipher_request *req; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci /* context buffer */ 21062306a36Sopenharmony_ci void *cipher_ctx; 21162306a36Sopenharmony_ci dma_addr_t cipher_ctx_dma; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci /* input buffer, could be single/scatter-gather lists */ 21462306a36Sopenharmony_ci void *cipher_addr; 21562306a36Sopenharmony_ci dma_addr_t cipher_dma_addr; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* output buffer, only used in scatter-gather lists */ 21862306a36Sopenharmony_ci void *dst_sg_addr; 21962306a36Sopenharmony_ci dma_addr_t dst_sg_dma_addr; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci /* callback func */ 22262306a36Sopenharmony_ci aspeed_hace_fn_t resume; 22362306a36Sopenharmony_ci}; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistruct aspeed_cipher_ctx { 22662306a36Sopenharmony_ci struct aspeed_hace_dev *hace_dev; 22762306a36Sopenharmony_ci int key_len; 22862306a36Sopenharmony_ci u8 key[AES_MAX_KEYLENGTH]; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci /* callback func */ 23162306a36Sopenharmony_ci aspeed_hace_fn_t start; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci struct crypto_skcipher *fallback_tfm; 23462306a36Sopenharmony_ci}; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistruct aspeed_cipher_reqctx { 23762306a36Sopenharmony_ci int enc_cmd; 23862306a36Sopenharmony_ci int src_nents; 23962306a36Sopenharmony_ci int dst_nents; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci struct skcipher_request fallback_req; /* keep at the end */ 24262306a36Sopenharmony_ci}; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_cistruct aspeed_hace_dev { 24562306a36Sopenharmony_ci void __iomem *regs; 24662306a36Sopenharmony_ci struct device *dev; 24762306a36Sopenharmony_ci int irq; 24862306a36Sopenharmony_ci struct clk *clk; 24962306a36Sopenharmony_ci unsigned long version; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci struct crypto_engine *crypt_engine_hash; 25262306a36Sopenharmony_ci struct crypto_engine *crypt_engine_crypto; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci struct aspeed_engine_hash hash_engine; 25562306a36Sopenharmony_ci struct aspeed_engine_crypto crypto_engine; 25662306a36Sopenharmony_ci}; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistruct aspeed_hace_alg { 25962306a36Sopenharmony_ci struct aspeed_hace_dev *hace_dev; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci const char *alg_base; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci union { 26462306a36Sopenharmony_ci struct skcipher_engine_alg skcipher; 26562306a36Sopenharmony_ci struct ahash_engine_alg ahash; 26662306a36Sopenharmony_ci } alg; 26762306a36Sopenharmony_ci}; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_cienum aspeed_version { 27062306a36Sopenharmony_ci AST2500_VERSION = 5, 27162306a36Sopenharmony_ci AST2600_VERSION 27262306a36Sopenharmony_ci}; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci#define ast_hace_write(hace, val, offset) \ 27562306a36Sopenharmony_ci writel((val), (hace)->regs + (offset)) 27662306a36Sopenharmony_ci#define ast_hace_read(hace, offset) \ 27762306a36Sopenharmony_ci readl((hace)->regs + (offset)) 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_civoid aspeed_register_hace_hash_algs(struct aspeed_hace_dev *hace_dev); 28062306a36Sopenharmony_civoid aspeed_unregister_hace_hash_algs(struct aspeed_hace_dev *hace_dev); 28162306a36Sopenharmony_civoid aspeed_register_hace_crypto_algs(struct aspeed_hace_dev *hace_dev); 28262306a36Sopenharmony_civoid aspeed_unregister_hace_crypto_algs(struct aspeed_hace_dev *hace_dev); 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci#endif 285