File Index
Files and directories
Sign in
FILE

zip_crypto.c

File preview with syntax highlighting.

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