crypto: Add support for crypto engine 5.0

Add new register definitions for QCE5.0 Hardware
Add new HAL (qce50.c) for interfacing with CE 5.0 hardware:
-- Implement the new interface to BAM (instead of data mover).
-- Add support for multiple Pipes.
-- Add support for use of HW key.

Change-Id: I69dc3993f607553d4752f9f9fb4fdfe1a09a6345
Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
This commit is contained in:
Mona Hossain 2012-05-07 08:52:06 -07:00 committed by Stephen Boyd
parent 03c98071ea
commit d4ad4eee69
13 changed files with 3841 additions and 192 deletions

View file

@ -600,6 +600,22 @@
qcom,memory-reservation-type = "EBI1";
qcom,memory-reservation-size = <0x100000>; /* 1M EBI1 buffer */
};
qcom,qcedev@fd440000 {
compatible = "qcom,qcedev";
reg = <0xfd440000 0x20000>,
<0xfd444000 0x8000>;
interrupts = <0 235 0>;
qcom,bam-pipes = <0>;
};
qcom,qcrypto@fd444000 {
compatible = "qcom,qcrypto";
reg = <0xfd440000 0x20000>,
<0xfd444000 0x8000>;
interrupts = <0 235 0>;
qcom,bam-pipes = <1>;
};
};
/include/ "msm-pm8x41-rpm-regulator.dtsi"

View file

@ -656,6 +656,10 @@ static struct of_dev_auxdata msm_8974_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("qcom,mdss_mdp", 0xFD900000, "mdp.0", NULL),
OF_DEV_AUXDATA("qcom,msm-tsens", 0xFC4A8000, \
"msm-tsens", NULL),
OF_DEV_AUXDATA("qcom,qcedev", 0xFD440000, \
"qcedev.0", NULL),
OF_DEV_AUXDATA("qcom,qcrypto", 0xFD440000, \
"qcrypto.0", NULL),
{}
};

View file

@ -4739,6 +4739,16 @@ static struct clk_lookup msm_clocks_8974[] = {
CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, ""),
CLK_LOOKUP("bus_clk", gcc_ce2_axi_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_ce2_clk.c, "qcedev.0"),
CLK_LOOKUP("iface_clk", gcc_ce2_ahb_clk.c, "qcedev.0"),
CLK_LOOKUP("bus_clk", gcc_ce2_axi_clk.c, "qcedev.0"),
CLK_LOOKUP("core_clk_src", ce2_clk_src.c, "qcedev.0"),
CLK_LOOKUP("core_clk", gcc_ce2_clk.c, "qcrypto.0"),
CLK_LOOKUP("iface_clk", gcc_ce2_ahb_clk.c, "qcrypto.0"),
CLK_LOOKUP("bus_clk", gcc_ce2_axi_clk.c, "qcrypto.0"),
CLK_LOOKUP("core_clk_src", ce2_clk_src.c, "qcrypto.0"),
CLK_LOOKUP("core_clk", gcc_gp1_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_gp2_clk.c, ""),
CLK_LOOKUP("core_clk", gcc_gp3_clk.c, ""),

View file

@ -288,6 +288,9 @@ config CRYPTO_DEV_S5P
config CRYPTO_DEV_QCE40
bool
config CRYPTO_DEV_QCE50
bool
config CRYPTO_DEV_QCRYPTO
tristate "Qualcomm Crypto accelerator"
select CRYPTO_DES
@ -303,20 +306,22 @@ config CRYPTO_DEV_QCRYPTO
config CRYPTO_DEV_QCE
tristate "Qualcomm Crypto Engine (QCE) module"
select CRYPTO_DEV_QCE40 if ARCH_MSM8960 || ARCH_MSM9615
select CRYPTO_DEV_QCE50 if ARCH_MSM8974
default n
help
This driver supports Qualcomm Crypto Engine in MSM7x30, MSM8660
MSM8x55, MSM8960 and MSM9615
To compile this driver as a module, choose M here: the
For MSM7x30 MSM8660 and MSM8x55 the module is called qce
For MSM8960 and MSM9615 the module is called qce40
For MSM8960, APQ8064 and MSM9615 the module is called qce40
For MSM8974 the module is called qce50
config CRYPTO_DEV_QCEDEV
tristate "QCEDEV Interface to CE module"
default n
help
This driver supports Qualcomm QCEDEV Crypto in MSM7x30, MSM8660,
MSM8960 and MSM9615.
MSM8960, MSM9615, APQ8064 and MSM8974.
This exposes the interface to the QCE hardware accelerator via IOCTLs
To compile this driver as a module, choose M here: the
module will be called qcedev.

View file

@ -1,8 +1,12 @@
obj-$(CONFIG_CRYPTO_DEV_QCEDEV) += qcedev.o
ifeq ($(CONFIG_CRYPTO_DEV_QCE40), y)
obj-$(CONFIG_CRYPTO_DEV_QCE) += qce40.o
ifeq ($(CONFIG_CRYPTO_DEV_QCE50), y)
obj-$(CONFIG_CRYPTO_DEV_QCE) += qce50.o
else
obj-$(CONFIG_CRYPTO_DEV_QCE) += qce.o
ifeq ($(CONFIG_CRYPTO_DEV_QCE40), y)
obj-$(CONFIG_CRYPTO_DEV_QCE) += qce40.o
else
obj-$(CONFIG_CRYPTO_DEV_QCE) += qce.o
endif
endif
obj-$(CONFIG_CRYPTO_DEV_QCRYPTO) += qcrypto.o
obj-$(CONFIG_CRYPTO_DEV_OTA_CRYPTO) += ota_crypto.o

View file

@ -1,6 +1,6 @@
/* Qualcomm Crypto Engine driver.
*
* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -2463,6 +2463,8 @@ int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
ce_support->aes_xts = false;
ce_support->aes_ccm = false;
ce_support->ota = pce_dev->ota;
ce_support->aligned_only = false;
ce_support->bam = false;
return 0;
}
EXPORT_SYMBOL(qce_hw_support);
@ -2703,7 +2705,5 @@ bad:
EXPORT_SYMBOL(qce_f9_req);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Crypto Engine driver");
MODULE_VERSION("1.15");

View file

@ -1,6 +1,6 @@
/* Qualcomm Crypto Engine driver API
*
* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -71,6 +71,7 @@ enum qce_hash_alg_enum {
QCE_HASH_SHA1_HMAC = 2,
QCE_HASH_SHA256_HMAC = 3,
QCE_HASH_AES_CMAC = 4,
QCE_AEAD_SHA1_HMAC = 5,
QCE_HASH_LAST
};
@ -110,6 +111,8 @@ struct ce_hw_support {
bool aes_xts;
bool aes_ccm;
bool ota;
bool aligned_only;
bool bam;
};
/* Sha operation parameters */

View file

@ -2599,11 +2599,11 @@ int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
ce_support->aes_xts = true;
ce_support->aes_ccm = true;
ce_support->ota = false;
ce_support->aligned_only = false;
ce_support->bam = false;
return 0;
}
EXPORT_SYMBOL(qce_hw_support);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Crypto Engine driver");
MODULE_VERSION("2.17");

2739
drivers/crypto/msm/qce50.c Normal file

File diff suppressed because it is too large Load diff

148
drivers/crypto/msm/qce50.h Normal file
View file

