18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright (c) 2019 HiSilicon Limited. */ 38c2ecf20Sopenharmony_ci#include <crypto/internal/acompress.h> 48c2ecf20Sopenharmony_ci#include <linux/bitfield.h> 58c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 68c2ecf20Sopenharmony_ci#include <linux/scatterlist.h> 78c2ecf20Sopenharmony_ci#include "zip.h" 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci/* hisi_zip_sqe dw3 */ 108c2ecf20Sopenharmony_ci#define HZIP_BD_STATUS_M GENMASK(7, 0) 118c2ecf20Sopenharmony_ci/* hisi_zip_sqe dw7 */ 128c2ecf20Sopenharmony_ci#define HZIP_IN_SGE_DATA_OFFSET_M GENMASK(23, 0) 138c2ecf20Sopenharmony_ci/* hisi_zip_sqe dw8 */ 148c2ecf20Sopenharmony_ci#define HZIP_OUT_SGE_DATA_OFFSET_M GENMASK(23, 0) 158c2ecf20Sopenharmony_ci/* hisi_zip_sqe dw9 */ 168c2ecf20Sopenharmony_ci#define HZIP_REQ_TYPE_M GENMASK(7, 0) 178c2ecf20Sopenharmony_ci#define HZIP_ALG_TYPE_ZLIB 0x02 188c2ecf20Sopenharmony_ci#define HZIP_ALG_TYPE_GZIP 0x03 198c2ecf20Sopenharmony_ci#define HZIP_BUF_TYPE_M GENMASK(11, 8) 208c2ecf20Sopenharmony_ci#define HZIP_PBUFFER 0x0 218c2ecf20Sopenharmony_ci#define HZIP_SGL 0x1 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define HZIP_ZLIB_HEAD_SIZE 2 248c2ecf20Sopenharmony_ci#define HZIP_GZIP_HEAD_SIZE 10 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define GZIP_HEAD_FHCRC_BIT BIT(1) 278c2ecf20Sopenharmony_ci#define GZIP_HEAD_FEXTRA_BIT BIT(2) 288c2ecf20Sopenharmony_ci#define GZIP_HEAD_FNAME_BIT BIT(3) 298c2ecf20Sopenharmony_ci#define GZIP_HEAD_FCOMMENT_BIT BIT(4) 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define GZIP_HEAD_FLG_SHIFT 3 328c2ecf20Sopenharmony_ci#define GZIP_HEAD_FEXTRA_SHIFT 10 338c2ecf20Sopenharmony_ci#define GZIP_HEAD_FEXTRA_XLEN 2UL 348c2ecf20Sopenharmony_ci#define GZIP_HEAD_FHCRC_SIZE 2 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define HZIP_GZIP_HEAD_BUF 256 378c2ecf20Sopenharmony_ci#define HZIP_ALG_PRIORITY 300 388c2ecf20Sopenharmony_ci#define HZIP_SGL_SGE_NR 10 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic const u8 zlib_head[HZIP_ZLIB_HEAD_SIZE] = {0x78, 0x9c}; 418c2ecf20Sopenharmony_cistatic const u8 gzip_head[HZIP_GZIP_HEAD_SIZE] = { 428c2ecf20Sopenharmony_ci 0x1f, 0x8b, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x03 438c2ecf20Sopenharmony_ci}; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cienum hisi_zip_alg_type { 468c2ecf20Sopenharmony_ci HZIP_ALG_TYPE_COMP = 0, 478c2ecf20Sopenharmony_ci HZIP_ALG_TYPE_DECOMP = 1, 488c2ecf20Sopenharmony_ci}; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cienum { 518c2ecf20Sopenharmony_ci HZIP_QPC_COMP, 528c2ecf20Sopenharmony_ci HZIP_QPC_DECOMP, 538c2ecf20Sopenharmony_ci HZIP_CTX_Q_NUM 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#define COMP_NAME_TO_TYPE(alg_name) \ 578c2ecf20Sopenharmony_ci (!strcmp((alg_name), "zlib-deflate") ? HZIP_ALG_TYPE_ZLIB : \ 588c2ecf20Sopenharmony_ci !strcmp((alg_name), "gzip") ? HZIP_ALG_TYPE_GZIP : 0) \ 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#define TO_HEAD_SIZE(req_type) \ 618c2ecf20Sopenharmony_ci (((req_type) == HZIP_ALG_TYPE_ZLIB) ? sizeof(zlib_head) : \ 628c2ecf20Sopenharmony_ci ((req_type) == HZIP_ALG_TYPE_GZIP) ? sizeof(gzip_head) : 0) \ 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#define TO_HEAD(req_type) \ 658c2ecf20Sopenharmony_ci (((req_type) == HZIP_ALG_TYPE_ZLIB) ? zlib_head : \ 668c2ecf20Sopenharmony_ci ((req_type) == HZIP_ALG_TYPE_GZIP) ? gzip_head : NULL) \ 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistruct hisi_zip_req { 698c2ecf20Sopenharmony_ci struct acomp_req *req; 708c2ecf20Sopenharmony_ci u32 sskip; 718c2ecf20Sopenharmony_ci u32 dskip; 728c2ecf20Sopenharmony_ci struct hisi_acc_hw_sgl *hw_src; 738c2ecf20Sopenharmony_ci struct hisi_acc_hw_sgl *hw_dst; 748c2ecf20Sopenharmony_ci dma_addr_t dma_src; 758c2ecf20Sopenharmony_ci dma_addr_t dma_dst; 768c2ecf20Sopenharmony_ci u16 req_id; 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistruct hisi_zip_req_q { 808c2ecf20Sopenharmony_ci struct hisi_zip_req *q; 818c2ecf20Sopenharmony_ci unsigned long *req_bitmap; 828c2ecf20Sopenharmony_ci rwlock_t req_lock; 838c2ecf20Sopenharmony_ci u16 size; 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistruct hisi_zip_qp_ctx { 878c2ecf20Sopenharmony_ci struct hisi_qp *qp; 888c2ecf20Sopenharmony_ci struct hisi_zip_req_q req_q; 898c2ecf20Sopenharmony_ci struct hisi_acc_sgl_pool *sgl_pool; 908c2ecf20Sopenharmony_ci struct hisi_zip *zip_dev; 918c2ecf20Sopenharmony_ci struct hisi_zip_ctx *ctx; 928c2ecf20Sopenharmony_ci}; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cistruct hisi_zip_ctx { 958c2ecf20Sopenharmony_ci struct hisi_zip_qp_ctx qp_ctx[HZIP_CTX_Q_NUM]; 968c2ecf20Sopenharmony_ci}; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic int sgl_sge_nr_set(const char *val, const struct kernel_param *kp) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci int ret; 1018c2ecf20Sopenharmony_ci u16 n; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci if (!val) 1048c2ecf20Sopenharmony_ci return -EINVAL; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci ret = kstrtou16(val, 10, &n); 1078c2ecf20Sopenharmony_ci if (ret || n == 0 || n > HISI_ACC_SGL_SGE_NR_MAX) 1088c2ecf20Sopenharmony_ci return -EINVAL; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci return param_set_ushort(val, kp); 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic const struct kernel_param_ops sgl_sge_nr_ops = { 1148c2ecf20Sopenharmony_ci .set = sgl_sge_nr_set, 1158c2ecf20Sopenharmony_ci .get = param_get_ushort, 1168c2ecf20Sopenharmony_ci}; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistatic u16 sgl_sge_nr = HZIP_SGL_SGE_NR; 1198c2ecf20Sopenharmony_cimodule_param_cb(sgl_sge_nr, &sgl_sge_nr_ops, &sgl_sge_nr, 0444); 1208c2ecf20Sopenharmony_ciMODULE_PARM_DESC(sgl_sge_nr, "Number of sge in sgl(1-255)"); 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistatic void hisi_zip_config_buf_type(struct hisi_zip_sqe *sqe, u8 buf_type) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci u32 val; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci val = (sqe->dw9) & ~HZIP_BUF_TYPE_M; 1278c2ecf20Sopenharmony_ci val |= FIELD_PREP(HZIP_BUF_TYPE_M, buf_type); 1288c2ecf20Sopenharmony_ci sqe->dw9 = val; 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic void hisi_zip_config_tag(struct hisi_zip_sqe *sqe, u32 tag) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci sqe->tag = tag; 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type, 1378c2ecf20Sopenharmony_ci dma_addr_t s_addr, dma_addr_t d_addr, u32 slen, 1388c2ecf20Sopenharmony_ci u32 dlen, u32 sskip, u32 dskip) 1398c2ecf20Sopenharmony_ci{ 1408c2ecf20Sopenharmony_ci memset(sqe, 0, sizeof(struct hisi_zip_sqe)); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci sqe->input_data_length = slen - sskip; 1438c2ecf20Sopenharmony_ci sqe->dw7 = FIELD_PREP(HZIP_IN_SGE_DATA_OFFSET_M, sskip); 1448c2ecf20Sopenharmony_ci sqe->dw8 = FIELD_PREP(HZIP_OUT_SGE_DATA_OFFSET_M, dskip); 1458c2ecf20Sopenharmony_ci sqe->dw9 = FIELD_PREP(HZIP_REQ_TYPE_M, req_type); 1468c2ecf20Sopenharmony_ci sqe->dest_avail_out = dlen - dskip; 1478c2ecf20Sopenharmony_ci sqe->source_addr_l = lower_32_bits(s_addr); 1488c2ecf20Sopenharmony_ci sqe->source_addr_h = upper_32_bits(s_addr); 1498c2ecf20Sopenharmony_ci sqe->dest_addr_l = lower_32_bits(d_addr); 1508c2ecf20Sopenharmony_ci sqe->dest_addr_h = upper_32_bits(d_addr); 1518c2ecf20Sopenharmony_ci} 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_cistatic int hisi_zip_start_qp(struct hisi_qp *qp, struct hisi_zip_qp_ctx *ctx, 1548c2ecf20Sopenharmony_ci int alg_type, int req_type) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci struct device *dev = &qp->qm->pdev->dev; 1578c2ecf20Sopenharmony_ci int ret; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci qp->req_type = req_type; 1608c2ecf20Sopenharmony_ci qp->alg_type = alg_type; 1618c2ecf20Sopenharmony_ci qp->qp_ctx = ctx; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci ret = hisi_qm_start_qp(qp, 0); 1648c2ecf20Sopenharmony_ci if (ret < 0) { 1658c2ecf20Sopenharmony_ci dev_err(dev, "failed to start qp (%d)!\n", ret); 1668c2ecf20Sopenharmony_ci return ret; 1678c2ecf20Sopenharmony_ci } 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci ctx->qp = qp; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci return 0; 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_cistatic void hisi_zip_release_qp(struct hisi_zip_qp_ctx *ctx) 1758c2ecf20Sopenharmony_ci{ 1768c2ecf20Sopenharmony_ci hisi_qm_stop_qp(ctx->qp); 1778c2ecf20Sopenharmony_ci hisi_qm_release_qp(ctx->qp); 1788c2ecf20Sopenharmony_ci} 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistatic int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type, int node) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci struct hisi_qp *qps[HZIP_CTX_Q_NUM] = { NULL }; 1838c2ecf20Sopenharmony_ci struct hisi_zip *hisi_zip; 1848c2ecf20Sopenharmony_ci int ret, i, j; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci ret = zip_create_qps(qps, HZIP_CTX_Q_NUM, node); 1878c2ecf20Sopenharmony_ci if (ret) { 1888c2ecf20Sopenharmony_ci pr_err("failed to create zip qps (%d)!\n", ret); 1898c2ecf20Sopenharmony_ci return -ENODEV; 1908c2ecf20Sopenharmony_ci } 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci hisi_zip = container_of(qps[0]->qm, struct hisi_zip, qm); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci for (i = 0; i < HZIP_CTX_Q_NUM; i++) { 1958c2ecf20Sopenharmony_ci /* alg_type = 0 for compress, 1 for decompress in hw sqe */ 1968c2ecf20Sopenharmony_ci ret = hisi_zip_start_qp(qps[i], &hisi_zip_ctx->qp_ctx[i], i, 1978c2ecf20Sopenharmony_ci req_type); 1988c2ecf20Sopenharmony_ci if (ret) { 1998c2ecf20Sopenharmony_ci for (j = i - 1; j >= 0; j--) 2008c2ecf20Sopenharmony_ci hisi_qm_stop_qp(hisi_zip_ctx->qp_ctx[j].qp); 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci hisi_qm_free_qps(qps, HZIP_CTX_Q_NUM); 2038c2ecf20Sopenharmony_ci return ret; 2048c2ecf20Sopenharmony_ci } 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci hisi_zip_ctx->qp_ctx[i].zip_dev = hisi_zip; 2078c2ecf20Sopenharmony_ci } 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci return 0; 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic void hisi_zip_ctx_exit(struct hisi_zip_ctx *hisi_zip_ctx) 2138c2ecf20Sopenharmony_ci{ 2148c2ecf20Sopenharmony_ci int i; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci for (i = 1; i >= 0; i--) 2178c2ecf20Sopenharmony_ci hisi_zip_release_qp(&hisi_zip_ctx->qp_ctx[i]); 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic u16 get_extra_field_size(const u8 *start) 2218c2ecf20Sopenharmony_ci{ 2228c2ecf20Sopenharmony_ci return *((u16 *)start) + GZIP_HEAD_FEXTRA_XLEN; 2238c2ecf20Sopenharmony_ci} 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic u32 get_name_field_size(const u8 *start) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci return strlen(start) + 1; 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic u32 get_comment_field_size(const u8 *start) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci return strlen(start) + 1; 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic u32 __get_gzip_head_size(const u8 *src) 2368c2ecf20Sopenharmony_ci{ 2378c2ecf20Sopenharmony_ci u8 head_flg = *(src + GZIP_HEAD_FLG_SHIFT); 2388c2ecf20Sopenharmony_ci u32 size = GZIP_HEAD_FEXTRA_SHIFT; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci if (head_flg & GZIP_HEAD_FEXTRA_BIT) 2418c2ecf20Sopenharmony_ci size += get_extra_field_size(src + size); 2428c2ecf20Sopenharmony_ci if (head_flg & GZIP_HEAD_FNAME_BIT) 2438c2ecf20Sopenharmony_ci size += get_name_field_size(src + size); 2448c2ecf20Sopenharmony_ci if (head_flg & GZIP_HEAD_FCOMMENT_BIT) 2458c2ecf20Sopenharmony_ci size += get_comment_field_size(src + size); 2468c2ecf20Sopenharmony_ci if (head_flg & GZIP_HEAD_FHCRC_BIT) 2478c2ecf20Sopenharmony_ci size += GZIP_HEAD_FHCRC_SIZE; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci return size; 2508c2ecf20Sopenharmony_ci} 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic int hisi_zip_create_req_q(struct hisi_zip_ctx *ctx) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci struct hisi_zip_req_q *req_q; 2558c2ecf20Sopenharmony_ci int i, ret; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci for (i = 0; i < HZIP_CTX_Q_NUM; i++) { 2588c2ecf20Sopenharmony_ci req_q = &ctx->qp_ctx[i].req_q; 2598c2ecf20Sopenharmony_ci req_q->size = QM_Q_DEPTH; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci req_q->req_bitmap = kcalloc(BITS_TO_LONGS(req_q->size), 2628c2ecf20Sopenharmony_ci sizeof(long), GFP_KERNEL); 2638c2ecf20Sopenharmony_ci if (!req_q->req_bitmap) { 2648c2ecf20Sopenharmony_ci ret = -ENOMEM; 2658c2ecf20Sopenharmony_ci if (i == 0) 2668c2ecf20Sopenharmony_ci return ret; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci goto err_free_loop0; 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci rwlock_init(&req_q->req_lock); 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci req_q->q = kcalloc(req_q->size, sizeof(struct hisi_zip_req), 2738c2ecf20Sopenharmony_ci GFP_KERNEL); 2748c2ecf20Sopenharmony_ci if (!req_q->q) { 2758c2ecf20Sopenharmony_ci ret = -ENOMEM; 2768c2ecf20Sopenharmony_ci if (i == 0) 2778c2ecf20Sopenharmony_ci goto err_free_bitmap; 2788c2ecf20Sopenharmony_ci else 2798c2ecf20Sopenharmony_ci goto err_free_loop1; 2808c2ecf20Sopenharmony_ci } 2818c2ecf20Sopenharmony_ci } 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci return 0; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_cierr_free_loop1: 2868c2ecf20Sopenharmony_ci kfree(ctx->qp_ctx[HZIP_QPC_DECOMP].req_q.req_bitmap); 2878c2ecf20Sopenharmony_cierr_free_loop0: 2888c2ecf20Sopenharmony_ci kfree(ctx->qp_ctx[HZIP_QPC_COMP].req_q.q); 2898c2ecf20Sopenharmony_cierr_free_bitmap: 2908c2ecf20Sopenharmony_ci kfree(ctx->qp_ctx[HZIP_QPC_COMP].req_q.req_bitmap); 2918c2ecf20Sopenharmony_ci return ret; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistatic void hisi_zip_release_req_q(struct hisi_zip_ctx *ctx) 2958c2ecf20Sopenharmony_ci{ 2968c2ecf20Sopenharmony_ci int i; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci for (i = 0; i < HZIP_CTX_Q_NUM; i++) { 2998c2ecf20Sopenharmony_ci kfree(ctx->qp_ctx[i].req_q.q); 3008c2ecf20Sopenharmony_ci kfree(ctx->qp_ctx[i].req_q.req_bitmap); 3018c2ecf20Sopenharmony_ci } 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic int hisi_zip_create_sgl_pool(struct hisi_zip_ctx *ctx) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci struct hisi_zip_qp_ctx *tmp; 3078c2ecf20Sopenharmony_ci struct device *dev; 3088c2ecf20Sopenharmony_ci int i; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci for (i = 0; i < HZIP_CTX_Q_NUM; i++) { 3118c2ecf20Sopenharmony_ci tmp = &ctx->qp_ctx[i]; 3128c2ecf20Sopenharmony_ci dev = &tmp->qp->qm->pdev->dev; 3138c2ecf20Sopenharmony_ci tmp->sgl_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH << 1, 3148c2ecf20Sopenharmony_ci sgl_sge_nr); 3158c2ecf20Sopenharmony_ci if (IS_ERR(tmp->sgl_pool)) { 3168c2ecf20Sopenharmony_ci if (i == 1) 3178c2ecf20Sopenharmony_ci goto err_free_sgl_pool0; 3188c2ecf20Sopenharmony_ci return -ENOMEM; 3198c2ecf20Sopenharmony_ci } 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci return 0; 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_cierr_free_sgl_pool0: 3258c2ecf20Sopenharmony_ci hisi_acc_free_sgl_pool(&ctx->qp_ctx[HZIP_QPC_COMP].qp->qm->pdev->dev, 3268c2ecf20Sopenharmony_ci ctx->qp_ctx[HZIP_QPC_COMP].sgl_pool); 3278c2ecf20Sopenharmony_ci return -ENOMEM; 3288c2ecf20Sopenharmony_ci} 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_cistatic void hisi_zip_release_sgl_pool(struct hisi_zip_ctx *ctx) 3318c2ecf20Sopenharmony_ci{ 3328c2ecf20Sopenharmony_ci int i; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci for (i = 0; i < HZIP_CTX_Q_NUM; i++) 3358c2ecf20Sopenharmony_ci hisi_acc_free_sgl_pool(&ctx->qp_ctx[i].qp->qm->pdev->dev, 3368c2ecf20Sopenharmony_ci ctx->qp_ctx[i].sgl_pool); 3378c2ecf20Sopenharmony_ci} 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_cistatic void hisi_zip_remove_req(struct hisi_zip_qp_ctx *qp_ctx, 3408c2ecf20Sopenharmony_ci struct hisi_zip_req *req) 3418c2ecf20Sopenharmony_ci{ 3428c2ecf20Sopenharmony_ci struct hisi_zip_req_q *req_q = &qp_ctx->req_q; 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci write_lock(&req_q->req_lock); 3458c2ecf20Sopenharmony_ci clear_bit(req->req_id, req_q->req_bitmap); 3468c2ecf20Sopenharmony_ci memset(req, 0, sizeof(struct hisi_zip_req)); 3478c2ecf20Sopenharmony_ci write_unlock(&req_q->req_lock); 3488c2ecf20Sopenharmony_ci} 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_cistatic void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data) 3518c2ecf20Sopenharmony_ci{ 3528c2ecf20Sopenharmony_ci struct hisi_zip_sqe *sqe = data; 3538c2ecf20Sopenharmony_ci struct hisi_zip_qp_ctx *qp_ctx = qp->qp_ctx; 3548c2ecf20Sopenharmony_ci struct hisi_zip_dfx *dfx = &qp_ctx->zip_dev->dfx; 3558c2ecf20Sopenharmony_ci struct hisi_zip_req_q *req_q = &qp_ctx->req_q; 3568c2ecf20Sopenharmony_ci struct hisi_zip_req *req = req_q->q + sqe->tag; 3578c2ecf20Sopenharmony_ci struct acomp_req *acomp_req = req->req; 3588c2ecf20Sopenharmony_ci struct device *dev = &qp->qm->pdev->dev; 3598c2ecf20Sopenharmony_ci u32 status, dlen, head_size; 3608c2ecf20Sopenharmony_ci int err = 0; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci atomic64_inc(&dfx->recv_cnt); 3638c2ecf20Sopenharmony_ci status = sqe->dw3 & HZIP_BD_STATUS_M; 3648c2ecf20Sopenharmony_ci if (status != 0 && status != HZIP_NC_ERR) { 3658c2ecf20Sopenharmony_ci dev_err(dev, "%scompress fail in qp%u: %u, output: %u\n", 3668c2ecf20Sopenharmony_ci (qp->alg_type == 0) ? "" : "de", qp->qp_id, status, 3678c2ecf20Sopenharmony_ci sqe->produced); 3688c2ecf20Sopenharmony_ci atomic64_inc(&dfx->err_bd_cnt); 3698c2ecf20Sopenharmony_ci err = -EIO; 3708c2ecf20Sopenharmony_ci } 3718c2ecf20Sopenharmony_ci dlen = sqe->produced; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci hisi_acc_sg_buf_unmap(dev, acomp_req->src, req->hw_src); 3748c2ecf20Sopenharmony_ci hisi_acc_sg_buf_unmap(dev, acomp_req->dst, req->hw_dst); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci head_size = (qp->alg_type == 0) ? TO_HEAD_SIZE(qp->req_type) : 0; 3778c2ecf20Sopenharmony_ci acomp_req->dlen = dlen + head_size; 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci if (acomp_req->base.complete) 3808c2ecf20Sopenharmony_ci acomp_request_complete(acomp_req, err); 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci hisi_zip_remove_req(qp_ctx, req); 3838c2ecf20Sopenharmony_ci} 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_cistatic void hisi_zip_set_acomp_cb(struct hisi_zip_ctx *ctx, 3868c2ecf20Sopenharmony_ci void (*fn)(struct hisi_qp *, void *)) 3878c2ecf20Sopenharmony_ci{ 3888c2ecf20Sopenharmony_ci int i; 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci for (i = 0; i < HZIP_CTX_Q_NUM; i++) 3918c2ecf20Sopenharmony_ci ctx->qp_ctx[i].qp->req_cb = fn; 3928c2ecf20Sopenharmony_ci} 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_cistatic int hisi_zip_acomp_init(struct crypto_acomp *tfm) 3958c2ecf20Sopenharmony_ci{ 3968c2ecf20Sopenharmony_ci const char *alg_name = crypto_tfm_alg_name(&tfm->base); 3978c2ecf20Sopenharmony_ci struct hisi_zip_ctx *ctx = crypto_tfm_ctx(&tfm->base); 3988c2ecf20Sopenharmony_ci struct device *dev; 3998c2ecf20Sopenharmony_ci int ret; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci ret = hisi_zip_ctx_init(ctx, COMP_NAME_TO_TYPE(alg_name), tfm->base.node); 4028c2ecf20Sopenharmony_ci if (ret) { 4038c2ecf20Sopenharmony_ci pr_err("failed to init ctx (%d)!\n", ret); 4048c2ecf20Sopenharmony_ci return ret; 4058c2ecf20Sopenharmony_ci } 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci dev = &ctx->qp_ctx[0].qp->qm->pdev->dev; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci ret = hisi_zip_create_req_q(ctx); 4108c2ecf20Sopenharmony_ci if (ret) { 4118c2ecf20Sopenharmony_ci dev_err(dev, "failed to create request queue (%d)!\n", ret); 4128c2ecf20Sopenharmony_ci goto err_ctx_exit; 4138c2ecf20Sopenharmony_ci } 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci ret = hisi_zip_create_sgl_pool(ctx); 4168c2ecf20Sopenharmony_ci if (ret) { 4178c2ecf20Sopenharmony_ci dev_err(dev, "failed to create sgl pool (%d)!\n", ret); 4188c2ecf20Sopenharmony_ci goto err_release_req_q; 4198c2ecf20Sopenharmony_ci } 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci hisi_zip_set_acomp_cb(ctx, hisi_zip_acomp_cb); 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci return 0; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_cierr_release_req_q: 4268c2ecf20Sopenharmony_ci hisi_zip_release_req_q(ctx); 4278c2ecf20Sopenharmony_cierr_ctx_exit: 4288c2ecf20Sopenharmony_ci hisi_zip_ctx_exit(ctx); 4298c2ecf20Sopenharmony_ci return ret; 4308c2ecf20Sopenharmony_ci} 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_cistatic void hisi_zip_acomp_exit(struct crypto_acomp *tfm) 4338c2ecf20Sopenharmony_ci{ 4348c2ecf20Sopenharmony_ci struct hisi_zip_ctx *ctx = crypto_tfm_ctx(&tfm->base); 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci hisi_zip_set_acomp_cb(ctx, NULL); 4378c2ecf20Sopenharmony_ci hisi_zip_release_sgl_pool(ctx); 4388c2ecf20Sopenharmony_ci hisi_zip_release_req_q(ctx); 4398c2ecf20Sopenharmony_ci hisi_zip_ctx_exit(ctx); 4408c2ecf20Sopenharmony_ci} 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_cistatic int add_comp_head(struct scatterlist *dst, u8 req_type) 4438c2ecf20Sopenharmony_ci{ 4448c2ecf20Sopenharmony_ci int head_size = TO_HEAD_SIZE(req_type); 4458c2ecf20Sopenharmony_ci const u8 *head = TO_HEAD(req_type); 4468c2ecf20Sopenharmony_ci int ret; 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ci ret = sg_copy_from_buffer(dst, sg_nents(dst), head, head_size); 4498c2ecf20Sopenharmony_ci if (ret != head_size) { 4508c2ecf20Sopenharmony_ci pr_err("the head size of buffer is wrong (%d)!\n", ret); 4518c2ecf20Sopenharmony_ci return -ENOMEM; 4528c2ecf20Sopenharmony_ci } 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci return head_size; 4558c2ecf20Sopenharmony_ci} 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_cistatic size_t __maybe_unused get_gzip_head_size(struct scatterlist *sgl) 4588c2ecf20Sopenharmony_ci{ 4598c2ecf20Sopenharmony_ci char buf[HZIP_GZIP_HEAD_BUF]; 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci sg_copy_to_buffer(sgl, sg_nents(sgl), buf, sizeof(buf)); 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci return __get_gzip_head_size(buf); 4648c2ecf20Sopenharmony_ci} 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_cistatic int get_comp_head_size(struct acomp_req *acomp_req, u8 req_type) 4678c2ecf20Sopenharmony_ci{ 4688c2ecf20Sopenharmony_ci if (!acomp_req->src || !acomp_req->slen) 4698c2ecf20Sopenharmony_ci return -EINVAL; 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci if ((req_type == HZIP_ALG_TYPE_GZIP) && 4728c2ecf20Sopenharmony_ci (acomp_req->slen < GZIP_HEAD_FEXTRA_SHIFT)) 4738c2ecf20Sopenharmony_ci return -EINVAL; 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci switch (req_type) { 4768c2ecf20Sopenharmony_ci case HZIP_ALG_TYPE_ZLIB: 4778c2ecf20Sopenharmony_ci return TO_HEAD_SIZE(HZIP_ALG_TYPE_ZLIB); 4788c2ecf20Sopenharmony_ci case HZIP_ALG_TYPE_GZIP: 4798c2ecf20Sopenharmony_ci return TO_HEAD_SIZE(HZIP_ALG_TYPE_GZIP); 4808c2ecf20Sopenharmony_ci default: 4818c2ecf20Sopenharmony_ci pr_err("request type does not support!\n"); 4828c2ecf20Sopenharmony_ci return -EINVAL; 4838c2ecf20Sopenharmony_ci } 4848c2ecf20Sopenharmony_ci} 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_cistatic struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req, 4878c2ecf20Sopenharmony_ci struct hisi_zip_qp_ctx *qp_ctx, 4888c2ecf20Sopenharmony_ci size_t head_size, bool is_comp) 4898c2ecf20Sopenharmony_ci{ 4908c2ecf20Sopenharmony_ci struct hisi_zip_req_q *req_q = &qp_ctx->req_q; 4918c2ecf20Sopenharmony_ci struct hisi_zip_req *q = req_q->q; 4928c2ecf20Sopenharmony_ci struct hisi_zip_req *req_cache; 4938c2ecf20Sopenharmony_ci int req_id; 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci write_lock(&req_q->req_lock); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci req_id = find_first_zero_bit(req_q->req_bitmap, req_q->size); 4988c2ecf20Sopenharmony_ci if (req_id >= req_q->size) { 4998c2ecf20Sopenharmony_ci write_unlock(&req_q->req_lock); 5008c2ecf20Sopenharmony_ci dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n"); 5018c2ecf20Sopenharmony_ci return ERR_PTR(-EAGAIN); 5028c2ecf20Sopenharmony_ci } 5038c2ecf20Sopenharmony_ci set_bit(req_id, req_q->req_bitmap); 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci req_cache = q + req_id; 5068c2ecf20Sopenharmony_ci req_cache->req_id = req_id; 5078c2ecf20Sopenharmony_ci req_cache->req = req; 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci if (is_comp) { 5108c2ecf20Sopenharmony_ci req_cache->sskip = 0; 5118c2ecf20Sopenharmony_ci req_cache->dskip = head_size; 5128c2ecf20Sopenharmony_ci } else { 5138c2ecf20Sopenharmony_ci req_cache->sskip = head_size; 5148c2ecf20Sopenharmony_ci req_cache->dskip = 0; 5158c2ecf20Sopenharmony_ci } 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci write_unlock(&req_q->req_lock); 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci return req_cache; 5208c2ecf20Sopenharmony_ci} 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_cistatic int hisi_zip_do_work(struct hisi_zip_req *req, 5238c2ecf20Sopenharmony_ci struct hisi_zip_qp_ctx *qp_ctx) 5248c2ecf20Sopenharmony_ci{ 5258c2ecf20Sopenharmony_ci struct acomp_req *a_req = req->req; 5268c2ecf20Sopenharmony_ci struct hisi_qp *qp = qp_ctx->qp; 5278c2ecf20Sopenharmony_ci struct device *dev = &qp->qm->pdev->dev; 5288c2ecf20Sopenharmony_ci struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool; 5298c2ecf20Sopenharmony_ci struct hisi_zip_dfx *dfx = &qp_ctx->zip_dev->dfx; 5308c2ecf20Sopenharmony_ci struct hisi_zip_sqe zip_sqe; 5318c2ecf20Sopenharmony_ci dma_addr_t input, output; 5328c2ecf20Sopenharmony_ci int ret; 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci if (!a_req->src || !a_req->slen || !a_req->dst || !a_req->dlen) 5358c2ecf20Sopenharmony_ci return -EINVAL; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->src, pool, 5388c2ecf20Sopenharmony_ci req->req_id << 1, &input); 5398c2ecf20Sopenharmony_ci if (IS_ERR(req->hw_src)) { 5408c2ecf20Sopenharmony_ci dev_err(dev, "failed to map the src buffer to hw sgl (%ld)!\n", 5418c2ecf20Sopenharmony_ci PTR_ERR(req->hw_src)); 5428c2ecf20Sopenharmony_ci return PTR_ERR(req->hw_src); 5438c2ecf20Sopenharmony_ci } 5448c2ecf20Sopenharmony_ci req->dma_src = input; 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_ci req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->dst, pool, 5478c2ecf20Sopenharmony_ci (req->req_id << 1) + 1, 5488c2ecf20Sopenharmony_ci &output); 5498c2ecf20Sopenharmony_ci if (IS_ERR(req->hw_dst)) { 5508c2ecf20Sopenharmony_ci ret = PTR_ERR(req->hw_dst); 5518c2ecf20Sopenharmony_ci dev_err(dev, "failed to map the dst buffer to hw slg (%d)!\n", 5528c2ecf20Sopenharmony_ci ret); 5538c2ecf20Sopenharmony_ci goto err_unmap_input; 5548c2ecf20Sopenharmony_ci } 5558c2ecf20Sopenharmony_ci req->dma_dst = output; 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci hisi_zip_fill_sqe(&zip_sqe, qp->req_type, input, output, a_req->slen, 5588c2ecf20Sopenharmony_ci a_req->dlen, req->sskip, req->dskip); 5598c2ecf20Sopenharmony_ci hisi_zip_config_buf_type(&zip_sqe, HZIP_SGL); 5608c2ecf20Sopenharmony_ci hisi_zip_config_tag(&zip_sqe, req->req_id); 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci /* send command to start a task */ 5638c2ecf20Sopenharmony_ci atomic64_inc(&dfx->send_cnt); 5648c2ecf20Sopenharmony_ci ret = hisi_qp_send(qp, &zip_sqe); 5658c2ecf20Sopenharmony_ci if (ret < 0) { 5668c2ecf20Sopenharmony_ci atomic64_inc(&dfx->send_busy_cnt); 5678c2ecf20Sopenharmony_ci ret = -EAGAIN; 5688c2ecf20Sopenharmony_ci dev_dbg_ratelimited(dev, "failed to send request!\n"); 5698c2ecf20Sopenharmony_ci goto err_unmap_output; 5708c2ecf20Sopenharmony_ci } 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ci return -EINPROGRESS; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_cierr_unmap_output: 5758c2ecf20Sopenharmony_ci hisi_acc_sg_buf_unmap(dev, a_req->dst, req->hw_dst); 5768c2ecf20Sopenharmony_cierr_unmap_input: 5778c2ecf20Sopenharmony_ci hisi_acc_sg_buf_unmap(dev, a_req->src, req->hw_src); 5788c2ecf20Sopenharmony_ci return ret; 5798c2ecf20Sopenharmony_ci} 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_cistatic int hisi_zip_acompress(struct acomp_req *acomp_req) 5828c2ecf20Sopenharmony_ci{ 5838c2ecf20Sopenharmony_ci struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm); 5848c2ecf20Sopenharmony_ci struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[HZIP_QPC_COMP]; 5858c2ecf20Sopenharmony_ci struct device *dev = &qp_ctx->qp->qm->pdev->dev; 5868c2ecf20Sopenharmony_ci struct hisi_zip_req *req; 5878c2ecf20Sopenharmony_ci int head_size; 5888c2ecf20Sopenharmony_ci int ret; 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci /* let's output compression head now */ 5918c2ecf20Sopenharmony_ci head_size = add_comp_head(acomp_req->dst, qp_ctx->qp->req_type); 5928c2ecf20Sopenharmony_ci if (head_size < 0) { 5938c2ecf20Sopenharmony_ci dev_err_ratelimited(dev, "failed to add comp head (%d)!\n", 5948c2ecf20Sopenharmony_ci head_size); 5958c2ecf20Sopenharmony_ci return head_size; 5968c2ecf20Sopenharmony_ci } 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci req = hisi_zip_create_req(acomp_req, qp_ctx, head_size, true); 5998c2ecf20Sopenharmony_ci if (IS_ERR(req)) 6008c2ecf20Sopenharmony_ci return PTR_ERR(req); 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci ret = hisi_zip_do_work(req, qp_ctx); 6038c2ecf20Sopenharmony_ci if (ret != -EINPROGRESS) { 6048c2ecf20Sopenharmony_ci dev_info_ratelimited(dev, "failed to do compress (%d)!\n", ret); 6058c2ecf20Sopenharmony_ci hisi_zip_remove_req(qp_ctx, req); 6068c2ecf20Sopenharmony_ci } 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci return ret; 6098c2ecf20Sopenharmony_ci} 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_cistatic int hisi_zip_adecompress(struct acomp_req *acomp_req) 6128c2ecf20Sopenharmony_ci{ 6138c2ecf20Sopenharmony_ci struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm); 6148c2ecf20Sopenharmony_ci struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[HZIP_QPC_DECOMP]; 6158c2ecf20Sopenharmony_ci struct device *dev = &qp_ctx->qp->qm->pdev->dev; 6168c2ecf20Sopenharmony_ci struct hisi_zip_req *req; 6178c2ecf20Sopenharmony_ci int head_size, ret; 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_ci head_size = get_comp_head_size(acomp_req, qp_ctx->qp->req_type); 6208c2ecf20Sopenharmony_ci if (head_size < 0) { 6218c2ecf20Sopenharmony_ci dev_err_ratelimited(dev, "failed to get comp head size (%d)!\n", 6228c2ecf20Sopenharmony_ci head_size); 6238c2ecf20Sopenharmony_ci return head_size; 6248c2ecf20Sopenharmony_ci } 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_ci req = hisi_zip_create_req(acomp_req, qp_ctx, head_size, false); 6278c2ecf20Sopenharmony_ci if (IS_ERR(req)) 6288c2ecf20Sopenharmony_ci return PTR_ERR(req); 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci ret = hisi_zip_do_work(req, qp_ctx); 6318c2ecf20Sopenharmony_ci if (ret != -EINPROGRESS) { 6328c2ecf20Sopenharmony_ci dev_info_ratelimited(dev, "failed to do decompress (%d)!\n", 6338c2ecf20Sopenharmony_ci ret); 6348c2ecf20Sopenharmony_ci hisi_zip_remove_req(qp_ctx, req); 6358c2ecf20Sopenharmony_ci } 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci return ret; 6388c2ecf20Sopenharmony_ci} 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_cistatic struct acomp_alg hisi_zip_acomp_zlib = { 6418c2ecf20Sopenharmony_ci .init = hisi_zip_acomp_init, 6428c2ecf20Sopenharmony_ci .exit = hisi_zip_acomp_exit, 6438c2ecf20Sopenharmony_ci .compress = hisi_zip_acompress, 6448c2ecf20Sopenharmony_ci .decompress = hisi_zip_adecompress, 6458c2ecf20Sopenharmony_ci .base = { 6468c2ecf20Sopenharmony_ci .cra_name = "zlib-deflate", 6478c2ecf20Sopenharmony_ci .cra_driver_name = "hisi-zlib-acomp", 6488c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 6498c2ecf20Sopenharmony_ci .cra_priority = HZIP_ALG_PRIORITY, 6508c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct hisi_zip_ctx), 6518c2ecf20Sopenharmony_ci } 6528c2ecf20Sopenharmony_ci}; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_cistatic struct acomp_alg hisi_zip_acomp_gzip = { 6558c2ecf20Sopenharmony_ci .init = hisi_zip_acomp_init, 6568c2ecf20Sopenharmony_ci .exit = hisi_zip_acomp_exit, 6578c2ecf20Sopenharmony_ci .compress = hisi_zip_acompress, 6588c2ecf20Sopenharmony_ci .decompress = hisi_zip_adecompress, 6598c2ecf20Sopenharmony_ci .base = { 6608c2ecf20Sopenharmony_ci .cra_name = "gzip", 6618c2ecf20Sopenharmony_ci .cra_driver_name = "hisi-gzip-acomp", 6628c2ecf20Sopenharmony_ci .cra_module = THIS_MODULE, 6638c2ecf20Sopenharmony_ci .cra_priority = HZIP_ALG_PRIORITY, 6648c2ecf20Sopenharmony_ci .cra_ctxsize = sizeof(struct hisi_zip_ctx), 6658c2ecf20Sopenharmony_ci } 6668c2ecf20Sopenharmony_ci}; 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ciint hisi_zip_register_to_crypto(void) 6698c2ecf20Sopenharmony_ci{ 6708c2ecf20Sopenharmony_ci int ret; 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci ret = crypto_register_acomp(&hisi_zip_acomp_zlib); 6738c2ecf20Sopenharmony_ci if (ret) { 6748c2ecf20Sopenharmony_ci pr_err("failed to register to zlib (%d)!\n", ret); 6758c2ecf20Sopenharmony_ci return ret; 6768c2ecf20Sopenharmony_ci } 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ci ret = crypto_register_acomp(&hisi_zip_acomp_gzip); 6798c2ecf20Sopenharmony_ci if (ret) { 6808c2ecf20Sopenharmony_ci pr_err("failed to register to gzip (%d)!\n", ret); 6818c2ecf20Sopenharmony_ci crypto_unregister_acomp(&hisi_zip_acomp_zlib); 6828c2ecf20Sopenharmony_ci } 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ci return ret; 6858c2ecf20Sopenharmony_ci} 6868c2ecf20Sopenharmony_ci 6878c2ecf20Sopenharmony_civoid hisi_zip_unregister_from_crypto(void) 6888c2ecf20Sopenharmony_ci{ 6898c2ecf20Sopenharmony_ci crypto_unregister_acomp(&hisi_zip_acomp_gzip); 6908c2ecf20Sopenharmony_ci crypto_unregister_acomp(&hisi_zip_acomp_zlib); 6918c2ecf20Sopenharmony_ci} 692