xref: /linux/drivers/crypto/hisilicon/zip/zip_crypto.c (revision 75b1a8f9d62e50f05d0e4e9f3c8bcde32527ffc1)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019 HiSilicon Limited. */
3 #include <crypto/internal/acompress.h>
4 #include <linux/bitfield.h>
5 #include <linux/dma-mapping.h>
6 #include <linux/scatterlist.h>
7 #include "zip.h"
8 
9 /* hisi_zip_sqe dw3 */
10 #define HZIP_BD_STATUS_M			GENMASK(7, 0)
11 /* hisi_zip_sqe dw7 */
12 #define HZIP_IN_SGE_DATA_OFFSET_M		GENMASK(23, 0)
13 /* hisi_zip_sqe dw8 */
14 #define HZIP_OUT_SGE_DATA_OFFSET_M		GENMASK(23, 0)
15 /* hisi_zip_sqe dw9 */
16 #define HZIP_REQ_TYPE_M				GENMASK(7, 0)
17 #define HZIP_ALG_TYPE_ZLIB			0x02
18 #define HZIP_ALG_TYPE_GZIP			0x03
19 #define HZIP_BUF_TYPE_M				GENMASK(11, 8)
20 #define HZIP_PBUFFER				0x0
21 #define HZIP_SGL				0x1
22 
23 #define HZIP_ZLIB_HEAD_SIZE			2
24 #define HZIP_GZIP_HEAD_SIZE			10
25 
26 #define GZIP_HEAD_FHCRC_BIT			BIT(1)
27 #define GZIP_HEAD_FEXTRA_BIT			BIT(2)
28 #define GZIP_HEAD_FNAME_BIT			BIT(3)
29 #define GZIP_HEAD_FCOMMENT_BIT			BIT(4)
30 
31 #define GZIP_HEAD_FLG_SHIFT			3
32 #define GZIP_HEAD_FEXTRA_SHIFT			10
33 #define GZIP_HEAD_FEXTRA_XLEN			2UL
34 #define GZIP_HEAD_FHCRC_SIZE			2
35 
36 #define HZIP_GZIP_HEAD_BUF			256
37 #define HZIP_ALG_PRIORITY			300
38 #define HZIP_SGL_SGE_NR				10
39 
40 static const u8 zlib_head[HZIP_ZLIB_HEAD_SIZE] = {0x78, 0x9c};
41 static const u8 gzip_head[HZIP_GZIP_HEAD_SIZE] = {
42 	0x1f, 0x8b, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x03
43 };
44 
45 enum hisi_zip_alg_type {
46 	HZIP_ALG_TYPE_COMP = 0,
47 	HZIP_ALG_TYPE_DECOMP = 1,
48 };
49 
50 enum {
51 	HZIP_QPC_COMP,
52 	HZIP_QPC_DECOMP,
53 	HZIP_CTX_Q_NUM
54 };
55 
56 #define COMP_NAME_TO_TYPE(alg_name)					\
57 	(!strcmp((alg_name), "zlib-deflate") ? HZIP_ALG_TYPE_ZLIB :	\
58 	 !strcmp((alg_name), "gzip") ? HZIP_ALG_TYPE_GZIP : 0)		\
59 
60 #define TO_HEAD_SIZE(req_type)						\
61 	(((req_type) == HZIP_ALG_TYPE_ZLIB) ? sizeof(zlib_head) :	\
62 	 ((req_type) == HZIP_ALG_TYPE_GZIP) ? sizeof(gzip_head) : 0)	\
63 
64 #define TO_HEAD(req_type)						\
65 	(((req_type) == HZIP_ALG_TYPE_ZLIB) ? zlib_head :		\
66 	 ((req_type) == HZIP_ALG_TYPE_GZIP) ? gzip_head : NULL)		\
67 
68 struct hisi_zip_req {
69 	struct acomp_req *req;
70 	u32 sskip;
71 	u32 dskip;
72 	struct hisi_acc_hw_sgl *hw_src;
73 	struct hisi_acc_hw_sgl *hw_dst;
74 	dma_addr_t dma_src;
75 	dma_addr_t dma_dst;
76 	u16 req_id;
77 };
78 
79 struct hisi_zip_req_q {
80 	struct hisi_zip_req *q;
81 	unsigned long *req_bitmap;
82 	rwlock_t req_lock;
83 	u16 size;
84 };
85 
86 struct hisi_zip_qp_ctx {
87 	struct hisi_qp *qp;
88 	struct hisi_zip_req_q req_q;
89 	struct hisi_acc_sgl_pool *sgl_pool;
90 	struct hisi_zip *zip_dev;
91 	struct hisi_zip_ctx *ctx;
92 };
93 
94 struct hisi_zip_ctx {
95 	struct hisi_zip_qp_ctx qp_ctx[HZIP_CTX_Q_NUM];
96 };
97 
98 static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)
99 {
100 	int ret;
101 	u16 n;
102 
103 	if (!val)
104 		return -EINVAL;
105 
106 	ret = kstrtou16(val, 10, &n);
107 	if (ret || n == 0 || n > HISI_ACC_SGL_SGE_NR_MAX)
108 		return -EINVAL;
109 
110 	return param_set_int(val, kp);
111 }
112 
113 static const struct kernel_param_ops sgl_sge_nr_ops = {
114 	.set = sgl_sge_nr_set,
115 	.get = param_get_int,
116 };
117 
118 static u16 sgl_sge_nr = HZIP_SGL_SGE_NR;
119 module_param_cb(sgl_sge_nr, &sgl_sge_nr_ops, &sgl_sge_nr, 0444);
120 MODULE_PARM_DESC(sgl_sge_nr, "Number of sge in sgl(1-255)");
121 
122 static void hisi_zip_config_buf_type(struct hisi_zip_sqe *sqe, u8 buf_type)
123 {
124 	u32 val;
125 
126 	val = (sqe->dw9) & ~HZIP_BUF_TYPE_M;
127 	val |= FIELD_PREP(HZIP_BUF_TYPE_M, buf_type);
128 	sqe->dw9 = val;
129 }
130 
131 static void hisi_zip_config_tag(struct hisi_zip_sqe *sqe, u32 tag)
132 {
133 	sqe->tag = tag;
134 }
135 
136 static void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type,
137 			      dma_addr_t s_addr, dma_addr_t d_addr, u32 slen,
138 			      u32 dlen, u32 sskip, u32 dskip)
139 {
140 	memset(sqe, 0, sizeof(struct hisi_zip_sqe));
141 
142 	sqe->input_data_length = slen - sskip;
143 	sqe->dw7 = FIELD_PREP(HZIP_IN_SGE_DATA_OFFSET_M, sskip);
144 	sqe->dw8 = FIELD_PREP(HZIP_OUT_SGE_DATA_OFFSET_M, dskip);
145 	sqe->dw9 = FIELD_PREP(HZIP_REQ_TYPE_M, req_type);
146 	sqe->dest_avail_out = dlen - dskip;
147 	sqe->source_addr_l = lower_32_bits(s_addr);
148 	sqe->source_addr_h = upper_32_bits(s_addr);
149 	sqe->dest_addr_l = lower_32_bits(d_addr);
150 	sqe->dest_addr_h = upper_32_bits(d_addr);
151 }
152 
153 static int hisi_zip_start_qp(struct hisi_qp *qp, struct hisi_zip_qp_ctx *ctx,
154 			     int alg_type, int req_type)
155 {
156 	struct device *dev = &qp->qm->pdev->dev;
157 	int ret;
158 
159 	qp->req_type = req_type;
160 	qp->alg_type = alg_type;
161 	qp->qp_ctx = ctx;
162 
163 	ret = hisi_qm_start_qp(qp, 0);
164 	if (ret < 0) {
165 		dev_err(dev, "failed to start qp (%d)!\n", ret);
166 		return ret;
167 	}
168 
169 	ctx->qp = qp;
170 
171 	return 0;
172 }
173 
174 static void hisi_zip_release_qp(struct hisi_zip_qp_ctx *ctx)
175 {
176 	hisi_qm_stop_qp(ctx->qp);
177 	hisi_qm_release_qp(ctx->qp);
178 }
179 
180 static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type, int node)
181 {
182 	struct hisi_qp *qps[HZIP_CTX_Q_NUM] = { NULL };
183 	struct hisi_zip *hisi_zip;
184 	int ret, i, j;
185 
186 	ret = zip_create_qps(qps, HZIP_CTX_Q_NUM, node);
187 	if (ret) {
188 		pr_err("failed to create zip qps (%d)!\n", ret);
189 		return -ENODEV;
190 	}
191 
192 	hisi_zip = container_of(qps[0]->qm, struct hisi_zip, qm);
193 
194 	for (i = 0; i < HZIP_CTX_Q_NUM; i++) {
195 		/* alg_type = 0 for compress, 1 for decompress in hw sqe */
196 		ret = hisi_zip_start_qp(qps[i], &hisi_zip_ctx->qp_ctx[i], i,
197 					req_type);
198 		if (ret) {
199 			for (j = i - 1; j >= 0; j--)
200 				hisi_qm_stop_qp(hisi_zip_ctx->qp_ctx[j].qp);
201 
202 			hisi_qm_free_qps(qps, HZIP_CTX_Q_NUM);
203 			return ret;
204 		}
205 
206 		hisi_zip_ctx->qp_ctx[i].zip_dev = hisi_zip;
207 	}
208 
209 	return 0;
210 }
211 
212 static void hisi_zip_ctx_exit(struct hisi_zip_ctx *hisi_zip_ctx)
213 {
214 	int i;
215 
216 	for (i = 1; i >= 0; i--)
217 		hisi_zip_release_qp(&hisi_zip_ctx->qp_ctx[i]);
218 }
219 
220 static u16 get_extra_field_size(const u8 *start)
221 {
222 	return *((u16 *)start) + GZIP_HEAD_FEXTRA_XLEN;
223 }
224 
225 static u32 get_name_field_size(const u8 *start)
226 {
227 	return strlen(start) + 1;
228 }
229 
230 static u32 get_comment_field_size(const u8 *start)
231 {
232 	return strlen(start) + 1;
233 }
234 
235 static u32 __get_gzip_head_size(const u8 *src)
236 {
237 	u8 head_flg = *(src + GZIP_HEAD_FLG_SHIFT);
238 	u32 size = GZIP_HEAD_FEXTRA_SHIFT;
239 
240 	if (head_flg & GZIP_HEAD_FEXTRA_BIT)
241 		size += get_extra_field_size(src + size);
242 	if (head_flg & GZIP_HEAD_FNAME_BIT)
243 		size += get_name_field_size(src + size);
244 	if (head_flg & GZIP_HEAD_FCOMMENT_BIT)
245 		size += get_comment_field_size(src + size);
246 	if (head_flg & GZIP_HEAD_FHCRC_BIT)
247 		size += GZIP_HEAD_FHCRC_SIZE;
248 
249 	return size;
250 }
251 
252 static int hisi_zip_create_req_q(struct hisi_zip_ctx *ctx)
253 {
254 	struct hisi_zip_req_q *req_q;
255 	int i, ret;
256 
257 	for (i = 0; i < HZIP_CTX_Q_NUM; i++) {
258 		req_q = &ctx->qp_ctx[i].req_q;
259 		req_q->size = QM_Q_DEPTH;
260 
261 		req_q->req_bitmap = kcalloc(BITS_TO_LONGS(req_q->size),
262 					    sizeof(long), GFP_KERNEL);
263 		if (!req_q->req_bitmap) {
264 			ret = -ENOMEM;
265 			if (i == 0)
266 				return ret;
267 
268 			goto err_free_loop0;
269 		}
270 		rwlock_init(&req_q->req_lock);
271 
272 		req_q->q = kcalloc(req_q->size, sizeof(struct hisi_zip_req),
273 				   GFP_KERNEL);
274 		if (!req_q->q) {
275 			ret = -ENOMEM;
276 			if (i == 0)
277 				goto err_free_bitmap;
278 			else
279 				goto err_free_loop1;
280 		}
281 	}
282 
283 	return 0;
284 
285 err_free_loop1:
286 	kfree(ctx->qp_ctx[HZIP_QPC_DECOMP].req_q.req_bitmap);
287 err_free_loop0:
288 	kfree(ctx->qp_ctx[HZIP_QPC_COMP].req_q.q);
289 err_free_bitmap:
290 	kfree(ctx->qp_ctx[HZIP_QPC_COMP].req_q.req_bitmap);
291 	return ret;
292 }
293 
294 static void hisi_zip_release_req_q(struct hisi_zip_ctx *ctx)
295 {
296 	int i;
297 
298 	for (i = 0; i < HZIP_CTX_Q_NUM; i++) {
299 		kfree(ctx->qp_ctx[i].req_q.q);
300 		kfree(ctx->qp_ctx[i].req_q.req_bitmap);
301 	}
302 }
303 
304 static int hisi_zip_create_sgl_pool(struct hisi_zip_ctx *ctx)
305 {
306 	struct hisi_zip_qp_ctx *tmp;
307 	struct device *dev;
308 	int i;
309 
310 	for (i = 0; i < HZIP_CTX_Q_NUM; i++) {
311 		tmp = &ctx->qp_ctx[i];
312 		dev = &tmp->qp->qm->pdev->dev;
313 		tmp->sgl_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH << 1,
314 							 sgl_sge_nr);
315 		if (IS_ERR(tmp->sgl_pool)) {
316 			if (i == 1)
317 				goto err_free_sgl_pool0;
318 			return -ENOMEM;
319 		}
320 	}
321 
322 	return 0;
323 
324 err_free_sgl_pool0:
325 	hisi_acc_free_sgl_pool(&ctx->qp_ctx[HZIP_QPC_COMP].qp->qm->pdev->dev,
326 			       ctx->qp_ctx[HZIP_QPC_COMP].sgl_pool);
327 	return -ENOMEM;
328 }
329 
330 static void hisi_zip_release_sgl_pool(struct hisi_zip_ctx *ctx)
331 {
332 	int i;
333 
334 	for (i = 0; i < HZIP_CTX_Q_NUM; i++)
335 		hisi_acc_free_sgl_pool(&ctx->qp_ctx[i].qp->qm->pdev->dev,
336 				       ctx->qp_ctx[i].sgl_pool);
337 }
338 
339 static void hisi_zip_remove_req(struct hisi_zip_qp_ctx *qp_ctx,
340 				struct hisi_zip_req *req)
341 {
342 	struct hisi_zip_req_q *req_q = &qp_ctx->req_q;
343 
344 	write_lock(&req_q->req_lock);
345 	clear_bit(req->req_id, req_q->req_bitmap);
346 	memset(req, 0, sizeof(struct hisi_zip_req));
347 	write_unlock(&req_q->req_lock);
348 }
349 
350 static void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data)
351 {
352 	struct hisi_zip_sqe *sqe = data;
353 	struct hisi_zip_qp_ctx *qp_ctx = qp->qp_ctx;
354 	struct hisi_zip_dfx *dfx = &qp_ctx->zip_dev->dfx;
355 	struct hisi_zip_req_q *req_q = &qp_ctx->req_q;
356 	struct hisi_zip_req *req = req_q->q + sqe->tag;
357 	struct acomp_req *acomp_req = req->req;
358 	struct device *dev = &qp->qm->pdev->dev;
359 	u32 status, dlen, head_size;
360 	int err = 0;
361 
362 	atomic64_inc(&dfx->recv_cnt);
363 	status = sqe->dw3 & HZIP_BD_STATUS_M;
364 	if (status != 0 && status != HZIP_NC_ERR) {
365 		dev_err(dev, "%scompress fail in qp%u: %u, output: %u\n",
366 			(qp->alg_type == 0) ? "" : "de", qp->qp_id, status,
367 			sqe->produced);
368 		atomic64_inc(&dfx->err_bd_cnt);
369 		err = -EIO;
370 	}
371 	dlen = sqe->produced;
372 
373 	hisi_acc_sg_buf_unmap(dev, acomp_req->src, req->hw_src);
374 	hisi_acc_sg_buf_unmap(dev, acomp_req->dst, req->hw_dst);
375 
376 	head_size = (qp->alg_type == 0) ? TO_HEAD_SIZE(qp->req_type) : 0;
377 	acomp_req->dlen = dlen + head_size;
378 
379 	if (acomp_req->base.complete)
380 		acomp_request_complete(acomp_req, err);
381 
382 	hisi_zip_remove_req(qp_ctx, req);
383 }
384 
385 static void hisi_zip_set_acomp_cb(struct hisi_zip_ctx *ctx,
386 				  void (*fn)(struct hisi_qp *, void *))
387 {
388 	int i;
389 
390 	for (i = 0; i < HZIP_CTX_Q_NUM; i++)
391 		ctx->qp_ctx[i].qp->req_cb = fn;
392 }
393 
394 static int hisi_zip_acomp_init(struct crypto_acomp *tfm)
395 {
396 	const char *alg_name = crypto_tfm_alg_name(&tfm->base);
397 	struct hisi_zip_ctx *ctx = crypto_tfm_ctx(&tfm->base);
398 	struct device *dev;
399 	int ret;
400 
401 	ret = hisi_zip_ctx_init(ctx, COMP_NAME_TO_TYPE(alg_name), tfm->base.node);
402 	if (ret) {
403 		pr_err("failed to init ctx (%d)!\n", ret);
404 		return ret;
405 	}
406 
407 	dev = &ctx->qp_ctx[0].qp->qm->pdev->dev;
408 
409 	ret = hisi_zip_create_req_q(ctx);
410 	if (ret) {
411 		dev_err(dev, "failed to create request queue (%d)!\n", ret);
412 		goto err_ctx_exit;
413 	}
414 
415 	ret = hisi_zip_create_sgl_pool(ctx);
416 	if (ret) {
417 		dev_err(dev, "failed to create sgl pool (%d)!\n", ret);
418 		goto err_release_req_q;
419 	}
420 
421 	hisi_zip_set_acomp_cb(ctx, hisi_zip_acomp_cb);
422 
423 	return 0;
424 
425 err_release_req_q:
426 	hisi_zip_release_req_q(ctx);
427 err_ctx_exit:
428 	hisi_zip_ctx_exit(ctx);
429 	return ret;
430 }
431 
432 static void hisi_zip_acomp_exit(struct crypto_acomp *tfm)
433 {
434 	struct hisi_zip_ctx *ctx = crypto_tfm_ctx(&tfm->base);
435 
436 	hisi_zip_set_acomp_cb(ctx, NULL);
437 	hisi_zip_release_sgl_pool(ctx);
438 	hisi_zip_release_req_q(ctx);
439 	hisi_zip_ctx_exit(ctx);
440 }
441 
442 static int add_comp_head(struct scatterlist *dst, u8 req_type)
443 {
444 	int head_size = TO_HEAD_SIZE(req_type);
445 	const u8 *head = TO_HEAD(req_type);
446 	int ret;
447 
448 	ret = sg_copy_from_buffer(dst, sg_nents(dst), head, head_size);
449 	if (ret != head_size) {
450 		pr_err("the head size of buffer is wrong (%d)!\n", ret);
451 		return -ENOMEM;
452 	}
453 
454 	return head_size;
455 }
456 
457 static size_t __maybe_unused get_gzip_head_size(struct scatterlist *sgl)
458 {
459 	char buf[HZIP_GZIP_HEAD_BUF];
460 
461 	sg_copy_to_buffer(sgl, sg_nents(sgl), buf, sizeof(buf));
462 
463 	return __get_gzip_head_size(buf);
464 }
465 
466 static int  get_comp_head_size(struct acomp_req *acomp_req, u8 req_type)
467 {
468 	if (!acomp_req->src || !acomp_req->slen)
469 		return -EINVAL;
470 
471 	if ((req_type == HZIP_ALG_TYPE_GZIP) &&
472 	    (acomp_req->slen < GZIP_HEAD_FEXTRA_SHIFT))
473 		return -EINVAL;
474 
475 	switch (req_type) {
476 	case HZIP_ALG_TYPE_ZLIB:
477 		return TO_HEAD_SIZE(HZIP_ALG_TYPE_ZLIB);
478 	case HZIP_ALG_TYPE_GZIP:
479 		return TO_HEAD_SIZE(HZIP_ALG_TYPE_GZIP);
480 	default:
481 		pr_err("request type does not support!\n");
482 		return -EINVAL;
483 	}
484 }
485 
486 static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req,
487 						struct hisi_zip_qp_ctx *qp_ctx,
488 						size_t head_size, bool is_comp)
489 {
490 	struct hisi_zip_req_q *req_q = &qp_ctx->req_q;
491 	struct hisi_zip_req *q = req_q->q;
492 	struct hisi_zip_req *req_cache;
493 	int req_id;
494 
495 	write_lock(&req_q->req_lock);
496 
497 	req_id = find_first_zero_bit(req_q->req_bitmap, req_q->size);
498 	if (req_id >= req_q->size) {
499 		write_unlock(&req_q->req_lock);
500 		dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n");
501 		return ERR_PTR(-EAGAIN);
502 	}
503 	set_bit(req_id, req_q->req_bitmap);
504 
505 	req_cache = q + req_id;
506 	req_cache->req_id = req_id;
507 	req_cache->req = req;
508 
509 	if (is_comp) {
510 		req_cache->sskip = 0;
511 		req_cache->dskip = head_size;
512 	} else {
513 		req_cache->sskip = head_size;
514 		req_cache->dskip = 0;
515 	}
516 
517 	write_unlock(&req_q->req_lock);
518 
519 	return req_cache;
520 }
521 
522 static int hisi_zip_do_work(struct hisi_zip_req *req,
523 			    struct hisi_zip_qp_ctx *qp_ctx)
524 {
525 	struct acomp_req *a_req = req->req;
526 	struct hisi_qp *qp = qp_ctx->qp;
527 	struct device *dev = &qp->qm->pdev->dev;
528 	struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;
529 	struct hisi_zip_dfx *dfx = &qp_ctx->zip_dev->dfx;
530 	struct hisi_zip_sqe zip_sqe;
531 	dma_addr_t input, output;
532 	int ret;
533 
534 	if (!a_req->src || !a_req->slen || !a_req->dst || !a_req->dlen)
535 		return -EINVAL;
536 
537 	req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->src, pool,
538 						    req->req_id << 1, &input);
539 	if (IS_ERR(req->hw_src)) {
540 		dev_err(dev, "failed to map the src buffer to hw sgl (%ld)!\n",
541 			PTR_ERR(req->hw_src));
542 		return PTR_ERR(req->hw_src);
543 	}
544 	req->dma_src = input;
545 
546 	req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->dst, pool,
547 						    (req->req_id << 1) + 1,
548 						    &output);
549 	if (IS_ERR(req->hw_dst)) {
550 		ret = PTR_ERR(req->hw_dst);
551 		dev_err(dev, "failed to map the dst buffer to hw slg (%d)!\n",
552 			ret);
553 		goto err_unmap_input;
554 	}
555 	req->dma_dst = output;
556 
557 	hisi_zip_fill_sqe(&zip_sqe, qp->req_type, input, output, a_req->slen,
558 			  a_req->dlen, req->sskip, req->dskip);
559 	hisi_zip_config_buf_type(&zip_sqe, HZIP_SGL);
560 	hisi_zip_config_tag(&zip_sqe, req->req_id);
561 
562 	/* send command to start a task */
563 	atomic64_inc(&dfx->send_cnt);
564 	ret = hisi_qp_send(qp, &zip_sqe);
565 	if (ret < 0) {
566 		atomic64_inc(&dfx->send_busy_cnt);
567 		ret = -EAGAIN;
568 		dev_dbg_ratelimited(dev, "failed to send request!\n");
569 		goto err_unmap_output;
570 	}
571 
572 	return -EINPROGRESS;
573 
574 err_unmap_output:
575 	hisi_acc_sg_buf_unmap(dev, a_req->dst, req->hw_dst);
576 err_unmap_input:
577 	hisi_acc_sg_buf_unmap(dev, a_req->src, req->hw_src);
578 	return ret;
579 }
580 
581 static int hisi_zip_acompress(struct acomp_req *acomp_req)
582 {
583 	struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm);
584 	struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[HZIP_QPC_COMP];
585 	struct device *dev = &qp_ctx->qp->qm->pdev->dev;
586 	struct hisi_zip_req *req;
587 	int head_size;
588 	int ret;
589 
590 	/* let's output compression head now */
591 	head_size = add_comp_head(acomp_req->dst, qp_ctx->qp->req_type);
592 	if (head_size < 0) {
593 		dev_err_ratelimited(dev, "failed to add comp head (%d)!\n",
594 				    head_size);
595 		return head_size;
596 	}
597 
598 	req = hisi_zip_create_req(acomp_req, qp_ctx, head_size, true);
599 	if (IS_ERR(req))
600 		return PTR_ERR(req);
601 
602 	ret = hisi_zip_do_work(req, qp_ctx);
603 	if (ret != -EINPROGRESS) {
604 		dev_info_ratelimited(dev, "failed to do compress (%d)!\n", ret);
605 		hisi_zip_remove_req(qp_ctx, req);
606 	}
607 
608 	return ret;
609 }
610 
611 static int hisi_zip_adecompress(struct acomp_req *acomp_req)
612 {
613 	struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm);
614 	struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[HZIP_QPC_DECOMP];
615 	struct device *dev = &qp_ctx->qp->qm->pdev->dev;
616 	struct hisi_zip_req *req;
617 	int head_size, ret;
618 
619 	head_size = get_comp_head_size(acomp_req, qp_ctx->qp->req_type);
620 	if (head_size < 0) {
621 		dev_err_ratelimited(dev, "failed to get comp head size (%d)!\n",
622 				    head_size);
623 		return head_size;
624 	}
625 
626 	req = hisi_zip_create_req(acomp_req, qp_ctx, head_size, false);
627 	if (IS_ERR(req))
628 		return PTR_ERR(req);
629 
630 	ret = hisi_zip_do_work(req, qp_ctx);
631 	if (ret != -EINPROGRESS) {
632 		dev_info_ratelimited(dev, "failed to do decompress (%d)!\n",
633 				     ret);
634 		hisi_zip_remove_req(qp_ctx, req);
635 	}
636 
637 	return ret;
638 }
639 
640 static struct acomp_alg hisi_zip_acomp_zlib = {
641 	.init			= hisi_zip_acomp_init,
642 	.exit			= hisi_zip_acomp_exit,
643 	.compress		= hisi_zip_acompress,
644 	.decompress		= hisi_zip_adecompress,
645 	.base			= {
646 		.cra_name		= "zlib-deflate",
647 		.cra_driver_name	= "hisi-zlib-acomp",
648 		.cra_module		= THIS_MODULE,
649 		.cra_priority           = HZIP_ALG_PRIORITY,
650 		.cra_ctxsize		= sizeof(struct hisi_zip_ctx),
651 	}
652 };
653 
654 static struct acomp_alg hisi_zip_acomp_gzip = {
655 	.init			= hisi_zip_acomp_init,
656 	.exit			= hisi_zip_acomp_exit,
657 	.compress		= hisi_zip_acompress,
658 	.decompress		= hisi_zip_adecompress,
659 	.base			= {
660 		.cra_name		= "gzip",
661 		.cra_driver_name	= "hisi-gzip-acomp",
662 		.cra_module		= THIS_MODULE,
663 		.cra_priority           = HZIP_ALG_PRIORITY,
664 		.cra_ctxsize		= sizeof(struct hisi_zip_ctx),
665 	}
666 };
667 
668 int hisi_zip_register_to_crypto(void)
669 {
670 	int ret;
671 
672 	ret = crypto_register_acomp(&hisi_zip_acomp_zlib);
673 	if (ret) {
674 		pr_err("failed to register to zlib (%d)!\n", ret);
675 		return ret;
676 	}
677 
678 	ret = crypto_register_acomp(&hisi_zip_acomp_gzip);
679 	if (ret) {
680 		pr_err("failed to register to gzip (%d)!\n", ret);
681 		crypto_unregister_acomp(&hisi_zip_acomp_zlib);
682 	}
683 
684 	return ret;
685 }
686 
687 void hisi_zip_unregister_from_crypto(void)
688 {
689 	crypto_unregister_acomp(&hisi_zip_acomp_gzip);
690 	crypto_unregister_acomp(&hisi_zip_acomp_zlib);
691 }
692