@ -0,0 +1,148 @@
/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _DRIVERS_CRYPTO_MSM_QCE50_H_
#define _DRIVERS_CRYPTO_MSM_QCE50_H_
#include <mach/sps.h>
/* MAX Data xfer block size between BAM and CE */
#define MAX_CE_BAM_BURST_SIZE 0x40
#define QCEBAM_BURST_SIZE MAX_CE_BAM_BURST_SIZE
#define MAX_BAM_DESCRIPTORS (0x40 - 1)
#define GET_VIRT_ADDR(x) \
((uint32_t)pce_dev->coh_vmem + \
((uint32_t)x - pce_dev->coh_pmem))
#define GET_PHYS_ADDR(x) \
(pce_dev->coh_pmem + (x - (uint32_t)pce_dev->coh_vmem))
#define CRYPTO_REG_SIZE 4
#define NUM_OF_CRYPTO_AUTH_IV_REG 16
#define NUM_OF_CRYPTO_CNTR_IV_REG 4
#define NUM_OF_CRYPTO_AUTH_BYTE_COUNT_REG 4
#define CRYPTO_TOTAL_REGISTERS_DUMPED 26
#define CRYPTO_RESULT_DUMP_SIZE \
ALIGN((CRYPTO_TOTAL_REGISTERS_DUMPED * CRYPTO_REG_SIZE), \
QCEBAM_BURST_SIZE)
/* QCE max number of descriptor in a descriptor list */
#define QCE_MAX_NUM_DESC 128
#define SPS_MAX_PKT_SIZE (64 * 1024 - 1)
/* State of consumer/producer Pipe */
enum qce_pipe_st_enum {
QCE_PIPE_STATE_IDLE = 0,
QCE_PIPE_STATE_IN_PROG = 1,
QCE_PIPE_STATE_COMP = 2,
QCE_PIPE_STATE_LAST
};
struct qce_sps_ep_conn_data {
struct sps_pipe *pipe;
struct sps_connect connect;
struct sps_register_event event;
};
/* CE Result DUMP format*/
struct ce_result_dump_format {
uint32_t auth_iv[NUM_OF_CRYPTO_AUTH_IV_REG];
uint32_t auth_byte_count[NUM_OF_CRYPTO_AUTH_BYTE_COUNT_REG];
uint32_t encr_cntr_iv[NUM_OF_CRYPTO_CNTR_IV_REG];
uint32_t status;
uint32_t status2;
};
struct qce_cmdlist_info {
uint32_t cmdlist;
struct sps_command_element *crypto_cfg;
struct sps_command_element *encr_seg_cfg;
struct sps_command_element *encr_seg_size;
struct sps_command_element *encr_seg_start;
struct sps_command_element *encr_key;
struct sps_command_element *encr_xts_key;
struct sps_command_element *encr_cntr_iv;
struct sps_command_element *encr_ccm_cntr_iv;
struct sps_command_element *encr_mask;
struct sps_command_element *encr_xts_du_size;
struct sps_command_element *auth_seg_cfg;
struct sps_command_element *auth_seg_size;
struct sps_command_element *auth_seg_start;
struct sps_command_element *auth_key;
struct sps_command_element *auth_iv;
struct sps_command_element *auth_nonce_info;
struct sps_command_element *auth_bytecount;
struct sps_command_element *seg_size;
struct sps_command_element *go_proc;
uint32_t size;
};
struct qce_cmdlistptr_ops {
struct qce_cmdlist_info cipher_aes_128_cbc_ctr;
struct qce_cmdlist_info cipher_aes_256_cbc_ctr;
struct qce_cmdlist_info cipher_aes_128_ecb;
struct qce_cmdlist_info cipher_aes_256_ecb;
struct qce_cmdlist_info cipher_aes_128_xts;
struct qce_cmdlist_info cipher_aes_256_xts;
struct qce_cmdlist_info cipher_des_cbc;
struct qce_cmdlist_info cipher_des_ecb;
struct qce_cmdlist_info cipher_3des_cbc;
struct qce_cmdlist_info cipher_3des_ecb;
struct qce_cmdlist_info auth_sha1;
struct qce_cmdlist_info auth_sha256;
struct qce_cmdlist_info auth_sha1_hmac;
struct qce_cmdlist_info auth_sha256_hmac;
struct qce_cmdlist_info auth_aes_128_cmac;
struct qce_cmdlist_info auth_aes_256_cmac;
struct qce_cmdlist_info aead_sha1_hmac;
struct qce_cmdlist_info aead_aes_128_ccm;
struct qce_cmdlist_info aead_aes_256_ccm;
struct qce_cmdlist_info unlock_all_pipes;
};
/* DM data structure with buffers, commandlists & commmand pointer lists */
struct ce_sps_data {
uint32_t bam_irq;
uint32_t bam_mem;
void __iomem *bam_iobase;
struct qce_sps_ep_conn_data producer;
struct qce_sps_ep_conn_data consumer;
struct sps_event_notify notify;
struct scatterlist *src;
struct scatterlist *dst;
unsigned int pipe_pair_index;
unsigned int src_pipe_index;
unsigned int dest_pipe_index;
uint32_t bam_handle;
enum qce_pipe_st_enum consumer_state; /* Consumer pipe state */
enum qce_pipe_st_enum producer_state; /* Producer pipe state */
int consumer_status; /* consumer pipe status */
int producer_status; /* producer pipe status */
struct sps_transfer in_transfer;
struct sps_transfer out_transfer;
int ce_burst_size;
struct qce_cmdlistptr_ops cmdlistptr;
uint32_t result_dump;
uint32_t ignore_buffer;
struct ce_result_dump_format *result;
uint32_t minor_version;
};
#endif /* _DRIVERS_CRYPTO_MSM_QCE50_H */

View file

@ -2016,21 +2016,8 @@ static int qcedev_probe(struct platform_device *pdev)
struct qcedev_control *podev;
struct msm_ce_hw_support *platform_support;
if (pdev->id >= MAX_QCE_DEVICE) {
pr_err("%s: device id %d exceeds allowed %d\n",
__func__, pdev->id, MAX_QCE_DEVICE);
return -ENOENT;
}
podev = &qce_dev[pdev->id];
podev = &qce_dev[0];
platform_support = (struct msm_ce_hw_support *)pdev->dev.platform_data;
podev->platform_support.ce_shared = platform_support->ce_shared;
podev->platform_support.shared_ce_resource =
platform_support->shared_ce_resource;
podev->platform_support.hw_key_support =
platform_support->hw_key_support;
podev->platform_support.bus_scale_table =
platform_support->bus_scale_table;
podev->ce_lock_count = 0;
podev->high_bw_req_count = 0;
INIT_LIST_HEAD(&podev->ready_commands);
@ -2050,7 +2037,6 @@ static int qcedev_probe(struct platform_device *pdev)
podev->qce = handle;
podev->pdev = pdev;
platform_set_drvdata(pdev, podev);
qce_hw_support(podev->qce, &podev->ce_support);
if (podev->platform_support.bus_scale_table != NULL) {
podev->bus_scale_handle =
@ -2065,7 +2051,25 @@ static int qcedev_probe(struct platform_device *pdev)
}
}
rc = misc_register(&podev->miscdevice);
qce_hw_support(podev->qce, &podev->ce_support);
if (podev->ce_support.bam) {
podev->platform_support.ce_shared = 0;
podev->platform_support.shared_ce_resource = 0;
podev->platform_support.hw_key_support = 0;
podev->platform_support.bus_scale_table = NULL;
podev->platform_support.sha_hmac = 1;
} else {
platform_support =
(struct msm_ce_hw_support *)pdev->dev.platform_data;
podev->platform_support.ce_shared = platform_support->ce_shared;
podev->platform_support.shared_ce_resource =
platform_support->shared_ce_resource;
podev->platform_support.hw_key_support =
platform_support->hw_key_support;
podev->platform_support.bus_scale_table =
platform_support->bus_scale_table;
podev->platform_support.sha_hmac = platform_support->sha_hmac;
}
if (rc >= 0)
return 0;
else
@ -2230,9 +2234,7 @@ static void qcedev_exit(void)
}
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Qualcomm DEV Crypto driver");
MODULE_VERSION("1.27");
module_init(qcedev_init);
module_exit(qcedev_exit);

View file

