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>
9 #define HZIP_ZLIB_HEAD_SIZE 2
10 #define HZIP_GZIP_HEAD_SIZE 10
12 #define GZIP_HEAD_FHCRC_BIT BIT(1)
13 #define GZIP_HEAD_FEXTRA_BIT BIT(2)
14 #define GZIP_HEAD_FNAME_BIT BIT(3)
15 #define GZIP_HEAD_FCOMMENT_BIT BIT(4)
17 #define GZIP_HEAD_FLG_SHIFT 3
18 #define GZIP_HEAD_FEXTRA_SHIFT 10
19 #define GZIP_HEAD_FEXTRA_XLEN 2
20 #define GZIP_HEAD_FHCRC_SIZE 2
22 #define HZIP_CTX_Q_NUM 2
23 #define HZIP_GZIP_HEAD_BUF 256
24 #define HZIP_ALG_PRIORITY 300
25 #define HZIP_SGL_SGE_NR 10
27 static const u8 zlib_head
[HZIP_ZLIB_HEAD_SIZE
] = {0x78, 0x9c};
28 static const u8 gzip_head
[HZIP_GZIP_HEAD_SIZE
] = {0x1f, 0x8b, 0x08, 0x0, 0x0,
29 0x0, 0x0, 0x0, 0x0, 0x03};
30 enum hisi_zip_alg_type
{
31 HZIP_ALG_TYPE_COMP
= 0,
32 HZIP_ALG_TYPE_DECOMP
= 1,
35 #define COMP_NAME_TO_TYPE(alg_name) \
36 (!strcmp((alg_name), "zlib-deflate") ? HZIP_ALG_TYPE_ZLIB : \
37 !strcmp((alg_name), "gzip") ? HZIP_ALG_TYPE_GZIP : 0) \
39 #define TO_HEAD_SIZE(req_type) \
40 (((req_type) == HZIP_ALG_TYPE_ZLIB) ? sizeof(zlib_head) : \
41 ((req_type) == HZIP_ALG_TYPE_GZIP) ? sizeof(gzip_head) : 0) \
43 #define TO_HEAD(req_type) \
44 (((req_type) == HZIP_ALG_TYPE_ZLIB) ? zlib_head : \
45 ((req_type) == HZIP_ALG_TYPE_GZIP) ? gzip_head : NULL) \
48 struct acomp_req
*req
;
51 struct hisi_acc_hw_sgl
*hw_src
;
52 struct hisi_acc_hw_sgl
*hw_dst
;
58 struct hisi_zip_req_q
{
59 struct hisi_zip_req
*q
;
60 unsigned long *req_bitmap
;
65 struct hisi_zip_qp_ctx
{
67 struct hisi_zip_sqe zip_sqe
;
68 struct hisi_zip_req_q req_q
;
69 struct hisi_acc_sgl_pool
*sgl_pool
;
70 struct hisi_zip
*zip_dev
;
71 struct hisi_zip_ctx
*ctx
;
77 struct hisi_zip_qp_ctx qp_ctx
[HZIP_CTX_Q_NUM
];
80 static int sgl_sge_nr_set(const char *val
, const struct kernel_param
*kp
)
88 ret
= kstrtou16(val
, 10, &n
);
89 if (ret
|| n
== 0 || n
> HISI_ACC_SGL_SGE_NR_MAX
)
92 return param_set_int(val
, kp
);
95 static const struct kernel_param_ops sgl_sge_nr_ops
= {
96 .set
= sgl_sge_nr_set
,
100 static u16 sgl_sge_nr
= HZIP_SGL_SGE_NR
;
101 module_param_cb(sgl_sge_nr
, &sgl_sge_nr_ops
, &sgl_sge_nr
, 0444);
102 MODULE_PARM_DESC(sgl_sge_nr
, "Number of sge in sgl(1-255)");
104 static void hisi_zip_config_buf_type(struct hisi_zip_sqe
*sqe
, u8 buf_type
)
108 val
= (sqe
->dw9
) & ~HZIP_BUF_TYPE_M
;
109 val
|= FIELD_PREP(HZIP_BUF_TYPE_M
, buf_type
);
113 static void hisi_zip_config_tag(struct hisi_zip_sqe
*sqe
, u32 tag
)
118 static void hisi_zip_fill_sqe(struct hisi_zip_sqe
*sqe
, u8 req_type
,
119 dma_addr_t s_addr
, dma_addr_t d_addr
, u32 slen
,
120 u32 dlen
, int sskip
, int dskip
)
122 memset(sqe
, 0, sizeof(struct hisi_zip_sqe
));
124 sqe
->input_data_length
= slen
- sskip
;
125 sqe
->dw7
= FIELD_PREP(HZIP_IN_SGE_DATA_OFFSET_M
, sskip
);
126 sqe
->dw8
= FIELD_PREP(HZIP_OUT_SGE_DATA_OFFSET_M
, dskip
);
127 sqe
->dw9
= FIELD_PREP(HZIP_REQ_TYPE_M
, req_type
);
128 sqe
->dest_avail_out
= dlen
- dskip
;
129 sqe
->source_addr_l
= lower_32_bits(s_addr
);
130 sqe
->source_addr_h
= upper_32_bits(s_addr
);
131 sqe
->dest_addr_l
= lower_32_bits(d_addr
);
132 sqe
->dest_addr_h
= upper_32_bits(d_addr
);
135 static int hisi_zip_create_qp(struct hisi_qm
*qm
, struct hisi_zip_qp_ctx
*ctx
,
136 int alg_type
, int req_type
)
141 qp
= hisi_qm_create_qp(qm
, alg_type
);
145 qp
->req_type
= req_type
;
149 ret
= hisi_qm_start_qp(qp
, 0);
156 hisi_qm_release_qp(qp
);
160 static void hisi_zip_release_qp(struct hisi_zip_qp_ctx
*ctx
)
162 hisi_qm_stop_qp(ctx
->qp
);
163 hisi_qm_release_qp(ctx
->qp
);
166 static int hisi_zip_ctx_init(struct hisi_zip_ctx
*hisi_zip_ctx
, u8 req_type
)
168 struct hisi_zip
*hisi_zip
;
172 /* find the proper zip device */
173 hisi_zip
= find_zip_device(cpu_to_node(smp_processor_id()));
175 pr_err("Failed to find a proper ZIP device!\n");
180 for (i
= 0; i
< HZIP_CTX_Q_NUM
; i
++) {
181 /* alg_type = 0 for compress, 1 for decompress in hw sqe */
182 ret
= hisi_zip_create_qp(qm
, &hisi_zip_ctx
->qp_ctx
[i
], i
,
187 hisi_zip_ctx
->qp_ctx
[i
].zip_dev
= hisi_zip
;
192 for (j
= i
- 1; j
>= 0; j
--)
193 hisi_zip_release_qp(&hisi_zip_ctx
->qp_ctx
[j
]);
198 static void hisi_zip_ctx_exit(struct hisi_zip_ctx
*hisi_zip_ctx
)
202 for (i
= 1; i
>= 0; i
--)
203 hisi_zip_release_qp(&hisi_zip_ctx
->qp_ctx
[i
]);
206 static u16
get_extra_field_size(const u8
*start
)
208 return *((u16
*)start
) + GZIP_HEAD_FEXTRA_XLEN
;
211 static u32
get_name_field_size(const u8
*start
)
213 return strlen(start
) + 1;
216 static u32
get_comment_field_size(const u8
*start
)
218 return strlen(start
) + 1;
221 static u32
__get_gzip_head_size(const u8
*src
)
223 u8 head_flg
= *(src
+ GZIP_HEAD_FLG_SHIFT
);
224 u32 size
= GZIP_HEAD_FEXTRA_SHIFT
;
226 if (head_flg
& GZIP_HEAD_FEXTRA_BIT
)
227 size
+= get_extra_field_size(src
+ size
);
228 if (head_flg
& GZIP_HEAD_FNAME_BIT
)
229 size
+= get_name_field_size(src
+ size
);
230 if (head_flg
& GZIP_HEAD_FCOMMENT_BIT
)
231 size
+= get_comment_field_size(src
+ size
);
232 if (head_flg
& GZIP_HEAD_FHCRC_BIT
)
233 size
+= GZIP_HEAD_FHCRC_SIZE
;
238 static int hisi_zip_create_req_q(struct hisi_zip_ctx
*ctx
)
240 struct hisi_zip_req_q
*req_q
;
243 for (i
= 0; i
< HZIP_CTX_Q_NUM
; i
++) {
244 req_q
= &ctx
->qp_ctx
[i
].req_q
;
245 req_q
->size
= QM_Q_DEPTH
;
247 req_q
->req_bitmap
= kcalloc(BITS_TO_LONGS(req_q
->size
),
248 sizeof(long), GFP_KERNEL
);
249 if (!req_q
->req_bitmap
) {
256 rwlock_init(&req_q
->req_lock
);
258 req_q
->q
= kcalloc(req_q
->size
, sizeof(struct hisi_zip_req
),
263 goto err_free_bitmap
;
272 kfree(ctx
->qp_ctx
[QPC_DECOMP
].req_q
.req_bitmap
);
274 kfree(ctx
->qp_ctx
[QPC_COMP
].req_q
.q
);
276 kfree(ctx
->qp_ctx
[QPC_COMP
].req_q
.req_bitmap
);
280 static void hisi_zip_release_req_q(struct hisi_zip_ctx
*ctx
)
284 for (i
= 0; i
< HZIP_CTX_Q_NUM
; i
++) {
285 kfree(ctx
->qp_ctx
[i
].req_q
.q
);
286 kfree(ctx
->qp_ctx
[i
].req_q
.req_bitmap
);
290 static int hisi_zip_create_sgl_pool(struct hisi_zip_ctx
*ctx
)
292 struct hisi_zip_qp_ctx
*tmp
;
296 for (i
= 0; i
< HZIP_CTX_Q_NUM
; i
++) {
297 tmp
= &ctx
->qp_ctx
[i
];
298 dev
= &tmp
->qp
->qm
->pdev
->dev
;
299 tmp
->sgl_pool
= hisi_acc_create_sgl_pool(dev
, QM_Q_DEPTH
<< 1,
301 if (IS_ERR(tmp
->sgl_pool
)) {
303 goto err_free_sgl_pool0
;
311 hisi_acc_free_sgl_pool(&ctx
->qp_ctx
[QPC_COMP
].qp
->qm
->pdev
->dev
,
312 ctx
->qp_ctx
[QPC_COMP
].sgl_pool
);
316 static void hisi_zip_release_sgl_pool(struct hisi_zip_ctx
*ctx
)
320 for (i
= 0; i
< HZIP_CTX_Q_NUM
; i
++)
321 hisi_acc_free_sgl_pool(&ctx
->qp_ctx
[i
].qp
->qm
->pdev
->dev
,
322 ctx
->qp_ctx
[i
].sgl_pool
);
325 static void hisi_zip_remove_req(struct hisi_zip_qp_ctx
*qp_ctx
,
326 struct hisi_zip_req
*req
)
328 struct hisi_zip_req_q
*req_q
= &qp_ctx
->req_q
;
330 write_lock(&req_q
->req_lock
);
331 clear_bit(req
->req_id
, req_q
->req_bitmap
);
332 memset(req
, 0, sizeof(struct hisi_zip_req
));
333 write_unlock(&req_q
->req_lock
);
336 static void hisi_zip_acomp_cb(struct hisi_qp
*qp
, void *data
)
338 struct hisi_zip_sqe
*sqe
= data
;
339 struct hisi_zip_qp_ctx
*qp_ctx
= qp
->qp_ctx
;
340 struct hisi_zip_req_q
*req_q
= &qp_ctx
->req_q
;
341 struct hisi_zip_req
*req
= req_q
->q
+ sqe
->tag
;
342 struct acomp_req
*acomp_req
= req
->req
;
343 struct device
*dev
= &qp
->qm
->pdev
->dev
;
344 u32 status
, dlen
, head_size
;
347 status
= sqe
->dw3
& HZIP_BD_STATUS_M
;
349 if (status
!= 0 && status
!= HZIP_NC_ERR
) {
350 dev_err(dev
, "%scompress fail in qp%u: %u, output: %u\n",
351 (qp
->alg_type
== 0) ? "" : "de", qp
->qp_id
, status
,
355 dlen
= sqe
->produced
;
357 hisi_acc_sg_buf_unmap(dev
, acomp_req
->src
, req
->hw_src
);
358 hisi_acc_sg_buf_unmap(dev
, acomp_req
->dst
, req
->hw_dst
);
360 head_size
= (qp
->alg_type
== 0) ? TO_HEAD_SIZE(qp
->req_type
) : 0;
361 acomp_req
->dlen
= dlen
+ head_size
;
363 if (acomp_req
->base
.complete
)
364 acomp_request_complete(acomp_req
, err
);
366 hisi_zip_remove_req(qp_ctx
, req
);
369 static void hisi_zip_set_acomp_cb(struct hisi_zip_ctx
*ctx
,
370 void (*fn
)(struct hisi_qp
*, void *))
374 for (i
= 0; i
< HZIP_CTX_Q_NUM
; i
++)
375 ctx
->qp_ctx
[i
].qp
->req_cb
= fn
;
378 static int hisi_zip_acomp_init(struct crypto_acomp
*tfm
)
380 const char *alg_name
= crypto_tfm_alg_name(&tfm
->base
);
381 struct hisi_zip_ctx
*ctx
= crypto_tfm_ctx(&tfm
->base
);
384 ret
= hisi_zip_ctx_init(ctx
, COMP_NAME_TO_TYPE(alg_name
));
388 ret
= hisi_zip_create_req_q(ctx
);
392 ret
= hisi_zip_create_sgl_pool(ctx
);
394 goto err_release_req_q
;
396 hisi_zip_set_acomp_cb(ctx
, hisi_zip_acomp_cb
);
401 hisi_zip_release_req_q(ctx
);
403 hisi_zip_ctx_exit(ctx
);
407 static void hisi_zip_acomp_exit(struct crypto_acomp
*tfm
)
409 struct hisi_zip_ctx
*ctx
= crypto_tfm_ctx(&tfm
->base
);
411 hisi_zip_set_acomp_cb(ctx
, NULL
);
412 hisi_zip_release_sgl_pool(ctx
);
413 hisi_zip_release_req_q(ctx
);
414 hisi_zip_ctx_exit(ctx
);
417 static int add_comp_head(struct scatterlist
*dst
, u8 req_type
)
419 int head_size
= TO_HEAD_SIZE(req_type
);
420 const u8
*head
= TO_HEAD(req_type
);
423 ret
= sg_copy_from_buffer(dst
, sg_nents(dst
), head
, head_size
);
424 if (ret
!= head_size
)
430 static size_t get_gzip_head_size(struct scatterlist
*sgl
)
432 char buf
[HZIP_GZIP_HEAD_BUF
];
434 sg_copy_to_buffer(sgl
, sg_nents(sgl
), buf
, sizeof(buf
));
436 return __get_gzip_head_size(buf
);
439 static size_t get_comp_head_size(struct scatterlist
*src
, u8 req_type
)
442 case HZIP_ALG_TYPE_ZLIB
:
443 return TO_HEAD_SIZE(HZIP_ALG_TYPE_ZLIB
);
444 case HZIP_ALG_TYPE_GZIP
:
445 return get_gzip_head_size(src
);
447 pr_err("request type does not support!\n");
452 static struct hisi_zip_req
*hisi_zip_create_req(struct acomp_req
*req
,
453 struct hisi_zip_qp_ctx
*qp_ctx
,
454 size_t head_size
, bool is_comp
)
456 struct hisi_zip_req_q
*req_q
= &qp_ctx
->req_q
;
457 struct hisi_zip_req
*q
= req_q
->q
;
458 struct hisi_zip_req
*req_cache
;
461 write_lock(&req_q
->req_lock
);
463 req_id
= find_first_zero_bit(req_q
->req_bitmap
, req_q
->size
);
464 if (req_id
>= req_q
->size
) {
465 write_unlock(&req_q
->req_lock
);
466 dev_dbg(&qp_ctx
->qp
->qm
->pdev
->dev
, "req cache is full!\n");
467 return ERR_PTR(-EBUSY
);
469 set_bit(req_id
, req_q
->req_bitmap
);
471 req_cache
= q
+ req_id
;
472 req_cache
->req_id
= req_id
;
473 req_cache
->req
= req
;
476 req_cache
->sskip
= 0;
477 req_cache
->dskip
= head_size
;
479 req_cache
->sskip
= head_size
;
480 req_cache
->dskip
= 0;
483 write_unlock(&req_q
->req_lock
);
488 static int hisi_zip_do_work(struct hisi_zip_req
*req
,
489 struct hisi_zip_qp_ctx
*qp_ctx
)
491 struct hisi_zip_sqe
*zip_sqe
= &qp_ctx
->zip_sqe
;
492 struct acomp_req
*a_req
= req
->req
;
493 struct hisi_qp
*qp
= qp_ctx
->qp
;
494 struct device
*dev
= &qp
->qm
->pdev
->dev
;
495 struct hisi_acc_sgl_pool
*pool
= qp_ctx
->sgl_pool
;
500 if (!a_req
->src
|| !a_req
->slen
|| !a_req
->dst
|| !a_req
->dlen
)
503 req
->hw_src
= hisi_acc_sg_buf_map_to_hw_sgl(dev
, a_req
->src
, pool
,
504 req
->req_id
<< 1, &input
);
505 if (IS_ERR(req
->hw_src
))
506 return PTR_ERR(req
->hw_src
);
507 req
->dma_src
= input
;
509 req
->hw_dst
= hisi_acc_sg_buf_map_to_hw_sgl(dev
, a_req
->dst
, pool
,
510 (req
->req_id
<< 1) + 1,
512 if (IS_ERR(req
->hw_dst
)) {
513 ret
= PTR_ERR(req
->hw_dst
);
514 goto err_unmap_input
;
516 req
->dma_dst
= output
;
518 hisi_zip_fill_sqe(zip_sqe
, qp
->req_type
, input
, output
, a_req
->slen
,
519 a_req
->dlen
, req
->sskip
, req
->dskip
);
520 hisi_zip_config_buf_type(zip_sqe
, HZIP_SGL
);
521 hisi_zip_config_tag(zip_sqe
, req
->req_id
);
523 /* send command to start a task */
524 ret
= hisi_qp_send(qp
, zip_sqe
);
526 goto err_unmap_output
;
531 hisi_acc_sg_buf_unmap(dev
, a_req
->dst
, req
->hw_dst
);
533 hisi_acc_sg_buf_unmap(dev
, a_req
->src
, req
->hw_src
);
537 static int hisi_zip_acompress(struct acomp_req
*acomp_req
)
539 struct hisi_zip_ctx
*ctx
= crypto_tfm_ctx(acomp_req
->base
.tfm
);
540 struct hisi_zip_qp_ctx
*qp_ctx
= &ctx
->qp_ctx
[QPC_COMP
];
541 struct hisi_zip_req
*req
;
545 /* let's output compression head now */
546 head_size
= add_comp_head(acomp_req
->dst
, qp_ctx
->qp
->req_type
);
550 req
= hisi_zip_create_req(acomp_req
, qp_ctx
, (size_t)head_size
, true);
554 ret
= hisi_zip_do_work(req
, qp_ctx
);
555 if (ret
!= -EINPROGRESS
)
556 hisi_zip_remove_req(qp_ctx
, req
);
561 static int hisi_zip_adecompress(struct acomp_req
*acomp_req
)
563 struct hisi_zip_ctx
*ctx
= crypto_tfm_ctx(acomp_req
->base
.tfm
);
564 struct hisi_zip_qp_ctx
*qp_ctx
= &ctx
->qp_ctx
[QPC_DECOMP
];
565 struct hisi_zip_req
*req
;
569 head_size
= get_comp_head_size(acomp_req
->src
, qp_ctx
->qp
->req_type
);
571 req
= hisi_zip_create_req(acomp_req
, qp_ctx
, head_size
, false);
575 ret
= hisi_zip_do_work(req
, qp_ctx
);
576 if (ret
!= -EINPROGRESS
)
577 hisi_zip_remove_req(qp_ctx
, req
);
582 static struct acomp_alg hisi_zip_acomp_zlib
= {
583 .init
= hisi_zip_acomp_init
,
584 .exit
= hisi_zip_acomp_exit
,
585 .compress
= hisi_zip_acompress
,
586 .decompress
= hisi_zip_adecompress
,
588 .cra_name
= "zlib-deflate",
589 .cra_driver_name
= "hisi-zlib-acomp",
590 .cra_module
= THIS_MODULE
,
591 .cra_priority
= HZIP_ALG_PRIORITY
,
592 .cra_ctxsize
= sizeof(struct hisi_zip_ctx
),
596 static struct acomp_alg hisi_zip_acomp_gzip
= {
597 .init
= hisi_zip_acomp_init
,
598 .exit
= hisi_zip_acomp_exit
,
599 .compress
= hisi_zip_acompress
,
600 .decompress
= hisi_zip_adecompress
,
603 .cra_driver_name
= "hisi-gzip-acomp",
604 .cra_module
= THIS_MODULE
,
605 .cra_priority
= HZIP_ALG_PRIORITY
,
606 .cra_ctxsize
= sizeof(struct hisi_zip_ctx
),
610 int hisi_zip_register_to_crypto(void)
614 ret
= crypto_register_acomp(&hisi_zip_acomp_zlib
);
616 pr_err("Zlib acomp algorithm registration failed\n");
620 ret
= crypto_register_acomp(&hisi_zip_acomp_gzip
);
622 pr_err("Gzip acomp algorithm registration failed\n");
623 crypto_unregister_acomp(&hisi_zip_acomp_zlib
);
629 void hisi_zip_unregister_from_crypto(void)
631 crypto_unregister_acomp(&hisi_zip_acomp_gzip
);
632 crypto_unregister_acomp(&hisi_zip_acomp_zlib
);