From: Chenghai Huang <huangchenghai2@huawei.com> When decompressing the last block of data in stream mode, there is a possibility that the input data is fully consumed with insufficient output space, but the stream end flag is not returned. Therefore, when the tail packet data is fully consumed, check if the hardware status is 0x2. If it is 0x2, notify the user to send a request with a zero input size to flush the remaining data in the hardware. Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Zongyu Wu <wuzongyu1@huawei.com> --- drv/hisi_comp.c | 7 +++++++ v1/drv/hisi_zip_udrv.c | 9 +++++++++ v1/drv/hisi_zip_udrv.h | 1 + 3 files changed, 17 insertions(+) diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c index 4dc0c6a..bcc4f17 100644 --- a/drv/hisi_comp.c +++ b/drv/hisi_comp.c @@ -49,12 +49,14 @@ #define LITLEN_OVERFLOW_POS_MASK 0xffffff #define HZ_DECOMP_NO_SPACE 0x01 +#define HZ_DECOMPING_NO_SPACE 0x02 #define HZ_DECOMP_BLK_NOSTART 0x03 #define HZ_NEGACOMPRESS 0x0d #define HZ_CRC_ERR 0x10 #define HZ_DECOMP_END 0x13 #define HZ_CTX_ST_MASK 0x000f +#define HZ_CTX_BFINAL_MASK 0x80 #define HZ_LSTBLK_MASK 0x0100 #define HZ_STATUS_MASK 0xff #define HZ_REQ_TYPE_MASK 0xff @@ -1591,6 +1593,11 @@ 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; + /* last block no space when decomping, need resend null size req */ + if (ctx_st == HZ_DECOMPING_NO_SPACE && recv_msg->req.src_len == recv_msg->in_cons && + (sqe->ctx_dw0 & HZ_CTX_BFINAL_MASK)) + recv_msg->req.status = WD_EAGAIN; + /* * It need to analysis the data cache by hardware. * If the cache data is a complete huffman block, diff --git a/v1/drv/hisi_zip_udrv.c b/v1/drv/hisi_zip_udrv.c index 3045e48..4e5ed80 100644 --- a/v1/drv/hisi_zip_udrv.c +++ b/v1/drv/hisi_zip_udrv.c @@ -49,6 +49,7 @@ #define HW_UNCOMP_DIF_CHECK_ERR 0x12 #define HW_DECOMP_NO_SPACE 0x01 +#define HW_DECOMPING_NO_SPACE 0x02 #define HW_DECOMP_BLK_NOSTART 0x03 #define HW_DECOMP_NO_CRC 0x04 #define ZIP_DIF_LEN 8 @@ -388,6 +389,7 @@ int qm_parse_zip_sqe(void *hw_msg, const struct qm_queue_info *info, { struct wcrypto_comp_msg *recv_msg = info->req_cache[i]; struct hisi_zip_sqe *sqe = hw_msg; + __u16 ctx_bfinal = sqe->ctx_dw0 & HZ_CTX_BFINAL_MASK; __u16 ctx_st = sqe->ctx_dw0 & HZ_CTX_ST_MASK; __u16 lstblk = sqe->dw3 & HZ_LSTBLK_MASK; __u32 status = sqe->dw3 & HZ_STATUS_MASK; @@ -437,6 +439,9 @@ int qm_parse_zip_sqe(void *hw_msg, const struct qm_queue_info *info, info->sqe_parse_priv(sqe, WCRYPTO_COMP, tag->priv); qm_parse_zip_sqe_set_status(recv_msg, status, lstblk, ctx_st); + if (ctx_st == HW_DECOMPING_NO_SPACE && recv_msg->in_size == recv_msg->in_cons && + ctx_bfinal) + recv_msg->status = WCRYPTO_DECOMP_END_NOSPACE; return 1; } @@ -841,6 +846,7 @@ int qm_parse_zip_sqe_v3(void *hw_msg, const struct qm_queue_info *info, { struct wcrypto_comp_msg *recv_msg = info->req_cache[i]; struct hisi_zip_sqe_v3 *sqe = hw_msg; + __u16 ctx_bfinal = sqe->ctx_dw0 & HZ_CTX_BFINAL_MASK; __u32 ctx_win_len = sqe->ctx_dw2 & CTX_WIN_LEN_MASK; __u16 ctx_st = sqe->ctx_dw0 & HZ_CTX_ST_MASK; __u16 lstblk = sqe->dw3 & HZ_LSTBLK_MASK; @@ -900,6 +906,9 @@ int qm_parse_zip_sqe_v3(void *hw_msg, const struct qm_queue_info *info, } qm_parse_zip_sqe_set_status(recv_msg, status, lstblk, ctx_st); + if (ctx_st == HW_DECOMPING_NO_SPACE && recv_msg->in_size == recv_msg->in_cons && + ctx_bfinal) + recv_msg->status = WCRYPTO_DECOMP_END_NOSPACE; /* * It need to analysis the data cache by hardware. diff --git a/v1/drv/hisi_zip_udrv.h b/v1/drv/hisi_zip_udrv.h index c93b01a..28a9c0f 100644 --- a/v1/drv/hisi_zip_udrv.h +++ b/v1/drv/hisi_zip_udrv.h @@ -120,6 +120,7 @@ struct hisi_zip_sqe_v3 { #define HZ_REF_VTYPE_SHIFT 12 #define HZ_BLK_SIZE_SHIFT 16 #define HZ_CTX_ST_MASK 0x000f +#define HZ_CTX_BFINAL_MASK 0x80 #define HZ_LSTBLK_MASK 0x0100 #define HZ_STATUS_MASK 0xff #define HZ_REQ_TYPE_MASK 0xff -- 2.33.0