[PATCH 4/5] crypto: hisilicon/sec - ahash adapt to Kunpeng930 SQE
From: Kai Ye
Date: Fri Aug 13 2021 - 05:41:44 EST
The SEC ahash needs to supporting next generation of SEC
accelerator hardware. So add the new BD filling process.
Signed-off-by: Kai Ye <yekai13@xxxxxxxxxx>
---
drivers/crypto/hisilicon/sec2/sec_crypto.c | 137 ++++++++++++++++++++++++++++-
drivers/crypto/hisilicon/sec2/sec_crypto.h | 1 +
2 files changed, 136 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
index 2c6cfa7..85defc1 100644
--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
@@ -55,6 +55,8 @@
#define SEC_AUTH_ALG_OFFSET_V3 15
#define SEC_CIPHER_AUTH_V3 0xbf
#define SEC_AUTH_CIPHER_V3 0x40
+#define SEC_AI_GEN_OFFSET_V3 2
+
#define SEC_FLAG_OFFSET 7
#define SEC_FLAG_MASK 0x0780
#define SEC_TYPE_MASK 0x0F
@@ -1681,6 +1683,69 @@ static void sec_ahash_stream_bd_fill(struct sec_auth_ctx *actx,
}
}
+static void sec_ahash_stream_bd_fill_v3(struct sec_auth_ctx *actx,
+ struct sec_req *req,
+ struct sec_sqe3 *sqe3)
+{
+ struct sec_ahash_req *sareq = &req->hash_req;
+ int sid = sareq->sid;
+ char *idx = &actx->metamac_idx[sid];
+
+ /**
+ * Mac addr for ahash result
+ *
+ * First BD: idx == -1 && sec_ahash_req->op == SEC_OP_UPDATE
+ * Middle BD: idx != -1 && sec_ahash_req->op == SEC_OP_UPDATE
+ * End BD: sec_ahash_req->op == SEC_OP_FINAL ||
+ * sec_ahash_req->op == SEC_OP_FINUP
+ * NOT stream BD, idx == -1, && sec_ahash_req->op == SEC_OP_FINAL ||
+ * sec_ahash_req->op == SEC_OP_FINUP
+ */
+ if (*idx != (char)-1) {
+ sqe3->auth_ivin.a_ivin_addr = cpu_to_le64(actx->metamac_dma +
+ (sid + *idx) * SEC_MAX_DIGEST_SZ);
+
+ sqe3->mac_addr = cpu_to_le64(actx->metamac_dma +
+ (sid + ((unsigned char)*idx ^ 0x1)) * SEC_MAX_DIGEST_SZ);
+ /* Middle BD */
+ if (sareq->op == SEC_SHA_UPDATE) {
+ sqe3->auth_mac_key |= cpu_to_le32((u32)AIGEN_NOGEN <<
+ SEC_AI_GEN_OFFSET_V3);
+ sqe3->stream_scene.stream_auth_pad = AUTHPAD_NOPAD;
+ }
+ } else {
+ /* no meta-mac */
+ sqe3->mac_addr = cpu_to_le64(actx->metamac_dma +
+ sid * SEC_MAX_DIGEST_SZ);
+ /* First BD */
+ if (sareq->op == SEC_SHA_UPDATE) {
+ sqe3->auth_mac_key |= cpu_to_le32((u32)AIGEN_GEN <<
+ SEC_AI_GEN_OFFSET_V3);
+ sqe3->stream_scene.stream_auth_pad = AUTHPAD_NOPAD;
+ sareq->is_stream_mode = true;
+ }
+ }
+
+ /* End BD */
+ if ((sareq->op == SEC_SHA_FINAL || sareq->op == SEC_SHA_FINUP) &&
+ sareq->is_stream_mode) {
+ sqe3->auth_ivin.a_ivin_addr = cpu_to_le64(actx->metamac_dma +
+ (sid + *idx) * SEC_MAX_DIGEST_SZ);
+
+ sqe3->mac_addr = cpu_to_le64(actx->metamac_dma + (sid +
+ ((unsigned char)*idx ^ 0x1)) * SEC_MAX_DIGEST_SZ);
+
+ sqe3->auth_mac_key |= cpu_to_le32((u32)AIGEN_NOGEN <<
+ SEC_AI_GEN_OFFSET_V3);
+ sqe3->stream_scene.stream_auth_pad = AUTHPAD_PAD;
+
+ /* Fill the total hash data length */
+ sqe3->stream_scene.long_a_data_len =
+ cpu_to_le64(sareq->total_data_len << 0x3);
+ sareq->is_stream_mode = false;
+ }
+}
+
static void sec_ahash_data_len_fill(struct sec_ahash_req *sareq,
struct sec_sqe *sec_sqe)
{
@@ -1693,6 +1758,18 @@ static void sec_ahash_data_len_fill(struct sec_ahash_req *sareq,
sec_sqe->type2.alen_ivllen = cpu_to_le32(sareq->req_data_len);
}
+static void sec_ahash_data_len_fill_v3(struct sec_ahash_req *sareq,
+ struct sec_sqe3 *sec_sqe3)
+{
+ if ((sareq->op == SEC_SHA_UPDATE || sareq->op == SEC_SHA_FINAL) &&
+ sareq->pp_data_len)
+ sec_sqe3->a_len_key = cpu_to_le32(sareq->block_data_len);
+ else if (!sareq->pp_data_len && sareq->op == SEC_SHA_FINAL)
+ sec_sqe3->a_len_key = cpu_to_le32(0);
+ else
+ sec_sqe3->a_len_key = cpu_to_le32(sareq->req_data_len);
+}
+
static int sec_ahash_bd_fill(struct sec_ctx *ctx, struct sec_req *req)
{
struct sec_auth_ctx *actx = &ctx->a_ctx;
@@ -1733,6 +1810,47 @@ static int sec_ahash_bd_fill(struct sec_ctx *ctx, struct sec_req *req)
return 0;
}
+static int sec_ahash_bd_fill_v3(struct sec_ctx *ctx, struct sec_req *req)
+{
+ struct sec_auth_ctx *actx = &ctx->a_ctx;
+ struct sec_sqe3 *sec_sqe3 = &req->sec_sqe3;
+ struct sec_ahash_req *sareq = &req->hash_req;
+ dma_addr_t pp_dma = sareq->pp_dma;
+ u32 bd_param = 0;
+
+ memset(sec_sqe3, 0, sizeof(struct sec_sqe3));
+
+ bd_param |= SEC_SGL << SEC_SRC_SGL_OFFSET_V3;
+ bd_param |= SEC_STREAM_SCENE << SEC_SCENE_OFFSET_V3;
+ bd_param |= SEC_BD_TYPE3;
+ sec_sqe3->bd_param = cpu_to_le32(bd_param);
+
+ sec_sqe3->data_src_addr = cpu_to_le64(pp_dma);
+
+ sec_sqe3->a_key_addr = cpu_to_le64(actx->a_key_dma);
+
+ sec_sqe3->auth_mac_key = cpu_to_le32((u32)SEC_AUTH_TYPE1);
+
+ sec_sqe3->auth_mac_key |=
+ cpu_to_le32((u32)(actx->mac_len /
+ SEC_SQE_LEN_RATE) << SEC_MAC_OFFSET_V3);
+
+ sec_sqe3->auth_mac_key |=
+ cpu_to_le32((u32)((actx->a_key_len) /
+ SEC_SQE_LEN_RATE) << SEC_AKEY_OFFSET_V3);
+
+ sec_sqe3->auth_mac_key |=
+ cpu_to_le32((u32)(actx->a_alg) << SEC_AUTH_ALG_OFFSET_V3);
+
+ sec_ahash_data_len_fill_v3(sareq, sec_sqe3);
+
+ sec_ahash_stream_bd_fill_v3(actx, req, sec_sqe3);
+
+ sec_sqe3->tag = cpu_to_le64((unsigned long)(uintptr_t)req);
+
+ return 0;
+}
+
/* increment counter (128-bit int) */
static void ctr_iv_inc(__u8 *counter, __u8 bits, __u32 nums)
{
@@ -2295,6 +2413,16 @@ static const struct sec_req_op sec_aead_req_ops_v3 = {
.process = sec_process,
};
+static const struct sec_req_op sec_ahash_req_ops_v3 = {
+ .buf_map = sec_ahash_sgl_map,
+ .buf_unmap = sec_ahash_sgl_unmap,
+ .do_transfer = sec_ahash_transfer,
+ .bd_fill = sec_ahash_bd_fill_v3,
+ .bd_send = sec_bd_send,
+ .callback = sec_ahash_callback,
+ .process = sec_process,
+};
+
static int sec_skcipher_ctx_init(struct crypto_skcipher *tfm)
{
struct sec_ctx *ctx = crypto_skcipher_ctx(tfm);
@@ -2875,8 +3003,13 @@ static int sec_ahash_tfm_init(struct crypto_tfm *tfm, const char *ahash_name)
if (ret)
goto err_auth_init;
- ctx->type_supported = SEC_BD_TYPE2;
- ctx->req_op = &sec_ahash_req_ops;
+ if (ctx->sec->qm.ver < QM_HW_V3) {
+ ctx->type_supported = SEC_BD_TYPE2;
+ ctx->req_op = &sec_ahash_req_ops;
+ } else {
+ ctx->type_supported = SEC_BD_TYPE3;
+ ctx->req_op = &sec_ahash_req_ops_v3;
+ }
/* Support 128 streams/threads per TFM, memory for small packets */
ret = sec_stream_mode_init(ctx);
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.h b/drivers/crypto/hisilicon/sec2/sec_crypto.h
index 2157b98..9f117b5 100644
--- a/drivers/crypto/hisilicon/sec2/sec_crypto.h
+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.h
@@ -9,6 +9,7 @@
#define SEC_MAX_KEY_SIZE 64
#define SEC_COMM_SCENE 0
#define SEC_IPSEC_SCENE 1
+#define SEC_STREAM_SCENE 0x7
#define SEC_MAX_STREAMS 128
#define SEC_SHA1_ALIGN_SZ 64
#define SEC_SHA512_ALIGN_SZ 128
--
2.7.4