aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorDan Streetman <ddstreet@ieee.org>2015-05-07 13:49:21 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-05-11 03:06:48 -0400
commited70b479c2c0b6e1319f0cb2de19f1051be219a4 (patch)
tree1ab8c03ff10b05133a8875913d027cb77836ad5a /drivers/crypto
parentb8e04187c90107c58d1ccbeb68a0ba4c5bfd4167 (diff)
crypto: nx - add hardware 842 crypto comp alg
Add crypto compression alg for 842 hardware compression and decompression, using the alg name "842" and driver_name "842-nx". This uses only the PowerPC coprocessor hardware for 842 compression. It also uses the hardware for decompression, but if the hardware fails it will fall back to the 842 software decompression library, so that decompression never fails (for valid 842 compressed buffers). A header must be used in most cases, due to the hardware's restrictions on the buffers being specifically aligned and sized. Due to the header this driver adds, compressed buffers it creates cannot be directly passed to the 842 software library for decompression. However, compressed buffers created by the software 842 library can be passed to this driver for hardware 842 decompression (with the exception of buffers containing the "short data" template, as lib/842/842.h explains). Signed-off-by: Dan Streetman <ddstreet@ieee.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/nx/Kconfig10
-rw-r--r--drivers/crypto/nx/Makefile2
-rw-r--r--drivers/crypto/nx/nx-842-crypto.c585
3 files changed, 597 insertions, 0 deletions
diff --git a/drivers/crypto/nx/Kconfig b/drivers/crypto/nx/Kconfig
index ee9e25956241..3e621ad09675 100644
--- a/drivers/crypto/nx/Kconfig
+++ b/drivers/crypto/nx/Kconfig
@@ -50,4 +50,14 @@ config CRYPTO_DEV_NX_COMPRESS_POWERNV
50 algorithm. This supports NX hardware on the PowerNV platform. 50 algorithm. This supports NX hardware on the PowerNV platform.
51 If you choose 'M' here, this module will be called nx_compress_powernv. 51 If you choose 'M' here, this module will be called nx_compress_powernv.
52 52
53config CRYPTO_DEV_NX_COMPRESS_CRYPTO
54 tristate "Compression acceleration cryptographic interface"
55 select CRYPTO_ALGAPI
56 select 842_DECOMPRESS
57 default y
58 help
59 Support for PowerPC Nest (NX) accelerators using the cryptographic
60 API. If you choose 'M' here, this module will be called
61 nx_compress_crypto.
62
53endif 63endif
diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile
index 6619787423b3..868b5e630794 100644
--- a/drivers/crypto/nx/Makefile
+++ b/drivers/crypto/nx/Makefile
@@ -13,6 +13,8 @@ nx-crypto-objs := nx.o \
13obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS) += nx-compress.o 13obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS) += nx-compress.o
14obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o 14obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o
15obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o 15obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o
16obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_CRYPTO) += nx-compress-crypto.o
16nx-compress-objs := nx-842.o 17nx-compress-objs := nx-842.o
17nx-compress-pseries-objs := nx-842-pseries.o 18nx-compress-pseries-objs := nx-842-pseries.o
18nx-compress-powernv-objs := nx-842-powernv.o 19nx-compress-powernv-objs := nx-842-powernv.o
20nx-compress-crypto-objs := nx-842-crypto.o
diff --git a/drivers/crypto/nx/nx-842-crypto.c b/drivers/crypto/nx/nx-842-crypto.c
new file mode 100644
index 000000000000..cb177c317179
--- /dev/null
+++ b/drivers/crypto/nx/nx-842-crypto.c
@@ -0,0 +1,585 @@
1/*
2 * Cryptographic API for the NX-842 hardware compression.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * Copyright (C) IBM Corporation, 2011-2015
15 *
16 * Original Authors: Robert Jennings <rcj@linux.vnet.ibm.com>
17 * Seth Jennings <sjenning@linux.vnet.ibm.com>
18 *
19 * Rewrite: Dan Streetman <ddstreet@ieee.org>
20 *
21 * This is an interface to the NX-842 compression hardware in PowerPC
22 * processors. Most of the complexity of this drvier is due to the fact that
23 * the NX-842 compression hardware requires the input and output data buffers
24 * to be specifically aligned, to be a specific multiple in length, and within
25 * specific minimum and maximum lengths. Those restrictions, provided by the
26 * nx-842 driver via nx842_constraints, mean this driver must use bounce
27 * buffers and headers to correct misaligned in or out buffers, and to split
28 * input buffers that are too large.
29 *
30 * This driver will fall back to software decompression if the hardware
31 * decompression fails, so this driver's decompression should never fail as
32 * long as the provided compressed buffer is valid. Any compressed buffer
33 * created by this driver will have a header (except ones where the input
34 * perfectly matches the constraints); so users of this driver cannot simply
35 * pass a compressed buffer created by this driver over to the 842 software
36 * decompression library. Instead, users must use this driver to decompress;
37 * if the hardware fails or is unavailable, the compressed buffer will be
38 * parsed and the header removed, and the raw 842 buffer(s) passed to the 842
39 * software decompression library.
40 *
41 * This does not fall back to software compression, however, since the caller
42 * of this function is specifically requesting hardware compression; if the
43 * hardware compression fails, the caller can fall back to software
44 * compression, and the raw 842 compressed buffer that the software compressor
45 * creates can be passed to this driver for hardware decompression; any
46 * buffer without our specific header magic is assumed to be a raw 842 buffer
47 * and passed directly to the hardware. Note that the software compression
48 * library will produce a compressed buffer that is incompatible with the
49 * hardware decompressor if the original input buffer length is not a multiple
50 * of 8; if such a compressed buffer is passed to this driver for
51 * decompression, the hardware will reject it and this driver will then pass
52 * it over to the software library for decompression.
53 */
54
55#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
56
57#include <linux/init.h>
58#include <linux/module.h>
59#include <linux/crypto.h>
60#include <linux/vmalloc.h>
61#include <linux/nx842.h>
62#include <linux/sw842.h>
63#include <linux/ratelimit.h>
64
65/* The first 5 bits of this magic are 0x1f, which is an invalid 842 5-bit
66 * template (see lib/842/842.h), so this magic number will never appear at
67 * the start of a raw 842 compressed buffer. That is important, as any buffer
68 * passed to us without this magic is assumed to be a raw 842 compressed
69 * buffer, and passed directly to the hardware to decompress.
70 */
71#define NX842_CRYPTO_MAGIC (0xf842)
72#define NX842_CRYPTO_GROUP_MAX (0x20)
73#define NX842_CRYPTO_HEADER_SIZE(g) \
74 (sizeof(struct nx842_crypto_header) + \
75 sizeof(struct nx842_crypto_header_group) * (g))
76#define NX842_CRYPTO_HEADER_MAX_SIZE \
77 NX842_CRYPTO_HEADER_SIZE(NX842_CRYPTO_GROUP_MAX)
78
79/* bounce buffer size */
80#define BOUNCE_BUFFER_ORDER (2)
81#define BOUNCE_BUFFER_SIZE \
82 ((unsigned int)(PAGE_SIZE << BOUNCE_BUFFER_ORDER))
83
84/* try longer on comp because we can fallback to sw decomp if hw is busy */
85#define COMP_BUSY_TIMEOUT (250) /* ms */
86#define DECOMP_BUSY_TIMEOUT (50) /* ms */
87
88struct nx842_crypto_header_group {
89 __be16 padding; /* unused bytes at start of group */
90 __be32 compressed_length; /* compressed bytes in group */
91 __be32 uncompressed_length; /* bytes after decompression */
92} __packed;
93
94struct nx842_crypto_header {
95 __be16 magic; /* NX842_CRYPTO_MAGIC */
96 __be16 ignore; /* decompressed end bytes to ignore */
97 u8 groups; /* total groups in this header */
98 struct nx842_crypto_header_group group[];
99} __packed;
100
101struct nx842_crypto_param {
102 u8 *in;
103 unsigned int iremain;
104 u8 *out;
105 unsigned int oremain;
106 unsigned int ototal;
107};
108
109static int update_param(struct nx842_crypto_param *p,
110 unsigned int slen, unsigned int dlen)
111{
112 if (p->iremain < slen)
113 return -EOVERFLOW;
114 if (p->oremain < dlen)
115 return -ENOSPC;
116
117 p->in += slen;
118 p->iremain -= slen;
119 p->out += dlen;
120 p->oremain -= dlen;
121 p->ototal += dlen;
122
123 return 0;
124}
125
126struct nx842_crypto_ctx {
127 u8 *wmem;
128 u8 *sbounce, *dbounce;
129
130 struct nx842_crypto_header header;
131 struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
132};
133
134static int nx842_crypto_init(struct crypto_tfm *tfm)
135{
136 struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
137
138 ctx->wmem = kmalloc(NX842_MEM_COMPRESS, GFP_KERNEL);
139 ctx->sbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER);
140 ctx->dbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER);
141 if (!ctx->wmem || !ctx->sbounce || !ctx->dbounce) {
142 kfree(ctx->wmem);
143 free_page((unsigned long)ctx->sbounce);
144 free_page((unsigned long)ctx->dbounce);
145 return -ENOMEM;
146 }
147
148 return 0;
149}
150
151static void nx842_crypto_exit(struct crypto_tfm *tfm)
152{
153 struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
154
155 kfree(ctx->wmem);
156 free_page((unsigned long)ctx->sbounce);
157 free_page((unsigned long)ctx->dbounce);
158}
159
160static int read_constraints(struct nx842_constraints *c)
161{
162 int ret;
163
164 ret = nx842_constraints(c);
165 if (ret) {
166 pr_err_ratelimited("could not get nx842 constraints : %d\n",
167 ret);
168 return ret;
169 }
170
171 /* limit maximum, to always have enough bounce buffer to decompress */
172 if (c->maximum > BOUNCE_BUFFER_SIZE) {
173 c->maximum = BOUNCE_BUFFER_SIZE;
174 pr_info_once("limiting nx842 maximum to %x\n", c->maximum);
175 }
176
177 return 0;
178}
179
180static int nx842_crypto_add_header(struct nx842_crypto_header *hdr, u8 *buf)
181{
182 int s = NX842_CRYPTO_HEADER_SIZE(hdr->groups);
183
184 /* compress should have added space for header */
185 if (s > be16_to_cpu(hdr->group[0].padding)) {
186 pr_err("Internal error: no space for header\n");
187 return -EINVAL;
188 }
189
190 memcpy(buf, hdr, s);
191
192 print_hex_dump_debug("header ", DUMP_PREFIX_OFFSET, 16, 1, buf, s, 0);
193
194 return 0;
195}
196
197static int compress(struct nx842_crypto_ctx *ctx,
198 struct nx842_crypto_param *p,
199 struct nx842_crypto_header_group *g,
200 struct nx842_constraints *c,
201 u16 *ignore,
202 unsigned int hdrsize)
203{
204 unsigned int slen = p->iremain, dlen = p->oremain, tmplen;
205 unsigned int adj_slen = slen;
206 u8 *src = p->in, *dst = p->out;
207 int ret, dskip = 0;
208 ktime_t timeout;
209
210 if (p->iremain == 0)
211 return -EOVERFLOW;
212
213 if (p->oremain == 0 || hdrsize + c->minimum > dlen)
214 return -ENOSPC;
215
216 if (slen % c->multiple)
217 adj_slen = round_up(slen, c->multiple);
218 if (slen < c->minimum)
219 adj_slen = c->minimum;
220 if (slen > c->maximum)
221 adj_slen = slen = c->maximum;
222 if (adj_slen > slen || (u64)src % c->alignment) {
223 adj_slen = min(adj_slen, BOUNCE_BUFFER_SIZE);
224 slen = min(slen, BOUNCE_BUFFER_SIZE);
225 if (adj_slen > slen)
226 memset(ctx->sbounce + slen, 0, adj_slen - slen);
227 memcpy(ctx->sbounce, src, slen);
228 src = ctx->sbounce;
229 slen = adj_slen;
230 pr_debug("using comp sbounce buffer, len %x\n", slen);
231 }
232
233 dst += hdrsize;
234 dlen -= hdrsize;
235
236 if ((u64)dst % c->alignment) {
237 dskip = (int)(PTR_ALIGN(dst, c->alignment) - dst);
238 dst += dskip;
239 dlen -= dskip;
240 }
241 if (dlen % c->multiple)
242 dlen = round_down(dlen, c->multiple);
243 if (dlen < c->minimum) {
244nospc:
245 dst = ctx->dbounce;
246 dlen = min(p->oremain, BOUNCE_BUFFER_SIZE);
247 dlen = round_down(dlen, c->multiple);
248 dskip = 0;
249 pr_debug("using comp dbounce buffer, len %x\n", dlen);
250 }
251 if (dlen > c->maximum)
252 dlen = c->maximum;
253
254 tmplen = dlen;
255 timeout = ktime_add_ms(ktime_get(), COMP_BUSY_TIMEOUT);
256 do {
257 dlen = tmplen; /* reset dlen, if we're retrying */
258 ret = nx842_compress(src, slen, dst, &dlen, ctx->wmem);
259 /* possibly we should reduce the slen here, instead of
260 * retrying with the dbounce buffer?
261 */
262 if (ret == -ENOSPC && dst != ctx->dbounce)
263 goto nospc;
264 } while (ret == -EBUSY && ktime_before(ktime_get(), timeout));
265 if (ret)
266 return ret;
267
268 dskip += hdrsize;
269
270 if (dst == ctx->dbounce)
271 memcpy(p->out + dskip, dst, dlen);
272
273 g->padding = cpu_to_be16(dskip);
274 g->compressed_length = cpu_to_be32(dlen);
275 g->uncompressed_length = cpu_to_be32(slen);
276
277 if (p->iremain < slen) {
278 *ignore = slen - p->iremain;
279 slen = p->iremain;
280 }
281
282 pr_debug("compress slen %x ignore %x dlen %x padding %x\n",
283 slen, *ignore, dlen, dskip);
284
285 return update_param(p, slen, dskip + dlen);
286}
287
288static int nx842_crypto_compress(struct crypto_tfm *tfm,
289 const u8 *src, unsigned int slen,
290 u8 *dst, unsigned int *dlen)
291{
292 struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
293 struct nx842_crypto_header *hdr = &ctx->header;
294 struct nx842_crypto_param p;
295 struct nx842_constraints c;
296 unsigned int groups, hdrsize, h;
297 int ret, n;
298 bool add_header;
299 u16 ignore = 0;
300
301 if (!tfm || !src || !slen || !dst || !dlen)
302 return -EINVAL;
303
304 p.in = (u8 *)src;
305 p.iremain = slen;
306 p.out = dst;
307 p.oremain = *dlen;
308 p.ototal = 0;
309
310 *dlen = 0;
311
312 ret = read_constraints(&c);
313 if (ret)
314 return ret;
315
316 groups = min_t(unsigned int, NX842_CRYPTO_GROUP_MAX,
317 DIV_ROUND_UP(p.iremain, c.maximum));
318 hdrsize = NX842_CRYPTO_HEADER_SIZE(groups);
319
320 /* skip adding header if the buffers meet all constraints */
321 add_header = (p.iremain % c.multiple ||
322 p.iremain < c.minimum ||
323 p.iremain > c.maximum ||
324 (u64)p.in % c.alignment ||
325 p.oremain % c.multiple ||
326 p.oremain < c.minimum ||
327 p.oremain > c.maximum ||
328 (u64)p.out % c.alignment);
329
330 hdr->magic = cpu_to_be16(NX842_CRYPTO_MAGIC);
331 hdr->groups = 0;
332 hdr->ignore = 0;
333
334 while (p.iremain > 0) {
335 n = hdr->groups++;
336 if (hdr->groups > NX842_CRYPTO_GROUP_MAX)
337 return -ENOSPC;
338
339 /* header goes before first group */
340 h = !n && add_header ? hdrsize : 0;
341
342 if (ignore)
343 pr_warn("interal error, ignore is set %x\n", ignore);
344
345 ret = compress(ctx, &p, &hdr->group[n], &c, &ignore, h);
346 if (ret)
347 return ret;
348 }
349
350 if (!add_header && hdr->groups > 1) {
351 pr_err("Internal error: No header but multiple groups\n");
352 return -EINVAL;
353 }
354
355 /* ignore indicates the input stream needed to be padded */
356 hdr->ignore = cpu_to_be16(ignore);
357 if (ignore)
358 pr_debug("marked %d bytes as ignore\n", ignore);
359
360 if (add_header)
361 ret = nx842_crypto_add_header(hdr, dst);
362 if (ret)
363 return ret;
364
365 *dlen = p.ototal;
366
367 pr_debug("compress total slen %x dlen %x\n", slen, *dlen);
368
369 return 0;
370}
371
372static int decompress(struct nx842_crypto_ctx *ctx,
373 struct nx842_crypto_param *p,
374 struct nx842_crypto_header_group *g,
375 struct nx842_constraints *c,
376 u16 ignore,
377 bool usehw)
378{
379 unsigned int slen = be32_to_cpu(g->compressed_length);
380 unsigned int required_len = be32_to_cpu(g->uncompressed_length);
381 unsigned int dlen = p->oremain, tmplen;
382 unsigned int adj_slen = slen;
383 u8 *src = p->in, *dst = p->out;
384 u16 padding = be16_to_cpu(g->padding);
385 int ret, spadding = 0, dpadding = 0;
386 ktime_t timeout;
387
388 if (!slen || !required_len)
389 return -EINVAL;
390
391 if (p->iremain <= 0 || padding + slen > p->iremain)
392 return -EOVERFLOW;
393
394 if (p->oremain <= 0 || required_len - ignore > p->oremain)
395 return -ENOSPC;
396
397 src += padding;
398
399 if (!usehw)
400 goto usesw;
401
402 if (slen % c->multiple)
403 adj_slen = round_up(slen, c->multiple);
404 if (slen < c->minimum)
405 adj_slen = c->minimum;
406 if (slen > c->maximum)
407 goto usesw;
408 if (slen < adj_slen || (u64)src % c->alignment) {
409 /* we can append padding bytes because the 842 format defines
410 * an "end" template (see lib/842/842_decompress.c) and will
411 * ignore any bytes following it.
412 */
413 if (slen < adj_slen)
414 memset(ctx->sbounce + slen, 0, adj_slen - slen);
415 memcpy(ctx->sbounce, src, slen);
416 src = ctx->sbounce;
417 spadding = adj_slen - slen;
418 slen = adj_slen;
419 pr_debug("using decomp sbounce buffer, len %x\n", slen);
420 }
421
422 if (dlen % c->multiple)
423 dlen = round_down(dlen, c->multiple);
424 if (dlen < required_len || (u64)dst % c->alignment) {
425 dst = ctx->dbounce;
426 dlen = min(required_len, BOUNCE_BUFFER_SIZE);
427 pr_debug("using decomp dbounce buffer, len %x\n", dlen);
428 }
429 if (dlen < c->minimum)
430 goto usesw;
431 if (dlen > c->maximum)
432 dlen = c->maximum;
433
434 tmplen = dlen;
435 timeout = ktime_add_ms(ktime_get(), DECOMP_BUSY_TIMEOUT);
436 do {
437 dlen = tmplen; /* reset dlen, if we're retrying */
438 ret = nx842_decompress(src, slen, dst, &dlen, ctx->wmem);
439 } while (ret == -EBUSY && ktime_before(ktime_get(), timeout));
440 if (ret) {
441usesw:
442 /* reset everything, sw doesn't have constraints */
443 src = p->in + padding;
444 slen = be32_to_cpu(g->compressed_length);
445 spadding = 0;
446 dst = p->out;
447 dlen = p->oremain;
448 dpadding = 0;
449 if (dlen < required_len) { /* have ignore bytes */
450 dst = ctx->dbounce;
451 dlen = BOUNCE_BUFFER_SIZE;
452 }
453 pr_info_ratelimited("using software 842 decompression\n");
454 ret = sw842_decompress(src, slen, dst, &dlen);
455 }
456 if (ret)
457 return ret;
458
459 slen -= spadding;
460
461 dlen -= ignore;
462 if (ignore)
463 pr_debug("ignoring last %x bytes\n", ignore);
464
465 if (dst == ctx->dbounce)
466 memcpy(p->out, dst, dlen);
467
468 pr_debug("decompress slen %x padding %x dlen %x ignore %x\n",
469 slen, padding, dlen, ignore);
470
471 return update_param(p, slen + padding, dlen);
472}
473
474static int nx842_crypto_decompress(struct crypto_tfm *tfm,
475 const u8 *src, unsigned int slen,
476 u8 *dst, unsigned int *dlen)
477{
478 struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
479 struct nx842_crypto_header *hdr;
480 struct nx842_crypto_param p;
481 struct nx842_constraints c;
482 int n, ret, hdr_len;
483 u16 ignore = 0;
484 bool usehw = true;
485
486 if (!tfm || !src || !slen || !dst || !dlen)
487 return -EINVAL;
488
489 p.in = (u8 *)src;
490 p.iremain = slen;
491 p.out = dst;
492 p.oremain = *dlen;
493 p.ototal = 0;
494
495 *dlen = 0;
496
497 if (read_constraints(&c))
498 usehw = false;
499
500 hdr = (struct nx842_crypto_header *)src;
501
502 /* If it doesn't start with our header magic number, assume it's a raw
503 * 842 compressed buffer and pass it directly to the hardware driver
504 */
505 if (be16_to_cpu(hdr->magic) != NX842_CRYPTO_MAGIC) {
506 struct nx842_crypto_header_group g = {
507 .padding = 0,
508 .compressed_length = cpu_to_be32(p.iremain),
509 .uncompressed_length = cpu_to_be32(p.oremain),
510 };
511
512 ret = decompress(ctx, &p, &g, &c, 0, usehw);
513 if (ret)
514 return ret;
515
516 *dlen = p.ototal;
517
518 return 0;
519 }
520
521 if (!hdr->groups) {
522 pr_err("header has no groups\n");
523 return -EINVAL;
524 }
525 if (hdr->groups > NX842_CRYPTO_GROUP_MAX) {
526 pr_err("header has too many groups %x, max %x\n",
527 hdr->groups, NX842_CRYPTO_GROUP_MAX);
528 return -EINVAL;
529 }
530
531 hdr_len = NX842_CRYPTO_HEADER_SIZE(hdr->groups);
532 if (hdr_len > slen)
533 return -EOVERFLOW;
534
535 memcpy(&ctx->header, src, hdr_len);
536 hdr = &ctx->header;
537
538 for (n = 0; n < hdr->groups; n++) {
539 /* ignore applies to last group */
540 if (n + 1 == hdr->groups)
541 ignore = be16_to_cpu(hdr->ignore);
542
543 ret = decompress(ctx, &p, &hdr->group[n], &c, ignore, usehw);
544 if (ret)
545 return ret;
546 }
547
548 *dlen = p.ototal;
549
550 pr_debug("decompress total slen %x dlen %x\n", slen, *dlen);
551
552 return 0;
553}
554
555static struct crypto_alg alg = {
556 .cra_name = "842",
557 .cra_driver_name = "842-nx",
558 .cra_priority = 300,
559 .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
560 .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
561 .cra_module = THIS_MODULE,
562 .cra_init = nx842_crypto_init,
563 .cra_exit = nx842_crypto_exit,
564 .cra_u = { .compress = {
565 .coa_compress = nx842_crypto_compress,
566 .coa_decompress = nx842_crypto_decompress } }
567};
568
569static int __init nx842_crypto_mod_init(void)
570{
571 return crypto_register_alg(&alg);
572}
573module_init(nx842_crypto_mod_init);
574
575static void __exit nx842_crypto_mod_exit(void)
576{
577 crypto_unregister_alg(&alg);
578}
579module_exit(nx842_crypto_mod_exit);
580
581MODULE_LICENSE("GPL");
582MODULE_DESCRIPTION("IBM PowerPC Nest (NX) 842 Hardware Compression Interface");
583MODULE_ALIAS_CRYPTO("842");
584MODULE_ALIAS_CRYPTO("842-nx");
585MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");