@ -228,6 +228,13 @@ struct qcrypto_cipher_req_ctx {
enum qce_cipher_alg_enum alg;
enum qce_cipher_dir_enum dir;
enum qce_cipher_mode_enum mode;
struct scatterlist *orig_src; /* Original src sg ptr */
struct scatterlist *orig_dst; /* Original dst sg ptr */
struct scatterlist dsg; /* Dest Data sg */
struct scatterlist ssg; /* Source Data sg */
unsigned char *data; /* Incoming data pointer*/
};
#define SHA_MAX_BLOCK_SIZE SHA256_BLOCK_SIZE
@ -275,6 +282,11 @@ struct qcrypto_sha_req_ctx {
};
struct scatterlist *src;
uint32_t nbytes;
struct scatterlist *orig_src; /* Original src sg ptr */
struct scatterlist dsg; /* Data sg */
unsigned char *data; /* Incoming data pointer*/
unsigned char *data2; /* Updated data pointer*/
};
static void _byte_stream_to_words(uint32_t *iv, unsigned char *b,
@ -497,9 +509,6 @@ static int _qcrypto_ahash_hmac_cra_init(struct crypto_tfm *tfm)
&sha_ctx->ahash_req_complete);
crypto_ahash_clear_flags(ahash, ~0);
if (sha_ctx->cp->platform_support.bus_scale_table != NULL)
qcrypto_ce_high_bw_req(sha_ctx->cp, true);
return 0;
};
@ -785,7 +794,6 @@ static void _qce_ahash_complete(void *cookie, unsigned char *digest,
dev_info(&cp->pdev->dev, "_qce_ahash_complete: %p ret %d\n",
areq, ret);
#endif
if (digest) {
memcpy(sha_ctx->digest, digest, diglen);
memcpy(areq->result, digest, diglen);
@ -819,6 +827,10 @@ static void _qce_ahash_complete(void *cookie, unsigned char *digest,
cp->res = 0;
pstat->sha_op_success++;
}
if (cp->ce_support.aligned_only) {
areq->src = rctx->orig_src;
kfree(rctx->data);
}
if (cp->platform_support.ce_shared)
schedule_work(&cp->unlock_ce_ws);
@ -850,6 +862,24 @@ static void _qce_ablk_cipher_complete(void *cookie, unsigned char *icb,
cp->res = 0;
pstat->ablk_cipher_op_success++;
}
if (cp->ce_support.aligned_only) {
struct qcrypto_cipher_req_ctx *rctx;
struct scatterlist *sg;
uint32_t bytes = 0;
rctx = ablkcipher_request_ctx(areq);
areq->src = rctx->orig_src;
areq->dst = rctx->orig_dst;
for (sg = areq->dst; bytes != areq->nbytes; sg++) {
memcpy(sg_virt(sg), ((char *)rctx->data + bytes),
sg->length);
bytes += sg->length;
}
kfree(rctx->data);
}
if (cp->platform_support.ce_shared)
schedule_work(&cp->unlock_ce_ws);
tasklet_schedule(&cp->done_tasklet);
@ -871,6 +901,30 @@ static void _qce_aead_complete(void *cookie, unsigned char *icv,
rctx = aead_request_ctx(areq);
if (rctx->mode == QCE_MODE_CCM) {
if (cp->ce_support.aligned_only) {
struct qcrypto_cipher_req_ctx *rctx;
struct scatterlist *sg;
uint32_t bytes = 0;
uint32_t nbytes = 0;
rctx = aead_request_ctx(areq);
areq->src = rctx->orig_src;
areq->dst = rctx->orig_dst;
if (rctx->dir == QCE_ENCRYPT)
nbytes = areq->cryptlen +
crypto_aead_authsize(aead);
else
nbytes = areq->cryptlen -
crypto_aead_authsize(aead);
for (sg = areq->dst; bytes != nbytes; sg++) {
memcpy(sg_virt(sg),
((char *)rctx->data + rctx->assoclen + bytes),
sg->length);
bytes += sg->length;
}
kfree(rctx->data);
}
kzfree(rctx->assoc);
areq->assoc = rctx->assoc_sg;
areq->assoclen = rctx->assoclen;
@ -997,17 +1051,222 @@ static int qcrypto_aead_ccm_format_adata(struct qce_req *qreq, uint32_t alen,
return 0;
}
static int _qcrypto_process_ablkcipher(struct crypto_priv *cp,
struct crypto_async_request *async_req)
{
struct qce_req qreq;
int ret;
struct qcrypto_cipher_req_ctx *rctx;
struct qcrypto_cipher_ctx *cipher_ctx;
struct ablkcipher_request *req;
struct crypto_ablkcipher *tfm;
req = container_of(async_req, struct ablkcipher_request, base);
cipher_ctx = crypto_tfm_ctx(async_req->tfm);
rctx = ablkcipher_request_ctx(req);
tfm = crypto_ablkcipher_reqtfm(req);
if (cp->ce_support.aligned_only) {
uint32_t bytes = 0;
struct scatterlist *sg = req->src;
rctx->orig_src = req->src;
rctx->orig_dst = req->dst;
rctx->data = kzalloc((req->nbytes + 64), GFP_KERNEL);
for (sg = req->src; bytes != req->nbytes; sg++) {
memcpy(((char *)rctx->data + bytes),
sg_virt(sg), sg->length);
bytes += sg->length;
}
sg_set_buf(&rctx->dsg, rctx->data, req->nbytes);
sg_mark_end(&rctx->dsg);
rctx->iv = req->info;
req->src = &rctx->dsg;
req->dst = &rctx->dsg;
}
qreq.op = QCE_REQ_ABLK_CIPHER;
qreq.qce_cb = _qce_ablk_cipher_complete;
qreq.areq = req;
qreq.alg = rctx->alg;
qreq.dir = rctx->dir;
qreq.mode = rctx->mode;
qreq.enckey = cipher_ctx->enc_key;
qreq.encklen = cipher_ctx->enc_key_len;
qreq.iv = req->info;
qreq.ivsize = crypto_ablkcipher_ivsize(tfm);
qreq.cryptlen = req->nbytes;
qreq.use_pmem = 0;
if ((cipher_ctx->enc_key_len == 0) &&
(cp->platform_support.hw_key_support == 0))
ret = -EINVAL;
else
ret = qce_ablk_cipher_req(cp->qce, &qreq);
return ret;
}
static int _qcrypto_process_ahash(struct crypto_priv *cp,
struct crypto_async_request *async_req)
{
struct ahash_request *req;
struct qce_sha_req sreq;
struct qcrypto_sha_ctx *sha_ctx;
int ret = 0;
req = container_of(async_req,
struct ahash_request, base);
sha_ctx = crypto_tfm_ctx(async_req->tfm);
sreq.qce_cb = _qce_ahash_complete;
sreq.digest = &sha_ctx->digest[0];
sreq.src = req->src;
sreq.auth_data[0] = sha_ctx->byte_count[0];
sreq.auth_data[1] = sha_ctx->byte_count[1];
sreq.auth_data[2] = sha_ctx->byte_count[2];
sreq.auth_data[3] = sha_ctx->byte_count[3];
sreq.first_blk = sha_ctx->first_blk;
sreq.last_blk = sha_ctx->last_blk;
sreq.size = req->nbytes;
sreq.areq = req;
switch (sha_ctx->alg) {
case QCE_HASH_SHA1:
sreq.alg = QCE_HASH_SHA1;
sreq.authkey = NULL;
break;
case QCE_HASH_SHA256:
sreq.alg = QCE_HASH_SHA256;
sreq.authkey = NULL;
break;
case QCE_HASH_SHA1_HMAC:
sreq.alg = QCE_HASH_SHA1_HMAC;
sreq.authkey = &sha_ctx->authkey[0];
sreq.authklen = SHA_HMAC_KEY_SIZE;
break;
case QCE_HASH_SHA256_HMAC:
sreq.alg = QCE_HASH_SHA256_HMAC;
sreq.authkey = &sha_ctx->authkey[0];
sreq.authklen = SHA_HMAC_KEY_SIZE;
break;
default:
break;
};
ret = qce_process_sha_req(cp->qce, &sreq);
return ret;
}
static int _qcrypto_process_aead(struct crypto_priv *cp,
struct crypto_async_request *async_req)
{
struct qce_req qreq;
int ret = 0;
struct qcrypto_cipher_req_ctx *rctx;
struct qcrypto_cipher_ctx *cipher_ctx;
struct aead_request *req = container_of(async_req,
struct aead_request, base);
struct crypto_aead *aead = crypto_aead_reqtfm(req);
rctx = aead_request_ctx(req);
cipher_ctx = crypto_tfm_ctx(async_req->tfm);
qreq.op = QCE_REQ_AEAD;
qreq.qce_cb = _qce_aead_complete;
qreq.areq = req;
qreq.alg = rctx->alg;
qreq.dir = rctx->dir;
qreq.mode = rctx->mode;
qreq.iv = rctx->iv;
qreq.enckey = cipher_ctx->enc_key;
qreq.encklen = cipher_ctx->enc_key_len;
qreq.authkey = cipher_ctx->auth_key;
qreq.authklen = cipher_ctx->auth_key_len;
qreq.authsize = crypto_aead_authsize(aead);
qreq.ivsize = crypto_aead_ivsize(aead);
if (qreq.mode == QCE_MODE_CCM) {
if (qreq.dir == QCE_ENCRYPT)
qreq.cryptlen = req->cryptlen;
else
qreq.cryptlen = req->cryptlen -
qreq.authsize;
/* Get NONCE */
ret = qccrypto_set_aead_ccm_nonce(&qreq);
if (ret)
return ret;
/* Format Associated data */
ret = qcrypto_aead_ccm_format_adata(&qreq,
req->assoclen,
req->assoc);
if (ret)
return ret;
if (cp->ce_support.aligned_only) {
uint32_t bytes = 0;
struct scatterlist *sg = req->src;
rctx->orig_src = req->src;
rctx->orig_dst = req->dst;
rctx->data = kzalloc((req->cryptlen + qreq.assoclen +
qreq.authsize + 64*2), GFP_KERNEL);
memcpy((char *)rctx->data, qreq.assoc, qreq.assoclen);
for (sg = req->src; bytes != req->cryptlen; sg++) {
memcpy((rctx->data + bytes + qreq.assoclen),
sg_virt(sg), sg->length);
bytes += sg->length;
}
sg_set_buf(&rctx->ssg, rctx->data, req->cryptlen +
qreq.assoclen);
sg_mark_end(&rctx->ssg);
if (qreq.dir == QCE_ENCRYPT)
sg_set_buf(&rctx->dsg, rctx->data,
qreq.assoclen + qreq.cryptlen +
ALIGN(qreq.authsize, 64));
else
sg_set_buf(&rctx->dsg, rctx->data,
qreq.assoclen + req->cryptlen +
qreq.authsize);
sg_mark_end(&rctx->dsg);
req->src = &rctx->ssg;
req->dst = &rctx->dsg;
}
/*
* Save the original associated data
* length and sg
*/
rctx->assoc_sg = req->assoc;
rctx->assoclen = req->assoclen;
rctx->assoc = qreq.assoc;
/*
* update req with new formatted associated
* data info
*/
req->assoc = &rctx->asg;
req->assoclen = qreq.assoclen;
sg_set_buf(req->assoc, qreq.assoc,
req->assoclen);
sg_mark_end(req->assoc);
}
ret = qce_aead_req(cp->qce, &qreq);
return ret;
}
static void _start_qcrypto_process(struct crypto_priv *cp)
{
struct crypto_async_request *async_req = NULL;
struct crypto_async_request *backlog = NULL;
unsigned long flags;
u32 type;
struct qce_req qreq;
int ret;
struct qcrypto_cipher_req_ctx *rctx;
struct qcrypto_cipher_ctx *cipher_ctx;
struct qcrypto_sha_ctx *sha_ctx;
struct crypto_stat *pstat;
pstat = &_qcrypto_stat[cp->pdev->id];
@ -1026,139 +1285,21 @@ again:
backlog->complete(backlog, -EINPROGRESS);
type = crypto_tfm_alg_type(async_req->tfm);
if (type == CRYPTO_ALG_TYPE_ABLKCIPHER) {
struct ablkcipher_request *req;
struct crypto_ablkcipher *tfm;
req = container_of(async_req, struct ablkcipher_request, base);
cipher_ctx = crypto_tfm_ctx(async_req->tfm);
rctx = ablkcipher_request_ctx(req);
tfm = crypto_ablkcipher_reqtfm(req);
qreq.op = QCE_REQ_ABLK_CIPHER;
qreq.qce_cb = _qce_ablk_cipher_complete;
qreq.areq = req;
qreq.alg = rctx->alg;
qreq.dir = rctx->dir;
qreq.mode = rctx->mode;
qreq.enckey = cipher_ctx->enc_key;
qreq.encklen = cipher_ctx->enc_key_len;
qreq.iv = req->info;
qreq.ivsize = crypto_ablkcipher_ivsize(tfm);
qreq.cryptlen = req->nbytes;
qreq.use_pmem = 0;
if ((cipher_ctx->enc_key_len == 0) &&
(cp->platform_support.hw_key_support == 0))
ret = -EINVAL;
else
ret = qce_ablk_cipher_req(cp->qce, &qreq);
} else {
if (type == CRYPTO_ALG_TYPE_AHASH) {
struct ahash_request *req;
struct qce_sha_req sreq;
req = container_of(async_req,
struct ahash_request, base);
sha_ctx = crypto_tfm_ctx(async_req->tfm);
sreq.qce_cb = _qce_ahash_complete;
sreq.digest = &sha_ctx->digest[0];
sreq.src = req->src;
sreq.auth_data[0] = sha_ctx->byte_count[0];
sreq.auth_data[1] = sha_ctx->byte_count[1];
sreq.auth_data[2] = sha_ctx->byte_count[2];
sreq.auth_data[3] = sha_ctx->byte_count[3];
sreq.first_blk = sha_ctx->first_blk;
sreq.last_blk = sha_ctx->last_blk;
sreq.size = req->nbytes;
sreq.areq = req;
switch (sha_ctx->alg) {
case QCE_HASH_SHA1:
sreq.alg = QCE_HASH_SHA1;
sreq.authkey = NULL;
break;
case QCE_HASH_SHA256:
sreq.alg = QCE_HASH_SHA256;
sreq.authkey = NULL;
break;
case QCE_HASH_SHA1_HMAC:
sreq.alg = QCE_HASH_SHA1_HMAC;
sreq.authkey = &sha_ctx->authkey[0];
break;
case QCE_HASH_SHA256_HMAC:
sreq.alg = QCE_HASH_SHA256_HMAC;
sreq.authkey = &sha_ctx->authkey[0];
break;
default:
break;
};
ret = qce_process_sha_req(cp->qce, &sreq);
} else {
struct aead_request *req = container_of(async_req,
struct aead_request, base);
struct crypto_aead *aead = crypto_aead_reqtfm(req);
rctx = aead_request_ctx(req);
cipher_ctx = crypto_tfm_ctx(async_req->tfm);
qreq.op = QCE_REQ_AEAD;
qreq.qce_cb = _qce_aead_complete;
qreq.areq = req;
qreq.alg = rctx->alg;
qreq.dir = rctx->dir;
qreq.mode = rctx->mode;
qreq.iv = rctx->iv;
qreq.enckey = cipher_ctx->enc_key;
qreq.encklen = cipher_ctx->enc_key_len;
qreq.authkey = cipher_ctx->auth_key;
qreq.authklen = cipher_ctx->auth_key_len;
qreq.authsize = crypto_aead_authsize(aead);
qreq.ivsize = crypto_aead_ivsize(aead);
if (qreq.mode == QCE_MODE_CCM) {
if (qreq.dir == QCE_ENCRYPT)
qreq.cryptlen = req->cryptlen;
else
qreq.cryptlen = req->cryptlen -
qreq.authsize;
/* Get NONCE */
ret = qccrypto_set_aead_ccm_nonce(&qreq);
if (ret)
goto done;
/* Format Associated data */
ret = qcrypto_aead_ccm_format_adata(&qreq,
req->assoclen,
req->assoc);
if (ret)
goto done;
/*
* Save the original associated data
* length and sg
*/
rctx->assoc_sg = req->assoc;
rctx->assoclen = req->assoclen;
rctx->assoc = qreq.assoc;
/*
* update req with new formatted associated
* data info
*/
req->assoc = &rctx->asg;
req->assoclen = qreq.assoclen;
sg_set_buf(req->assoc, qreq.assoc,
req->assoclen);
sg_mark_end(req->assoc);
}
ret = qce_aead_req(cp->qce, &qreq);
}
switch (type) {
case CRYPTO_ALG_TYPE_ABLKCIPHER:
ret = _qcrypto_process_ablkcipher(cp, async_req);
break;
case CRYPTO_ALG_TYPE_AHASH:
ret = _qcrypto_process_ahash(cp, async_req);
break;
case CRYPTO_ALG_TYPE_AEAD:
ret = _qcrypto_process_aead(cp, async_req);
break;
default:
ret = -EINVAL;
};
done:
if (ret) {
if (ret) {
spin_lock_irqsave(&cp->lock, flags);
cp->req = NULL;
spin_unlock_irqrestore(&cp->lock, flags);
@ -2118,6 +2259,26 @@ static int _sha256_import(struct ahash_request *req, const void *in)
return 0;
}
static void _copy_source(struct ahash_request *req)
{
struct qcrypto_sha_req_ctx *srctx = NULL;
uint32_t bytes = 0;
struct scatterlist *sg = req->src;
srctx = ahash_request_ctx(req);
srctx->orig_src = req->src;
srctx->data = kzalloc((req->nbytes + 64), GFP_KERNEL);
for (sg = req->src; bytes != req->nbytes;
sg++) {
memcpy(((char *)srctx->data + bytes),
sg_virt(sg), sg->length);
bytes += sg->length;
}
sg_set_buf(&srctx->dsg, srctx->data,
req->nbytes);
sg_mark_end(&srctx->dsg);
req->src = &srctx->dsg;
}
static int _sha_update(struct ahash_request *req, uint32_t sha_block_size)
{
@ -2198,23 +2359,55 @@ static int _sha_update(struct ahash_request *req, uint32_t sha_block_size)
}
if (sha_ctx->trailing_buf_len) {
num_sg = end_src + 2;
sha_ctx->sg = kzalloc(num_sg * (sizeof(struct scatterlist)),
if (cp->ce_support.aligned_only) {
sha_ctx->sg = kzalloc(sizeof(struct scatterlist),
GFP_KERNEL);
if (sha_ctx->sg == NULL) {
pr_err("qcrypto Can't Allocate mem: sha_ctx->sg, error %ld\n",
PTR_ERR(sha_ctx->sg));
return -ENOMEM;
}
sg_set_buf(&sha_ctx->sg[0], sha_ctx->tmp_tbuf,
if (sha_ctx->sg == NULL) {
pr_err("MemAlloc fail sha_ctx->sg, error %ld\n",
PTR_ERR(sha_ctx->sg));
return -ENOMEM;
}
rctx->data2 = kzalloc((req->nbytes + 64), GFP_KERNEL);
if (rctx->data2 == NULL) {
pr_err("Mem Alloc fail srctx->data2, err %ld\n",
PTR_ERR(rctx->data2));
kfree(sha_ctx->sg);
return -ENOMEM;
}
memcpy(rctx->data2, sha_ctx->tmp_tbuf,
sha_ctx->trailing_buf_len);
for (i = 1; i < num_sg; i++)
sg_set_buf(&sha_ctx->sg[i], sg_virt(&req->src[i-1]),
req->src[i-1].length);
memcpy((rctx->data2 + sha_ctx->trailing_buf_len),
rctx->data, req->src[i-1].length);
kfree(rctx->data);
rctx->data = rctx->data2;
sg_set_buf(&sha_ctx->sg[0], rctx->data,
(sha_ctx->trailing_buf_len +
req->src[i-1].length));
req->src = sha_ctx->sg;
sg_mark_end(&sha_ctx->sg[0]);
req->src = sha_ctx->sg;
sg_mark_end(&sha_ctx->sg[num_sg - 1]);
} else {
num_sg = end_src + 2;
sha_ctx->sg = kzalloc(num_sg *
(sizeof(struct scatterlist)), GFP_KERNEL);
if (sha_ctx->sg == NULL) {
pr_err("MEMalloc fail sha_ctx->sg, error %ld\n",
PTR_ERR(sha_ctx->sg));
return -ENOMEM;
}
sg_set_buf(&sha_ctx->sg[0], sha_ctx->tmp_tbuf,
sha_ctx->trailing_buf_len);
for (i = 1; i < num_sg; i++)
sg_set_buf(&sha_ctx->sg[i],
sg_virt(&req->src[i-1]),
req->src[i-1].length);
req->src = sha_ctx->sg;
sg_mark_end(&sha_ctx->sg[num_sg - 1]);
}
} else
sg_mark_end(&req->src[end_src]);
@ -2232,6 +2425,11 @@ static int _sha1_update(struct ahash_request *req)
{
struct qcrypto_sha_req_ctx *rctx = ahash_request_ctx(req);
struct sha1_state *sha_state_ctx = &rctx->sha1_state_ctx;
struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(req->base.tfm);
struct crypto_priv *cp = sha_ctx->cp;
if (cp->ce_support.aligned_only)
_copy_source(req);
sha_state_ctx->count += req->nbytes;
return _sha_update(req, SHA1_BLOCK_SIZE);
@ -2241,6 +2439,11 @@ static int _sha256_update(struct ahash_request *req)
{
struct qcrypto_sha_req_ctx *rctx = ahash_request_ctx(req);
struct sha256_state *sha_state_ctx = &rctx->sha256_state_ctx;
struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(req->base.tfm);
struct crypto_priv *cp = sha_ctx->cp;
if (cp->ce_support.aligned_only)
_copy_source(req);
sha_state_ctx->count += req->nbytes;
return _sha_update(req, SHA256_BLOCK_SIZE);
@ -2253,6 +2456,9 @@ static int _sha_final(struct ahash_request *req, uint32_t sha_block_size)
struct qcrypto_sha_req_ctx *rctx = ahash_request_ctx(req);
int ret = 0;
if (cp->ce_support.aligned_only)
_copy_source(req);
sha_ctx->last_blk = 1;
/* save the original req structure fields*/
@ -2288,10 +2494,13 @@ static int _sha_digest(struct ahash_request *req)
struct crypto_priv *cp = sha_ctx->cp;
int ret = 0;
if (cp->ce_support.aligned_only)
_copy_source(req);
/* save the original req structure fields*/
rctx->src = req->src;
rctx->nbytes = req->nbytes;
sha_ctx->first_blk = 1;
sha_ctx->last_blk = 1;
ret = _qcrypto_queue_req(cp, &req->base);
@ -2326,7 +2535,7 @@ static int _sha_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
struct qcrypto_sha_ctx *sha_ctx = crypto_tfm_ctx(&tfm->base);
int ret = 0;
sha_ctx->in_buf = kzalloc(len, GFP_KERNEL);
sha_ctx->in_buf = kzalloc(len + 64, GFP_KERNEL);
if (sha_ctx->in_buf == NULL) {
pr_err("qcrypto Can't Allocate mem: sha_ctx->in_buf, error %ld\n",
PTR_ERR(sha_ctx->in_buf));
@ -3079,17 +3288,27 @@ static int _qcrypto_probe(struct platform_device *pdev)
cp->qce = handle;
cp->pdev = pdev;
qce_hw_support(cp->qce, &cp->ce_support);
platform_support = (struct msm_ce_hw_support *)pdev->dev.platform_data;
cp->platform_support.ce_shared = platform_support->ce_shared;
cp->platform_support.shared_ce_resource =
if (cp->ce_support.bam) {
cp->platform_support.ce_shared = 0;
cp->platform_support.shared_ce_resource = 0;
cp->platform_support.hw_key_support = 0;
cp->platform_support.bus_scale_table = NULL;
cp->platform_support.sha_hmac = 1;
} else {
platform_support =
(struct msm_ce_hw_support *)pdev->dev.platform_data;
cp->platform_support.ce_shared = platform_support->ce_shared;
cp->platform_support.shared_ce_resource =
platform_support->shared_ce_resource;
cp->platform_support.hw_key_support =
cp->platform_support.hw_key_support =
platform_support->hw_key_support;
cp->platform_support.bus_scale_table =
cp->platform_support.bus_scale_table =
platform_support->bus_scale_table;
cp->platform_support.sha_hmac = platform_support->sha_hmac;
}
cp->high_bw_req_count = 0;
cp->ce_lock_count = 0;
cp->platform_support.sha_hmac = platform_support->sha_hmac;
if (cp->platform_support.ce_shared)
INIT_WORK(&cp->unlock_ce_ws, qcrypto_unlock_ce);
@ -3370,6 +3589,4 @@ module_init(_qcrypto_init);
module_exit(_qcrypto_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Qualcomm Crypto driver");
MODULE_VERSION("1.22");

View file

@ -0,0 +1,501 @@
/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _DRIVERS_CRYPTO_MSM_QCRYPTOHW_50_H_
#define _DRIVERS_CRYPTO_MSM_QCRYPTOHW_50_H_
#define QCE_AUTH_REG_BYTE_COUNT 4
#define CRYPTO_VERSION_REG 0x1A000
#define CRYPTO_DATA_IN0_REG 0x1A010
#define CRYPTO_DATA_IN1_REG 0x1A014
#define CRYPTO_DATA_IN2_REG 0x1A018
#define CRYPTO_DATA_IN3_REG 0x1A01C
#define CRYPTO_DATA_OUT0_REG 0x1A020
#define CRYPTO_DATA_OUT1_REG 0x1A024
#define CRYPTO_DATA_OUT2_REG 0x1A028
#define CRYPTO_DATA_OUT3_REG 0x1A02C
#define CRYPTO_STATUS_REG 0x1A100
#define CRYPTO_STATUS2_REG 0x1A100
#define CRYPTO_ENGINES_AVAIL 0x1A108
#define CRYPTO_FIFO_SIZES_REG 0x1A10C
#define CRYPTO_SEG_SIZE_REG 0x1A110
#define CRYPTO_GOPROC_REG 0x1A120
#define CRYPTO_GOPROC_QC_KEY_REG 0x1B000
#define CRYPTO_GOPROC_OEM_KEY_REG 0x1C000
#define CRYPTO_ENCR_SEG_CFG_REG 0x1A200
#define CRYPTO_ENCR_SEG_SIZE_REG 0x1A204
#define CRYPTO_ENCR_SEG_START_REG 0x1A208
#define CRYPTO_ENCR_KEY0_REG 0x1D000
#define CRYPTO_ENCR_KEY1_REG 0x1D004
#define CRYPTO_ENCR_KEY2_REG 0x1D008
#define CRYPTO_ENCR_KEY3_REG 0x1D00C
#define CRYPTO_ENCR_KEY4_REG 0x1D010
#define CRYPTO_ENCR_KEY5_REG 0x1D014
#define CRYPTO_ENCR_KEY6_REG 0x1D018
#define CRYPTO_ENCR_KEY7_REG 0x1D01C
#define CRYPTO_ENCR_XTS_KEY0_REG 0x1D020
#define CRYPTO_ENCR_XTS_KEY1_REG 0x1D024
#define CRYPTO_ENCR_XTS_KEY2_REG 0x1D028
#define CRYPTO_ENCR_XTS_KEY3_REG 0x1D02C
#define CRYPTO_ENCR_XTS_KEY4_REG 0x1D030
#define CRYPTO_ENCR_XTS_KEY5_REG 0x1D034
#define CRYPTO_ENCR_XTS_KEY6_REG 0x1D038
#define CRYPTO_ENCR_XTS_KEY7_REG 0x1D03C
#define CRYPTO_ENCR_PIP0_KEY0_REG 0x1E000
#define CRYPTO_ENCR_PIP0_KEY1_REG 0x1E004
#define CRYPTO_ENCR_PIP0_KEY2_REG 0x1E008
#define CRYPTO_ENCR_PIP0_KEY3_REG 0x1E00C
#define CRYPTO_ENCR_PIP0_KEY4_REG 0x1E010
#define CRYPTO_ENCR_PIP0_KEY5_REG 0x1E004
#define CRYPTO_ENCR_PIP0_KEY6_REG 0x1E008
#define CRYPTO_ENCR_PIP0_KEY7_REG 0x1E00C
#define CRYPTO_ENCR_PIP1_KEY0_REG 0x1E000
#define CRYPTO_ENCR_PIP1_KEY1_REG 0x1E004
#define CRYPTO_ENCR_PIP1_KEY2_REG 0x1E008
#define CRYPTO_ENCR_PIP1_KEY3_REG 0x1E00C
#define CRYPTO_ENCR_PIP1_KEY4_REG 0x1E010
#define CRYPTO_ENCR_PIP1_KEY5_REG 0x1E014
#define CRYPTO_ENCR_PIP1_KEY6_REG 0x1E018
#define CRYPTO_ENCR_PIP1_KEY7_REG 0x1E01C
#define CRYPTO_ENCR_PIP2_KEY0_REG 0x1E020
#define CRYPTO_ENCR_PIP2_KEY1_REG 0x1E024
#define CRYPTO_ENCR_PIP2_KEY2_REG 0x1E028
#define CRYPTO_ENCR_PIP2_KEY3_REG 0x1E02C
#define CRYPTO_ENCR_PIP2_KEY4_REG 0x1E030
#define CRYPTO_ENCR_PIP2_KEY5_REG 0x1E034
#define CRYPTO_ENCR_PIP2_KEY6_REG 0x1E038
#define CRYPTO_ENCR_PIP2_KEY7_REG 0x1E03C
#define CRYPTO_ENCR_PIP3_KEY0_REG 0x1E040
#define CRYPTO_ENCR_PIP3_KEY1_REG 0x1E044
#define CRYPTO_ENCR_PIP3_KEY2_REG 0x1E048
#define CRYPTO_ENCR_PIP3_KEY3_REG 0x1E04C
#define CRYPTO_ENCR_PIP3_KEY4_REG 0x1E050
#define CRYPTO_ENCR_PIP3_KEY5_REG 0x1E054
#define CRYPTO_ENCR_PIP3_KEY6_REG 0x1E058
#define CRYPTO_ENCR_PIP3_KEY7_REG 0x1E05C
#define CRYPTO_ENCR_PIP0_XTS_KEY0_REG 0x1E200
#define CRYPTO_ENCR_PIP0_XTS_KEY1_REG 0x1E204
#define CRYPTO_ENCR_PIP0_XTS_KEY2_REG 0x1E208
#define CRYPTO_ENCR_PIP0_XTS_KEY3_REG 0x1E20C
#define CRYPTO_ENCR_PIP0_XTS_KEY4_REG 0x1E210
#define CRYPTO_ENCR_PIP0_XTS_KEY5_REG 0x1E214
#define CRYPTO_ENCR_PIP0_XTS_KEY6_REG 0x1E218
#define CRYPTO_ENCR_PIP0_XTS_KEY7_REG 0x1E21C
#define CRYPTO_ENCR_PIP1_XTS_KEY0_REG 0x1E220
#define CRYPTO_ENCR_PIP1_XTS_KEY1_REG 0x1E224
#define CRYPTO_ENCR_PIP1_XTS_KEY2_REG 0x1E228
#define CRYPTO_ENCR_PIP1_XTS_KEY3_REG 0x1E22C
#define CRYPTO_ENCR_PIP1_XTS_KEY4_REG 0x1E230
#define CRYPTO_ENCR_PIP1_XTS_KEY5_REG 0x1E234
#define CRYPTO_ENCR_PIP1_XTS_KEY6_REG 0x1E238
#define CRYPTO_ENCR_PIP1_XTS_KEY7_REG 0x1E23C
#define CRYPTO_ENCR_PIP2_XTS_KEY0_REG 0x1E240
#define CRYPTO_ENCR_PIP2_XTS_KEY1_REG 0x1E244
#define CRYPTO_ENCR_PIP2_XTS_KEY2_REG 0x1E248
#define CRYPTO_ENCR_PIP2_XTS_KEY3_REG 0x1E24C
#define CRYPTO_ENCR_PIP2_XTS_KEY4_REG 0x1E250
#define CRYPTO_ENCR_PIP2_XTS_KEY5_REG 0x1E254
#define CRYPTO_ENCR_PIP2_XTS_KEY6_REG 0x1E258
#define CRYPTO_ENCR_PIP2_XTS_KEY7_REG 0x1E25C
#define CRYPTO_ENCR_PIP3_XTS_KEY0_REG 0x1E260
#define CRYPTO_ENCR_PIP3_XTS_KEY1_REG 0x1E264
#define CRYPTO_ENCR_PIP3_XTS_KEY2_REG 0x1E268
#define CRYPTO_ENCR_PIP3_XTS_KEY3_REG 0x1E26C
#define CRYPTO_ENCR_PIP3_XTS_KEY4_REG 0x1E270
#define CRYPTO_ENCR_PIP3_XTS_KEY5_REG 0x1E274
#define CRYPTO_ENCR_PIP3_XTS_KEY6_REG 0x1E278
#define CRYPTO_ENCR_PIP3_XTS_KEY7_REG 0x1E27C
#define CRYPTO_CNTR0_IV0_REG 0x1A20C
#define CRYPTO_CNTR1_IV1_REG 0x1A210
#define CRYPTO_CNTR2_IV2_REG 0x1A214
#define CRYPTO_CNTR3_IV3_REG 0x1A218
#define CRYPTO_CNTR_MASK_REG 0x1A21C
#define CRYPTO_ENCR_CCM_INT_CNTR0_REG 0x1A220
#define CRYPTO_ENCR_CCM_INT_CNTR1_REG 0x1A224
#define CRYPTO_ENCR_CCM_INT_CNTR2_REG 0x1A228
#define CRYPTO_ENCR_CCM_INT_CNTR3_REG 0x1A22C
#define CRYPTO_ENCR_XTS_DU_SIZE_REG 0xA1230
#define CRYPTO_AUTH_SEG_CFG_REG 0x1A300
#define CRYPTO_AUTH_SEG_SIZE_REG 0x1A304
#define CRYPTO_AUTH_SEG_START_REG 0x1A308
#define CRYPTO_AUTH_KEY0_REG 0x1D040
#define CRYPTO_AUTH_KEY1_REG 0x1D044
#define CRYPTO_AUTH_KEY2_REG 0x1D048
#define CRYPTO_AUTH_KEY3_REG 0x1D04C
#define CRYPTO_AUTH_KEY4_REG 0x1D050
#define CRYPTO_AUTH_KEY5_REG 0x1D054
#define CRYPTO_AUTH_KEY6_REG 0x1D058
#define CRYPTO_AUTH_KEY7_REG 0x1D05C
#define CRYPTO_AUTH_KEY8_REG 0x1D060
#define CRYPTO_AUTH_KEY9_REG 0x1D064
#define CRYPTO_AUTH_KEY10_REG 0x1D068
#define CRYPTO_AUTH_KEY11_REG 0x1D06C
#define CRYPTO_AUTH_KEY12_REG 0x1D070
#define CRYPTO_AUTH_KEY13_REG 0x1D074
#define CRYPTO_AUTH_KEY14_REG 0x1D078
#define CRYPTO_AUTH_KEY15_REG 0x1D07C
#define CRYPTO_AUTH_PIPE0_KEY0_REG 0x1E800
#define CRYPTO_AUTH_PIPE0_KEY1_REG 0x1E804
#define CRYPTO_AUTH_PIPE0_KEY2_REG 0x1E808
#define CRYPTO_AUTH_PIPE0_KEY3_REG 0x1E80C
#define CRYPTO_AUTH_PIPE0_KEY4_REG 0x1E810
#define CRYPTO_AUTH_PIPE0_KEY5_REG 0x1E814
#define CRYPTO_AUTH_PIPE0_KEY6_REG 0x1E818
#define CRYPTO_AUTH_PIPE0_KEY7_REG 0x1E81C
#define CRYPTO_AUTH_PIPE0_KEY8_REG 0x1E820
#define CRYPTO_AUTH_PIPE0_KEY9_REG 0x1E824
#define CRYPTO_AUTH_PIPE0_KEY10_REG 0x1E828
#define CRYPTO_AUTH_PIPE0_KEY11_REG 0x1E82C
#define CRYPTO_AUTH_PIPE0_KEY12_REG 0x1E830
#define CRYPTO_AUTH_PIPE0_KEY13_REG 0x1E834
#define CRYPTO_AUTH_PIPE0_KEY14_REG 0x1E838
#define CRYPTO_AUTH_PIPE0_KEY15_REG 0x1E83C
#define CRYPTO_AUTH_PIPE1_KEY0_REG 0x1E800
#define CRYPTO_AUTH_PIPE1_KEY1_REG 0x1E804
#define CRYPTO_AUTH_PIPE1_KEY2_REG 0x1E808
#define CRYPTO_AUTH_PIPE1_KEY3_REG 0x1E80C
#define CRYPTO_AUTH_PIPE1_KEY4_REG 0x1E810
#define CRYPTO_AUTH_PIPE1_KEY5_REG 0x1E814
#define CRYPTO_AUTH_PIPE1_KEY6_REG 0x1E818
#define CRYPTO_AUTH_PIPE1_KEY7_REG 0x1E81C
#define CRYPTO_AUTH_PIPE1_KEY8_REG 0x1E820
#define CRYPTO_AUTH_PIPE1_KEY9_REG 0x1E824
#define CRYPTO_AUTH_PIPE1_KEY10_REG 0x1E828
#define CRYPTO_AUTH_PIPE1_KEY11_REG 0x1E82C
#define CRYPTO_AUTH_PIPE1_KEY12_REG 0x1E830
#define CRYPTO_AUTH_PIPE1_KEY13_REG 0x1E834
#define CRYPTO_AUTH_PIPE1_KEY14_REG 0x1E838
#define CRYPTO_AUTH_PIPE1_KEY15_REG 0x1E83C
#define CRYPTO_AUTH_PIPE2_KEY0_REG 0x1E840
#define CRYPTO_AUTH_PIPE2_KEY1_REG 0x1E844
#define CRYPTO_AUTH_PIPE2_KEY2_REG 0x1E848
#define CRYPTO_AUTH_PIPE2_KEY3_REG 0x1E84C
#define CRYPTO_AUTH_PIPE2_KEY4_REG 0x1E850
#define CRYPTO_AUTH_PIPE2_KEY5_REG 0x1E854
#define CRYPTO_AUTH_PIPE2_KEY6_REG 0x1E858
#define CRYPTO_AUTH_PIPE2_KEY7_REG 0x1E85C
#define CRYPTO_AUTH_PIPE2_KEY8_REG 0x1E860
#define CRYPTO_AUTH_PIPE2_KEY9_REG 0x1E864
#define CRYPTO_AUTH_PIPE2_KEY10_REG 0x1E868
#define CRYPTO_AUTH_PIPE2_KEY11_REG 0x1E86C
#define CRYPTO_AUTH_PIPE2_KEY12_REG 0x1E870
#define CRYPTO_AUTH_PIPE2_KEY13_REG 0x1E874
#define CRYPTO_AUTH_PIPE2_KEY14_REG 0x1E878
#define CRYPTO_AUTH_PIPE2_KEY15_REG 0x1E87C
#define CRYPTO_AUTH_PIPE3_KEY0_REG 0x1E880
#define CRYPTO_AUTH_PIPE3_KEY1_REG 0x1E884
#define CRYPTO_AUTH_PIPE3_KEY2_REG 0x1E888
#define CRYPTO_AUTH_PIPE3_KEY3_REG 0x1E88C
#define CRYPTO_AUTH_PIPE3_KEY4_REG 0x1E890
#define CRYPTO_AUTH_PIPE3_KEY5_REG 0x1E894
#define CRYPTO_AUTH_PIPE3_KEY6_REG 0x1E898
#define CRYPTO_AUTH_PIPE3_KEY7_REG 0x1E89C
#define CRYPTO_AUTH_PIPE3_KEY8_REG 0x1E8A0
#define CRYPTO_AUTH_PIPE3_KEY9_REG 0x1E8A4
#define CRYPTO_AUTH_PIPE3_KEY10_REG 0x1E8A8
#define CRYPTO_AUTH_PIPE3_KEY11_REG 0x1E8AC
#define CRYPTO_AUTH_PIPE3_KEY12_REG 0x1E8B0
#define CRYPTO_AUTH_PIPE3_KEY13_REG 0x1E8B4
#define CRYPTO_AUTH_PIPE3_KEY14_REG 0x1E8B8
#define CRYPTO_AUTH_PIPE3_KEY15_REG 0x1E8BC
#define CRYPTO_AUTH_IV0_REG 0x1A310
#define CRYPTO_AUTH_IV1_REG 0x1A314
#define CRYPTO_AUTH_IV2_REG 0x1A318
#define CRYPTO_AUTH_IV3_REG 0x1A31C
#define CRYPTO_AUTH_IV4_REG 0x1A320
#define CRYPTO_AUTH_IV5_REG 0x1A324
#define CRYPTO_AUTH_IV6_REG 0x1A328
#define CRYPTO_AUTH_IV7_REG 0x1A32C
#define CRYPTO_AUTH_IV8_REG 0x1A330
#define CRYPTO_AUTH_IV9_REG 0x1A334
#define CRYPTO_AUTH_IV10_REG 0x1A338
#define CRYPTO_AUTH_IV11_REG 0x1A33C
#define CRYPTO_AUTH_IV12_REG 0x1A340
#define CRYPTO_AUTH_IV13_REG 0x1A344
#define CRYPTO_AUTH_IV14_REG 0x1A348
#define CRYPTO_AUTH_IV15_REG 0x1A34C
#define CRYPTO_AUTH_INFO_NONCE0_REG 0x1A350
#define CRYPTO_AUTH_INFO_NONCE1_REG 0x1A354
#define CRYPTO_AUTH_INFO_NONCE2_REG 0x1A358
#define CRYPTO_AUTH_INFO_NONCE3_REG 0x1A35C
#define CRYPTO_AUTH_BYTECNT0_REG 0x1A390
#define CRYPTO_AUTH_BYTECNT1_REG 0x1A394
#define CRYPTO_AUTH_BYTECNT2_REG 0x1A398
#define CRYPTO_AUTH_BYTECNT3_REG 0x1A39C
#define CRYPTO_AUTH_EXP_MAC0_REG 0x1A3A0
#define CRYPTO_AUTH_EXP_MAC1_REG 0x1A3A4
#define CRYPTO_AUTH_EXP_MAC2_REG 0x1A3A8
#define CRYPTO_AUTH_EXP_MAC3_REG 0x1A3AC
#define CRYPTO_AUTH_EXP_MAC4_REG 0x1A3B0
#define CRYPTO_AUTH_EXP_MAC5_REG 0x1A3B4
#define CRYPTO_AUTH_EXP_MAC6_REG 0x1A3B8
#define CRYPTO_AUTH_EXP_MAC7_REG 0x1A3BC
#define CRYPTO_CONFIG_REG 0x1A400
#define CRYPTO_DEBUG_ENABLE_REG 0x1AF00
#define CRYPTO_DEBUG_REG 0x1AF04
/* Register bits */
#define CRYPTO_CORE_STEP_REV_MASK 0xFFFF
#define CRYPTO_CORE_STEP_REV 0 /* bit 15-0 */
#define CRYPTO_CORE_MAJOR_REV_MASK 0xFF000000
#define CRYPTO_CORE_MAJOR_REV 24 /* bit 31-24 */
#define CRYPTO_CORE_MINOR_REV_MASK 0xFF0000
#define CRYPTO_CORE_MINOR_REV 16 /* bit 23-16 */
/* status reg */
#define CRYPTO_MAC_FAILED 31
#define CRYPTO_DOUT_SIZE_AVAIL 26 /* bit 30-26 */
#define CRYPTO_DOUT_SIZE_AVAIL_MASK (0x1F << CRYPTO_DOUT_SIZE_AVAIL)
#define CRYPTO_DIN_SIZE_AVAIL 21 /* bit 21-25 */
#define CRYPTO_DIN_SIZE_AVAIL_MASK (0x1F << CRYPTO_DIN_SIZE_AVAIL)
#define CRYPTO_ACCESS_VIOL 19
#define CRYPTO_PIPE_ACTIVE_ERR 18
#define CRYPTO_CFG_CHNG_ERR 17
#define CRYPTO_DOUT_ERR 16
#define CRYPTO_DIN_ERR 15
#define CRYPTO_AXI_ERR 14
#define CRYPTO_CRYPTO_STATE 10 /* bit 13-10 */
#define CRYPTO_CRYPTO_STATE_MASK (0xF << CRYPTO_CRYPTO_STATE)
#define CRYPTO_ENCR_BUSY 9
#define CRYPTO_AUTH_BUSY 8
#define CRYPTO_DOUT_INTR 7
#define CRYPTO_DIN_INTR 6
#define CRYPTO_OP_DONE_INTR 5
#define CRYPTO_ERR_INTR 4
#define CRYPTO_DOUT_RDY 3
#define CRYPTO_DIN_RDY 2
#define CRYPTO_OPERATION_DONE 1
#define CRYPTO_SW_ERR 0
/* status2 reg */
#define CRYPTO_AXI_EXTRA 1
#define CRYPTO_LOCKED 2
/* config reg */
#define CRYPTO_REQ_SIZE 17 /* bit 20-17 */
#define CRYPTO_REQ_SIZE_MASK (0xF << CRYPTO_REQ_SIZE)
#define CRYPTO_REQ_SIZE_ENUM_1_BEAT 0
#define CRYPTO_REQ_SIZE_ENUM_2_BEAT 1
#define CRYPTO_REQ_SIZE_ENUM_3_BEAT 2
#define CRYPTO_REQ_SIZE_ENUM_4_BEAT 3
#define CRYPTO_REQ_SIZE_ENUM_5_BEAT 4
#define CRYPTO_REQ_SIZE_ENUM_6_BEAT 5
#define CRYPTO_REQ_SIZE_ENUM_7_BEAT 6
#define CRYPTO_REQ_SIZE_ENUM_8_BEAT 7
#define CRYPTO_REQ_SIZE_ENUM_9_BEAT 8
#define CRYPTO_REQ_SIZE_ENUM_10_BEAT 9
#define CRYPTO_REQ_SIZE_ENUM_11_BEAT 10
#define CRYPTO_REQ_SIZE_ENUM_12_BEAT 11
#define CRYPTO_REQ_SIZE_ENUM_13_BEAT 12
#define CRYPTO_REQ_SIZE_ENUM_14_BEAT 13
#define CRYPTO_REQ_SIZE_ENUM_15_BEAT 14
#define CRYPTO_REQ_SIZE_ENUM_16_BEAT 15
#define CRYPTO_MAX_QUEUED_REQ 14 /* bit 16-14 */
#define CRYPTO_MAX_QUEUED_REQ_MASK (0x7 << CRYPTO_MAX_QUEUED_REQ)
#define CRYPTO_ENUM_1_QUEUED_REQS 0
#define CRYPTO_ENUM_2_QUEUED_REQS 1
#define CRYPTO_ENUM_3_QUEUED_REQS 2
#define CRYPTO_IRQ_ENABLES 10 /* bit 13-10 */
#define CRYPTO_IRQ_ENABLES_MASK (0xF << CRYPTO_IRQ_ENABLES)
#define CRYPTO_LITTLE_ENDIAN_MODE 9
#define CRYPTO_PIPE_SET_SELECT 5 /* bit 8-5 */
#define CRYPTO_PIPE_SET_SELECT_MASK (0xF << CRYPTO_PIPE_SET_SELECT)
#define CRYPTO_HIGH_SPD_EN_N 4
#define CRYPTO_MASK_DOUT_INTR 3
#define CRYPTO_MASK_DIN_INTR 2
#define CRYPTO_MASK_OP_DONE_INTR 1
#define CRYPTO_MASK_ERR_INTR 0
/* auth_seg_cfg reg */
#define CRYPTO_COMP_EXP_MAC 24
#define CRYPTO_COMP_EXP_MAC_DISABLED 0
#define CRYPTO_COMP_EXP_MAC_ENABLED 1
#define CRYPTO_F9_DIRECTION 23
#define CRYPTO_F9_DIRECTION_UPLINK 0
#define CRYPTO_F9_DIRECTION_DOWNLINK 1
#define CRYPTO_AUTH_NONCE_NUM_WORDS 20 /* bit 22-20 */
#define CRYPTO_AUTH_NONCE_NUM_WORDS_MASK \
(0x7 << CRYPTO_AUTH_NONCE_NUM_WORDS)
#define CRYPTO_USE_PIPE_KEY_AUTH 19
#define CRYPTO_USE_HW_KEY_AUTH 18
#define CRYPTO_FIRST 17
#define CRYPTO_LAST 16
#define CRYPTO_AUTH_POS 15 /* bit 15 .. 14*/
#define CRYPTO_AUTH_POS_MASK (0x3 << CRYPTO_AUTH_POS)
#define CRYPTO_AUTH_POS_BEFORE 0
#define CRYPTO_AUTH_POS_AFTER 1
#define CRYPTO_AUTH_SIZE 9 /* bits 13 .. 9*/
#define CRYPTO_AUTH_SIZE_MASK (0x1F << CRYPTO_AUTH_SIZE)
#define CRYPTO_AUTH_SIZE_SHA1 0
#define CRYPTO_AUTH_SIZE_SHA256 1
#define CRYPTO_AUTH_SIZE_ENUM_1_BYTES 0
#define CRYPTO_AUTH_SIZE_ENUM_2_BYTES 1
#define CRYPTO_AUTH_SIZE_ENUM_3_BYTES 2
#define CRYPTO_AUTH_SIZE_ENUM_4_BYTES 3
#define CRYPTO_AUTH_SIZE_ENUM_5_BYTES 4
#define CRYPTO_AUTH_SIZE_ENUM_6_BYTES 5
#define CRYPTO_AUTH_SIZE_ENUM_7_BYTES 6
#define CRYPTO_AUTH_SIZE_ENUM_8_BYTES 7
#define CRYPTO_AUTH_SIZE_ENUM_9_BYTES 8
#define CRYPTO_AUTH_SIZE_ENUM_10_BYTES 9
#define CRYPTO_AUTH_SIZE_ENUM_11_BYTES 10
#define CRYPTO_AUTH_SIZE_ENUM_12_BYTES 11
#define CRYPTO_AUTH_SIZE_ENUM_13_BYTES 12
#define CRYPTO_AUTH_SIZE_ENUM_14_BYTES 13
#define CRYPTO_AUTH_SIZE_ENUM_15_BYTES 14
#define CRYPTO_AUTH_SIZE_ENUM_16_BYTES 15
#define CRYPTO_AUTH_MODE 6 /* bit 8 .. 6*/
#define CRYPTO_AUTH_MODE_MASK (0x7 << CRYPTO_AUTH_MODE)
#define CRYPTO_AUTH_MODE_HASH 0
#define CRYPTO_AUTH_MODE_HMAC 1
#define CRYPTO_AUTH_MODE_CCM 0
#define CRYPTO_AUTH_MODE_CMAC 1
#define CRYPTO_AUTH_KEY_SIZE 3 /* bit 5 .. 3*/
#define CRYPTO_AUTH_KEY_SIZE_MASK (0x7 << CRYPTO_AUTH_KEY_SIZE)
#define CRYPTO_AUTH_KEY_SZ_AES128 0
#define CRYPTO_AUTH_KEY_SZ_AES256 2
#define CRYPTO_AUTH_ALG 0 /* bit 2 .. 0*/
#define CRYPTO_AUTH_ALG_MASK 7
#define CRYPTO_AUTH_ALG_NONE 0
#define CRYPTO_AUTH_ALG_SHA 1
#define CRYPTO_AUTH_ALG_AES 2
#define CRYPTO_AUTH_ALG_KASUMI 3
#define CRYPTO_AUTH_ALG_SNOW3G 4
/* encr_xts_du_size reg */
#define CRYPTO_ENCR_XTS_DU_SIZE 0 /* bit 19-0 */
#define CRYPTO_ENCR_XTS_DU_SIZE_MASK 0xfffff
/* encr_seg_cfg reg */
#define CRYPTO_F8_KEYSTREAM_ENABLE 17/* bit */
#define CRYPTO_F8_KEYSTREAM_DISABLED 0
#define CRYPTO_F8_KEYSTREAM_ENABLED 1
#define CRYPTO_F8_DIRECTION 16 /* bit */
#define CRYPTO_F8_DIRECTION_UPLINK 0
#define CRYPTO_F8_DIRECTION_DOWNLINK 1
#define CRYPTO_USE_PIPE_KEY_ENCR 15 /* bit */
#define CRYPTO_USE_PIPE_KEY_ENCR_ENABLED 1
#define CRYPTO_USE_KEY_REGISTERS 0
#define CRYPTO_USE_HW_KEY_ENCR 14
#define CRYPTO_USE_KEY_REG 0
#define CRYPTO_USE_HW_KEY 1
#define CRYPTO_LAST_CCM 13
#define CRYPTO_LAST_CCM_XFR 1
#define CRYPTO_INTERM_CCM_XFR 0
#define CRYPTO_CNTR_ALG 11 /* bit 12-11 */
#define CRYPTO_CNTR_ALG_MASK (3 << CRYPTO_CNTR_ALG)
#define CRYPTO_CNTR_ALG_NIST 0
#define CRYPTO_ENCODE 10
#define CRYPTO_ENCR_MODE 6 /* bit 9-6 */
#define CRYPTO_ENCR_MODE_MASK (0xF << CRYPTO_ENCR_MODE)
/* only valid when AES */
#define CRYPTO_ENCR_MODE_ECB 0
#define CRYPTO_ENCR_MODE_CBC 1
#define CRYPTO_ENCR_MODE_CTR 2
#define CRYPTO_ENCR_MODE_XTS 3
#define CRYPTO_ENCR_MODE_CCM 4
#define CRYPTO_ENCR_KEY_SZ 3 /* bit 5-3 */
#define CRYPTO_ENCR_KEY_SZ_MASK (7 << CRYPTO_ENCR_KEY_SZ)
#define CRYPTO_ENCR_KEY_SZ_DES 0
#define CRYPTO_ENCR_KEY_SZ_3DES 1
#define CRYPTO_ENCR_KEY_SZ_AES128 0
#define CRYPTO_ENCR_KEY_SZ_AES256 2
#define CRYPTO_ENCR_KEY_SZ_UEA1 0
#define CRYPTO_ENCR_KEY_SZ_UEA2 1
#define CRYPTO_ENCR_ALG 0 /* bit 2-0 */
#define CRYPTO_ENCR_ALG_MASK (7 << CRYPTO_ENCR_ALG)
#define CRYPTO_ENCR_ALG_NONE 0
#define CRYPTO_ENCR_ALG_DES 1
#define CRYPTO_ENCR_ALG_AES 2
#define CRYPTO_ENCR_ALG_KASUMI 3
#define CRYPTO_ENCR_ALG_SNOW_3G 5
/* goproc reg */
#define CRYPTO_GO 0
#define CRYPTO_CLR_CNTXT 1
#define CRYPTO_RESULTS_DUMP 2
/* engines_avail */
#define CRYPTO_ENCR_AES_SEL 0
#define CRYPTO_DES_SEL 3
#define CRYPTO_ENCR_SNOW3G_SEL 4
#define CRYPTO_ENCR_KASUMI_SEL 5
#define CRYPTO_SHA_SEL 6
#define CRYPTO_SHA512_SEL 7
#define CRYPTO_AUTH_AES_SEL 8
#define CRYPTO_AUTH_SNOW3G_SEL 9
#define CRYPTO_AUTH_KASUMI_SEL 10
#define CRYPTO_BAM_SEL 11
#endif /* _DRIVERS_CRYPTO_MSM_QCRYPTOHW_50_H_ */