From 71d7f88f42da4959037adebd34804ef32af95d0d Mon Sep 17 00:00:00 2001
From: Kai Ye <yekai13@huawei.com>
Date: Wed, 22 Jun 2022 10:26:30 +0800
Subject: [PATCH 140/183] uadk: supports zip and sec message dumping

Dumping ZIP and SEC messages as receiving task errors.

Signed-off-by: Kai Ye <yekai13@huawei.com>
---
 drv/hisi_comp.c             |  18 ++-
 drv/hisi_sec.c              | 297 +++++++++++++++++++++++-------------
 include/drv/wd_aead_drv.h   |   1 +
 include/drv/wd_cipher_drv.h |   1 +
 include/drv/wd_digest_drv.h |   1 +
 wd_aead.c                   |   5 +
 wd_cipher.c                 |   5 +
 wd_digest.c                 |   5 +
 8 files changed, 227 insertions(+), 106 deletions(-)

diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c
index 2c0fc41..69785e9 100644
--- a/drv/hisi_comp.c
+++ b/drv/hisi_comp.c
@@ -189,6 +189,13 @@ struct hisi_zip_ctx {
 	struct wd_ctx_config_internal	config;
 };
 
+static void dump_zip_msg(struct wd_comp_msg *msg)
+{
+	WD_ERR("dump zip message after a task error occurs.\n");
+	WD_ERR("avali_out:%u in_cons:%u produced:%u data_fmt:%d.\n",
+		msg->avail_out, msg->in_cons, msg->produced, msg->data_fmt);
+}
+
 static int buf_size_check_deflate(__u32 *in_size, __u32 *out_size)
 {
 	if (unlikely(*in_size > HZ_MAX_SIZE)) {
@@ -958,13 +965,15 @@ static void get_ctx_buf(struct hisi_zip_sqe *sqe,
 }
 
 static int parse_zip_sqe(struct hisi_qp *qp, struct hisi_zip_sqe *sqe,
-			 struct wd_comp_msg *recv_msg)
+			 struct wd_comp_msg *msg)
 {
 	__u32 buf_type = (sqe->dw9 & HZ_BUF_TYPE_MASK) >> BUF_TYPE_SHIFT;
 	__u16 ctx_st = sqe->ctx_dw0 & HZ_CTX_ST_MASK;
 	__u16 lstblk = sqe->dw3 & HZ_LSTBLK_MASK;
 	__u32 status = sqe->dw3 & HZ_STATUS_MASK;
 	__u32 type = sqe->dw9 & HZ_REQ_TYPE_MASK;
+	struct wd_comp_msg *recv_msg = msg;
+	bool need_debug = wd_need_debug();
 	int alg_type, ret;
 	__u32 tag;
 
@@ -1007,7 +1016,9 @@ static int parse_zip_sqe(struct hisi_qp *qp, struct hisi_zip_sqe *sqe,
 	if (ctx_st == HZ_DECOMP_NO_SPACE)
 		recv_msg->req.status = WD_EAGAIN;
 
-	dbg("zip recv lst =%hu, ctx_st=0x%x, status=0x%x, alg=%u!\n", lstblk, ctx_st, status, type);
+	if (need_debug)
+		WD_DEBUG("zip recv lst =%hu, ctx_st=0x%x, status=0x%x, alg=%u!\n",
+		 lstblk, ctx_st, status, type);
 	if (lstblk && (status == HZ_DECOMP_END))
 		recv_msg->req.status = WD_STREAM_END;
 
@@ -1018,6 +1029,9 @@ static int parse_zip_sqe(struct hisi_qp *qp, struct hisi_zip_sqe *sqe,
 	if (buf_type == WD_SGL_BUF)
 		free_hw_sgl((handle_t)qp, sqe, alg_type);
 
+	if (unlikely(recv_msg->req.status == WD_IN_EPARA))
+		dump_zip_msg(recv_msg);
+
 	return 0;
 }
 
diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c
index 7f12549..5865ffb 100644
--- a/drv/hisi_sec.c
+++ b/drv/hisi_sec.c
@@ -486,6 +486,56 @@ static int g_hmac_a_alg[WD_DIGEST_TYPE_MAX] = {
 int hisi_sec_init(struct wd_ctx_config_internal *config, void *priv);
 void hisi_sec_exit(void *priv);
 
+static void dump_sec_msg(void *msg, const char *alg)
+{
+	struct wd_cipher_msg *cmsg;
+	struct wd_digest_msg *dmsg;
+	struct wd_aead_msg *amsg;
+
+	WD_ERR("dump %s alg message after a task error occurs.\n", alg);
+
+	if (!strcmp(alg, "cipher")) {
+		cmsg = (struct wd_cipher_msg *)msg;
+		WD_ERR("type:%u alg:%u op_type:%u mode:%u data_fmt:%u\n",
+			cmsg->alg_type, cmsg->alg, cmsg->op_type, cmsg->mode,
+			cmsg->data_fmt);
+		WD_ERR("key_bytes:%u iv_bytes:%u in_bytes:%u out_bytes:%u\n",
+			cmsg->key_bytes, cmsg->iv_bytes, cmsg->in_bytes, cmsg->out_bytes);
+	} else if (!strcmp(alg, "digest")) {
+		dmsg = (struct wd_digest_msg *)msg;
+		WD_ERR("type:%u alg:%u has_next:%u mode:%u data_fmt:%u\n",
+			dmsg->alg_type, dmsg->alg, dmsg->has_next, dmsg->mode, dmsg->data_fmt);
+		WD_ERR("key_bytes:%u iv_bytes:%u in_bytes:%u out_bytes:%u\n",
+			dmsg->key_bytes, dmsg->iv_bytes, dmsg->in_bytes, dmsg->out_bytes);
+	} else if (!strcmp(alg, "aead")) {
+		amsg = (struct wd_aead_msg *)msg;
+		WD_ERR("type:%u calg:%u op_type:%u cmode:%u\n",
+			amsg->alg_type, amsg->calg, amsg->op_type, amsg->cmode);
+		WD_ERR("data_fmt:%u ckey_bytes:%u auth_bytes:%u\n",
+			amsg->data_fmt, amsg->ckey_bytes, amsg->auth_bytes);
+		WD_ERR("assoc_bytes:%u in_bytes:%u  out_bytes:%u\n",
+			amsg->assoc_bytes, amsg->in_bytes, amsg->out_bytes);
+	}
+}
+
+static __u8 get_data_fmt_v3(__u32 bd_param)
+{
+	/* Only check the src addr type */
+	if (bd_param & SEC_PBUFF_MODE_MASK_V3)
+		return WD_SGL_BUF;
+
+	return WD_FLAT_BUF;
+}
+
+static __u8 get_data_fmt_v2(__u32 sds_sa_type)
+{
+	/* Only check the src addr type */
+	if (sds_sa_type & SEC_SGL_SDS_MASK)
+		return WD_SGL_BUF;
+
+	return WD_FLAT_BUF;
+}
+
 /* increment counter (128-bit int) by software */
 static void ctr_iv_inc(__u8 *counter, __u32 len)
 {
@@ -668,25 +718,14 @@ static void fill_cipher_bd2_addr(struct wd_cipher_msg *msg,
 	sqe->type2.data_dst_addr = (__u64)(uintptr_t)msg->out;
 	sqe->type2.c_ivin_addr = (__u64)(uintptr_t)msg->iv;
 	sqe->type2.c_key_addr = (__u64)(uintptr_t)msg->key;
-
-	/*
-	 * Because some special algorithms need to update IV
-	 * after receiving the BD, and the relevant information
-	 * is in the send message, so the BD field segment is
-	 * needed to return the message pointer.
-	 * The Cipher algorithm does not use the mac_addr segment
-	 * in the BD domain and the hardware will copy all the
-	 * field values of the send BD when returning, so we use
-	 * mac_addr to carry the message pointer here.
-	 */
-	sqe->type2.mac_addr = (__u64)(uintptr_t)msg;
 }
 
-static void parse_cipher_bd2(struct hisi_sec_sqe *sqe,
+static void parse_cipher_bd2(struct hisi_qp *qp, struct hisi_sec_sqe *sqe,
 			     struct wd_cipher_msg *recv_msg)
 {
-	struct wd_cipher_msg *rmsg;
+	struct wd_cipher_msg *temp_msg;
 	__u16 done;
+	__u32 tag;
 
 	done = sqe->type2.done_flag & SEC_DONE_MASK;
 	if (done != SEC_HW_TASK_DONE || sqe->type2.error_type) {
@@ -697,17 +736,33 @@ static void parse_cipher_bd2(struct hisi_sec_sqe *sqe,
 		recv_msg->result = WD_SUCCESS;
 	}
 
-	rmsg = (struct wd_cipher_msg *)(uintptr_t)sqe->type2.mac_addr;
+	tag = sqe->type2.tag;
+	recv_msg->tag = tag;
+
+	if (qp->q_info.qp_mode == CTX_MODE_ASYNC) {
+		recv_msg->alg_type = WD_CIPHER;
+		recv_msg->data_fmt = get_data_fmt_v2(sqe->sds_sa_type);
+		recv_msg->in = (__u8 *)(uintptr_t)sqe->type2.data_src_addr;
+		recv_msg->out = (__u8 *)(uintptr_t)sqe->type2.data_dst_addr;
+		temp_msg = wd_cipher_get_msg(qp->q_info.idx, tag);
+		if (!temp_msg) {
+			recv_msg->result = WD_IN_EPARA;
+			WD_ERR("failed to get send msg! idx = %u, tag = %u.\n",
+				qp->q_info.idx, tag);
+			return;
+		}
+	} else {
+		/* The synchronization mode uses the same message */
+		temp_msg = recv_msg;
+	}
 
-	if (rmsg->data_fmt != WD_SGL_BUF)
-		update_iv(rmsg);
+	if (temp_msg->data_fmt != WD_SGL_BUF)
+		update_iv(temp_msg);
 	else
-		update_iv_sgl(rmsg);
+		update_iv_sgl(temp_msg);
 
-	recv_msg->data_fmt = rmsg->data_fmt;
-	recv_msg->alg_type = rmsg->alg_type;
-	recv_msg->in = rmsg->in;
-	recv_msg->out = rmsg->out;
+	if (unlikely(recv_msg->result != WD_SUCCESS))
+		dump_sec_msg(temp_msg, "cipher");
 }
 
 static int cipher_len_check(struct wd_cipher_msg *msg)
@@ -752,24 +807,6 @@ static int cipher_len_check(struct wd_cipher_msg *msg)
 	return 0;
 }
 
-static __u8 hisi_sec_get_data_fmt_v3(__u32 bd_param)
-{
-	/* Only check the src addr type */
-	if (bd_param & SEC_PBUFF_MODE_MASK_V3)
-		return WD_SGL_BUF;
-
-	return WD_FLAT_BUF;
-}
-
-static __u8 hisi_sec_get_data_fmt_v2(__u32 sds_sa_type)
-{
-	/* Only check the src addr type */
-	if (sds_sa_type & SEC_SGL_SDS_MASK)
-		return WD_SGL_BUF;
-
-	return WD_FLAT_BUF;
-}
-
 static void hisi_sec_put_sgl(handle_t h_qp, __u8 alg_type, void *in, void *out)
 {
 	handle_t h_sgl_pool;
@@ -967,8 +1004,7 @@ int hisi_sec_cipher_recv(handle_t ctx, void *cipher_msg)
 	if (ret)
 		return ret;
 
-	parse_cipher_bd2(&sqe, recv_msg);
-	recv_msg->tag = sqe.type2.tag;
+	parse_cipher_bd2((struct hisi_qp *)h_qp, &sqe, recv_msg);
 
 	if (recv_msg->data_fmt == WD_SGL_BUF)
 		hisi_sec_put_sgl(h_qp, recv_msg->alg_type, recv_msg->in,
@@ -1064,18 +1100,6 @@ static void fill_cipher_bd3_addr(struct wd_cipher_msg *msg,
 	sqe->data_dst_addr = (__u64)(uintptr_t)msg->out;
 	sqe->no_scene.c_ivin_addr = (__u64)(uintptr_t)msg->iv;
 	sqe->c_key_addr = (__u64)(uintptr_t)msg->key;
-
-	/*
-	 * Because some special algorithms need to update IV
-	 * after receiving the BD, and the relevant information
-	 * is in the send message, so the BD field segment is
-	 * needed to return the message pointer.
-	 * The Cipher algorithm does not use the mac_addr segment
-	 * in the BD domain and the hardware will copy all the
-	 * field values of the send BD when returning, so we use
-	 * mac_addr to carry the message pointer here.
-	 */
-	sqe->mac_addr = (__u64)(uintptr_t)msg;
 }
 
 static int fill_cipher_bd3(struct wd_cipher_msg *msg, struct hisi_sec_sqe3 *sqe)
@@ -1159,11 +1183,12 @@ int hisi_sec_cipher_send_v3(handle_t ctx, void *cipher_msg)
 	return 0;
 }
 
-static void parse_cipher_bd3(struct hisi_sec_sqe3 *sqe,
+static void parse_cipher_bd3(struct hisi_qp *qp, struct hisi_sec_sqe3 *sqe,
 			     struct wd_cipher_msg *recv_msg)
 {
-	struct wd_cipher_msg *rmsg;
+	struct wd_cipher_msg *temp_msg;
 	__u16 done;
+	__u32 tag;
 
 	done = sqe->done_flag & SEC_DONE_MASK;
 	if (done != SEC_HW_TASK_DONE || sqe->error_type) {
@@ -1174,16 +1199,33 @@ static void parse_cipher_bd3(struct hisi_sec_sqe3 *sqe,
 		recv_msg->result = WD_SUCCESS;
 	}
 
-	rmsg = (struct wd_cipher_msg *)(uintptr_t)sqe->mac_addr;
-	if (rmsg->data_fmt != WD_SGL_BUF)
-		update_iv(rmsg);
+	tag = sqe->tag;
+
+	recv_msg->tag = tag;
+	if (qp->q_info.qp_mode == CTX_MODE_ASYNC) {
+		recv_msg->alg_type = WD_CIPHER;
+		recv_msg->data_fmt = get_data_fmt_v3(sqe->bd_param);
+		recv_msg->in = (__u8 *)(uintptr_t)sqe->data_src_addr;
+		recv_msg->out = (__u8 *)(uintptr_t)sqe->data_dst_addr;
+		temp_msg = wd_cipher_get_msg(qp->q_info.idx, tag);
+		if (!temp_msg) {
+			recv_msg->result = WD_IN_EPARA;
+			WD_ERR("failed to get send msg! idx = %u, tag = %u.\n",
+				qp->q_info.idx, tag);
+			return;
+		}
+	} else {
+		/* The synchronization mode uses the same message */
+		temp_msg = recv_msg;
+	}
+
+	if (temp_msg->data_fmt != WD_SGL_BUF)
+		update_iv(temp_msg);
 	else
-		update_iv_sgl(rmsg);
+		update_iv_sgl(temp_msg);
 
-	recv_msg->data_fmt = rmsg->data_fmt;
-	recv_msg->alg_type = rmsg->alg_type;
-	recv_msg->in = rmsg->in;
-	recv_msg->out = rmsg->out;
+	if (unlikely(recv_msg->result != WD_SUCCESS))
+		dump_sec_msg(temp_msg, "cipher");
 }
 
 int hisi_sec_cipher_recv_v3(handle_t ctx, void *cipher_msg)
@@ -1202,8 +1244,7 @@ int hisi_sec_cipher_recv_v3(handle_t ctx, void *cipher_msg)
 	if (ret)
 		return ret;
 
-	parse_cipher_bd3(&sqe, recv_msg);
-	recv_msg->tag = sqe.tag;
+	parse_cipher_bd3((struct hisi_qp *)h_qp, &sqe, recv_msg);
 
 	if (recv_msg->data_fmt == WD_SGL_BUF)
 		hisi_sec_put_sgl(h_qp, recv_msg->alg_type, recv_msg->in,
@@ -1268,9 +1309,10 @@ static void qm_fill_digest_long_bd(struct wd_digest_msg *msg,
 	}
 }
 
-static void parse_digest_bd2(struct hisi_sec_sqe *sqe,
+static void parse_digest_bd2(struct hisi_qp *qp, struct hisi_sec_sqe *sqe,
 			     struct wd_digest_msg *recv_msg)
 {
+	struct wd_digest_msg *temp_msg;
 	__u16 done;
 
 	done = sqe->type2.done_flag & SEC_DONE_MASK;
@@ -1284,9 +1326,24 @@ static void parse_digest_bd2(struct hisi_sec_sqe *sqe,
 
 	recv_msg->tag = sqe->type2.tag;
 
-	recv_msg->data_fmt = hisi_sec_get_data_fmt_v2(sqe->sds_sa_type);
-	recv_msg->in = (__u8 *)(uintptr_t)sqe->type2.data_src_addr;
-	recv_msg->alg_type = WD_DIGEST;
+	if (qp->q_info.qp_mode == CTX_MODE_ASYNC) {
+		recv_msg->alg_type = WD_DIGEST;
+		recv_msg->data_fmt = get_data_fmt_v2(sqe->sds_sa_type);
+		recv_msg->in = (__u8 *)(uintptr_t)sqe->type2.data_src_addr;
+		temp_msg = wd_digest_get_msg(qp->q_info.idx, recv_msg->tag);
+		if (!temp_msg) {
+			recv_msg->result = WD_IN_EPARA;
+			WD_ERR("failed to get send msg! idx = %u, tag = %u.\n",
+				qp->q_info.idx, recv_msg->tag);
+			return;
+		}
+	} else {
+		/* The synchronization mode uses the same message */
+		temp_msg = recv_msg;
+	}
+
+	if (unlikely(recv_msg->result != WD_SUCCESS))
+		dump_sec_msg(temp_msg, "digest");
 }
 
 static int digest_long_bd_check(struct wd_digest_msg *msg)
@@ -1417,7 +1474,7 @@ int hisi_sec_digest_recv(handle_t ctx, void *digest_msg)
 	if (ret)
 		return ret;
 
-	parse_digest_bd2(&sqe, recv_msg);
+	parse_digest_bd2((struct hisi_qp *)h_qp, &sqe, recv_msg);
 
 	if (recv_msg->data_fmt == WD_SGL_BUF)
 		hisi_sec_put_sgl(h_qp, recv_msg->alg_type, recv_msg->in,
@@ -1558,9 +1615,10 @@ put_sgl:
 	return ret;
 }
 
-static void parse_digest_bd3(struct hisi_sec_sqe3 *sqe,
+static void parse_digest_bd3(struct hisi_qp *qp, struct hisi_sec_sqe3 *sqe,
 				struct wd_digest_msg *recv_msg)
 {
+	struct wd_digest_msg *temp_msg;
 	__u16 done;
 
 	done = sqe->done_flag & SEC_DONE_MASK;
@@ -1574,9 +1632,24 @@ static void parse_digest_bd3(struct hisi_sec_sqe3 *sqe,
 
 	recv_msg->tag = sqe->tag;
 
-	recv_msg->data_fmt = hisi_sec_get_data_fmt_v3(sqe->bd_param);
-	recv_msg->in = (__u8 *)(uintptr_t)sqe->data_src_addr;
-	recv_msg->alg_type = WD_DIGEST;
+	if (qp->q_info.qp_mode == CTX_MODE_ASYNC) {
+		recv_msg->alg_type = WD_DIGEST;
+		recv_msg->data_fmt = get_data_fmt_v3(sqe->bd_param);
+		recv_msg->in = (__u8 *)(uintptr_t)sqe->data_src_addr;
+		temp_msg = wd_digest_get_msg(qp->q_info.idx, recv_msg->tag);
+		if (!temp_msg) {
+			recv_msg->result = WD_IN_EPARA;
+			WD_ERR("failed to get send msg! idx = %u, tag = %u.\n",
+				qp->q_info.idx, recv_msg->tag);
+			return;
+		}
+	} else {
+		/* The synchronization mode uses the same message */
+		temp_msg = recv_msg;
+	}
+
+	if (unlikely(recv_msg->result != WD_SUCCESS))
+		dump_sec_msg(temp_msg, "digest");
 }
 
 int hisi_sec_digest_recv_v3(handle_t ctx, void *digest_msg)
@@ -1595,7 +1668,7 @@ int hisi_sec_digest_recv_v3(handle_t ctx, void *digest_msg)
 	if (ret)
 		return ret;
 
-	parse_digest_bd3(&sqe, recv_msg);
+	parse_digest_bd3((struct hisi_qp *)h_qp, &sqe, recv_msg);
 
 	if (recv_msg->data_fmt == WD_SGL_BUF)
 		hisi_sec_put_sgl(h_qp,  recv_msg->alg_type, recv_msg->in,
@@ -1899,9 +1972,10 @@ int hisi_sec_aead_send(handle_t ctx, void *aead_msg)
 	return 0;
 }
 
-static void parse_aead_bd2(struct hisi_sec_sqe *sqe,
+static void parse_aead_bd2(struct hisi_qp *qp, struct hisi_sec_sqe *sqe,
 	struct wd_aead_msg *recv_msg)
 {
+	struct wd_aead_msg *temp_msg;
 	__u16 done, icv;
 
 	done = sqe->type2.done_flag & SEC_DONE_MASK;
@@ -1917,18 +1991,25 @@ static void parse_aead_bd2(struct hisi_sec_sqe *sqe,
 
 	recv_msg->tag = sqe->type2.tag;
 
-	recv_msg->data_fmt = hisi_sec_get_data_fmt_v2(sqe->sds_sa_type);
-	recv_msg->in = (__u8 *)(uintptr_t)sqe->type2.data_src_addr;
-	recv_msg->out = (__u8 *)(uintptr_t)sqe->type2.data_dst_addr;
-	recv_msg->alg_type = WD_AEAD;
-	recv_msg->mac = (__u8 *)(uintptr_t)sqe->type2.mac_addr;
-	recv_msg->auth_bytes = (sqe->type2.mac_key_alg &
-			       SEC_MAC_LEN_MASK) * WORD_BYTES;
-	if (!recv_msg->auth_bytes)
-		recv_msg->auth_bytes = sqe->type2.icvw_kmode &
-				       SEC_AUTH_LEN_MASK;
-	recv_msg->out_bytes = sqe->type2.clen_ivhlen +
-			      sqe->type2.cipher_src_offset;
+	if (qp->q_info.qp_mode == CTX_MODE_ASYNC) {
+		recv_msg->alg_type = WD_AEAD;
+		recv_msg->data_fmt = get_data_fmt_v2(sqe->sds_sa_type);
+		recv_msg->in = (__u8 *)(uintptr_t)sqe->type2.data_src_addr;
+		recv_msg->out = (__u8 *)(uintptr_t)sqe->type2.data_dst_addr;
+		temp_msg = wd_aead_get_msg(qp->q_info.idx, recv_msg->tag);
+		if (!temp_msg) {
+			recv_msg->result = WD_IN_EPARA;
+			WD_ERR("failed to get send msg! idx = %u, tag = %u.\n",
+				qp->q_info.idx, recv_msg->tag);
+			return;
+		}
+	} else {
+		/* The synchronization mode uses the same message */
+		temp_msg = recv_msg;
+	}
+
+	if (unlikely(recv_msg->result != WD_SUCCESS))
+		dump_sec_msg(temp_msg, "aead");
 }
 
 int hisi_sec_aead_recv(handle_t ctx, void *aead_msg)
@@ -1947,7 +2028,7 @@ int hisi_sec_aead_recv(handle_t ctx, void *aead_msg)
 	if (ret)
 		return ret;
 
-	parse_aead_bd2(&sqe, recv_msg);
+	parse_aead_bd2((struct hisi_qp *)h_qp, &sqe, recv_msg);
 
 	if (recv_msg->data_fmt == WD_SGL_BUF)
 		hisi_sec_put_sgl(h_qp, recv_msg->alg_type, recv_msg->in,
@@ -2160,9 +2241,10 @@ int hisi_sec_aead_send_v3(handle_t ctx, void *aead_msg)
 	return 0;
 }
 
-static void parse_aead_bd3(struct hisi_sec_sqe3 *sqe,
+static void parse_aead_bd3(struct hisi_qp *qp, struct hisi_sec_sqe3 *sqe,
 	struct wd_aead_msg *recv_msg)
 {
+	struct wd_aead_msg *temp_msg;
 	__u16 done, icv;
 
 	done = sqe->done_flag & SEC_DONE_MASK;
@@ -2178,18 +2260,25 @@ static void parse_aead_bd3(struct hisi_sec_sqe3 *sqe,
 
 	recv_msg->tag = sqe->tag;
 
-	recv_msg->data_fmt = hisi_sec_get_data_fmt_v3(sqe->bd_param);
-	recv_msg->in = (__u8 *)(uintptr_t)sqe->data_src_addr;
-	recv_msg->out = (__u8 *)(uintptr_t)sqe->data_dst_addr;
-	recv_msg->alg_type = WD_AEAD;
-	recv_msg->mac = (__u8 *)(uintptr_t)sqe->mac_addr;
-	recv_msg->auth_bytes = ((sqe->auth_mac_key >> SEC_MAC_OFFSET_V3) &
-			       SEC_MAC_LEN_MASK) * WORD_BYTES;
-	if (!recv_msg->auth_bytes)
-		recv_msg->auth_bytes = (sqe->c_icv_key >> SEC_MAC_OFFSET_V3) &
-				       SEC_MAC_LEN_MASK;
-	recv_msg->out_bytes = sqe->c_len_ivin +
-			      sqe->cipher_src_offset;
+	if (qp->q_info.qp_mode == CTX_MODE_ASYNC) {
+		recv_msg->alg_type = WD_AEAD;
+		recv_msg->data_fmt = get_data_fmt_v3(sqe->bd_param);
+		recv_msg->in = (__u8 *)(uintptr_t)sqe->data_src_addr;
+		recv_msg->out = (__u8 *)(uintptr_t)sqe->data_dst_addr;
+		temp_msg = wd_aead_get_msg(qp->q_info.idx, recv_msg->tag);
+		if (!temp_msg) {
+			recv_msg->result = WD_IN_EPARA;
+			WD_ERR("failed to get send msg! idx = %u, tag = %u.\n",
+				qp->q_info.idx, recv_msg->tag);
+			return;
+		}
+	} else {
+		/* The synchronization mode uses the same message */
+		temp_msg = recv_msg;
+	}
+
+	if (unlikely(recv_msg->result != WD_SUCCESS))
+		dump_sec_msg(temp_msg, "aead");
 }
 
 int hisi_sec_aead_recv_v3(handle_t ctx, void *aead_msg)
@@ -2208,7 +2297,7 @@ int hisi_sec_aead_recv_v3(handle_t ctx, void *aead_msg)
 	if (ret)
 		return ret;
 
-	parse_aead_bd3(&sqe, recv_msg);
+	parse_aead_bd3((struct hisi_qp *)h_qp, &sqe, recv_msg);
 
 	if (recv_msg->data_fmt == WD_SGL_BUF)
 		hisi_sec_put_sgl(h_qp, recv_msg->alg_type,
diff --git a/include/drv/wd_aead_drv.h b/include/drv/wd_aead_drv.h
index cca28ba..de4a7d7 100644
--- a/include/drv/wd_aead_drv.h
+++ b/include/drv/wd_aead_drv.h
@@ -76,6 +76,7 @@ struct wd_aead_driver {
 
 void wd_aead_set_driver(struct wd_aead_driver *drv);
 struct wd_aead_driver *wd_aead_get_driver(void);
+struct wd_aead_msg *wd_aead_get_msg(__u32 idx, __u32 tag);
 
 #ifdef WD_STATIC_DRV
 #define WD_AEAD_SET_DRIVER(drv)					      \
diff --git a/include/drv/wd_cipher_drv.h b/include/drv/wd_cipher_drv.h
index 84c9844..a8da8cc 100644
--- a/include/drv/wd_cipher_drv.h
+++ b/include/drv/wd_cipher_drv.h
@@ -62,6 +62,7 @@ struct wd_cipher_driver {
 
 void wd_cipher_set_driver(struct wd_cipher_driver *drv);
 struct wd_cipher_driver *wd_cipher_get_driver(void);
+struct wd_cipher_msg *wd_cipher_get_msg(__u32 idx, __u32 tag);
 
 #ifdef WD_STATIC_DRV
 #define WD_CIPHER_SET_DRIVER(drv)					      \
diff --git a/include/drv/wd_digest_drv.h b/include/drv/wd_digest_drv.h
index 10ce6e1..39839f6 100644
--- a/include/drv/wd_digest_drv.h
+++ b/include/drv/wd_digest_drv.h
@@ -64,6 +64,7 @@ struct wd_digest_driver {
 
 void wd_digest_set_driver(struct wd_digest_driver *drv);
 struct wd_digest_driver *wd_digest_get_driver(void);
+struct wd_digest_msg *wd_digest_get_msg(__u32 idx, __u32 tag);
 
 #ifdef WD_STATIC_DRV
 #define WD_DIGEST_SET_DRIVER(drv)					      \
diff --git a/wd_aead.c b/wd_aead.c
index 0c54de3..d43ace1 100644
--- a/wd_aead.c
+++ b/wd_aead.c
@@ -596,6 +596,11 @@ fail_with_msg:
 	return ret;
 }
 
+struct wd_aead_msg *wd_aead_get_msg(__u32 idx, __u32 tag)
+{
+	return wd_find_msg_in_pool(&wd_aead_setting.pool, idx, tag);
+}
+
 int wd_aead_poll_ctx(__u32 idx, __u32 expt, __u32 *count)
 {
 	struct wd_ctx_config_internal *config = &wd_aead_setting.config;
diff --git a/wd_cipher.c b/wd_cipher.c
index 0cd2e42..3d00598 100644
--- a/wd_cipher.c
+++ b/wd_cipher.c
@@ -505,6 +505,11 @@ fail_with_msg:
 	return ret;
 }
 
+struct wd_cipher_msg *wd_cipher_get_msg(__u32 idx, __u32 tag)
+{
+	return wd_find_msg_in_pool(&wd_cipher_setting.pool, idx, tag);
+}
+
 int wd_cipher_poll_ctx(__u32 idx, __u32 expt, __u32 *count)
 {
 	struct wd_ctx_config_internal *config = &wd_cipher_setting.config;
diff --git a/wd_digest.c b/wd_digest.c
index ae37e32..43b4bc5 100644
--- a/wd_digest.c
+++ b/wd_digest.c
@@ -405,6 +405,11 @@ fail_with_msg:
 	return ret;
 }
 
+struct wd_digest_msg *wd_digest_get_msg(__u32 idx, __u32 tag)
+{
+	return wd_find_msg_in_pool(&wd_digest_setting.pool, idx, tag);
+}
+
 int wd_digest_poll_ctx(__u32 idx, __u32 expt, __u32 *count)
 {
 	struct wd_ctx_config_internal *config = &wd_digest_setting.config;
-- 
2.27.0

