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