• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Driver for IBM PowerNV 842 compression accelerator
3  *
4  * Copyright (C) 2015 Dan Streetman, IBM Corp
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16 
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18 
19 #include "nx-842.h"
20 
21 #include <linux/timer.h>
22 
23 #include <asm/prom.h>
24 #include <asm/icswx.h>
25 
26 MODULE_LICENSE("GPL");
27 MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");
28 MODULE_DESCRIPTION("842 H/W Compression driver for IBM PowerNV processors");
29 MODULE_ALIAS_CRYPTO("842");
30 MODULE_ALIAS_CRYPTO("842-nx");
31 
32 #define WORKMEM_ALIGN	(CRB_ALIGN)
33 #define CSB_WAIT_MAX	(5000) /* ms */
34 
35 struct nx842_workmem {
36 	/* Below fields must be properly aligned */
37 	struct coprocessor_request_block crb; /* CRB_ALIGN align */
38 	struct data_descriptor_entry ddl_in[DDL_LEN_MAX]; /* DDE_ALIGN align */
39 	struct data_descriptor_entry ddl_out[DDL_LEN_MAX]; /* DDE_ALIGN align */
40 	/* Above fields must be properly aligned */
41 
42 	ktime_t start;
43 
44 	char padding[WORKMEM_ALIGN]; /* unused, to allow alignment */
45 } __packed __aligned(WORKMEM_ALIGN);
46 
47 struct nx842_coproc {
48 	unsigned int chip_id;
49 	unsigned int ct;
50 	unsigned int ci;
51 	struct list_head list;
52 };
53 
54 /* no cpu hotplug on powernv, so this list never changes after init */
55 static LIST_HEAD(nx842_coprocs);
56 static unsigned int nx842_ct;
57 
58 /**
59  * setup_indirect_dde - Setup an indirect DDE
60  *
61  * The DDE is setup with the the DDE count, byte count, and address of
62  * first direct DDE in the list.
63  */
setup_indirect_dde(struct data_descriptor_entry * dde,struct data_descriptor_entry * ddl,unsigned int dde_count,unsigned int byte_count)64 static void setup_indirect_dde(struct data_descriptor_entry *dde,
65 			       struct data_descriptor_entry *ddl,
66 			       unsigned int dde_count, unsigned int byte_count)
67 {
68 	dde->flags = 0;
69 	dde->count = dde_count;
70 	dde->index = 0;
71 	dde->length = cpu_to_be32(byte_count);
72 	dde->address = cpu_to_be64(nx842_get_pa(ddl));
73 }
74 
75 /**
76  * setup_direct_dde - Setup single DDE from buffer
77  *
78  * The DDE is setup with the buffer and length.  The buffer must be properly
79  * aligned.  The used length is returned.
80  * Returns:
81  *   N    Successfully set up DDE with N bytes
82  */
setup_direct_dde(struct data_descriptor_entry * dde,unsigned long pa,unsigned int len)83 static unsigned int setup_direct_dde(struct data_descriptor_entry *dde,
84 				     unsigned long pa, unsigned int len)
85 {
86 	unsigned int l = min_t(unsigned int, len, LEN_ON_PAGE(pa));
87 
88 	dde->flags = 0;
89 	dde->count = 0;
90 	dde->index = 0;
91 	dde->length = cpu_to_be32(l);
92 	dde->address = cpu_to_be64(pa);
93 
94 	return l;
95 }
96 
97 /**
98  * setup_ddl - Setup DDL from buffer
99  *
100  * Returns:
101  *   0		Successfully set up DDL
102  */
setup_ddl(struct data_descriptor_entry * dde,struct data_descriptor_entry * ddl,unsigned char * buf,unsigned int len,bool in)103 static int setup_ddl(struct data_descriptor_entry *dde,
104 		     struct data_descriptor_entry *ddl,
105 		     unsigned char *buf, unsigned int len,
106 		     bool in)
107 {
108 	unsigned long pa = nx842_get_pa(buf);
109 	int i, ret, total_len = len;
110 
111 	if (!IS_ALIGNED(pa, DDE_BUFFER_ALIGN)) {
112 		pr_debug("%s buffer pa 0x%lx not 0x%x-byte aligned\n",
113 			 in ? "input" : "output", pa, DDE_BUFFER_ALIGN);
114 		return -EINVAL;
115 	}
116 
117 	/* only need to check last mult; since buffer must be
118 	 * DDE_BUFFER_ALIGN aligned, and that is a multiple of
119 	 * DDE_BUFFER_SIZE_MULT, and pre-last page DDE buffers
120 	 * are guaranteed a multiple of DDE_BUFFER_SIZE_MULT.
121 	 */
122 	if (len % DDE_BUFFER_LAST_MULT) {
123 		pr_debug("%s buffer len 0x%x not a multiple of 0x%x\n",
124 			 in ? "input" : "output", len, DDE_BUFFER_LAST_MULT);
125 		if (in)
126 			return -EINVAL;
127 		len = round_down(len, DDE_BUFFER_LAST_MULT);
128 	}
129 
130 	/* use a single direct DDE */
131 	if (len <= LEN_ON_PAGE(pa)) {
132 		ret = setup_direct_dde(dde, pa, len);
133 		WARN_ON(ret < len);
134 		return 0;
135 	}
136 
137 	/* use the DDL */
138 	for (i = 0; i < DDL_LEN_MAX && len > 0; i++) {
139 		ret = setup_direct_dde(&ddl[i], pa, len);
140 		buf += ret;
141 		len -= ret;
142 		pa = nx842_get_pa(buf);
143 	}
144 
145 	if (len > 0) {
146 		pr_debug("0x%x total %s bytes 0x%x too many for DDL.\n",
147 			 total_len, in ? "input" : "output", len);
148 		if (in)
149 			return -EMSGSIZE;
150 		total_len -= len;
151 	}
152 	setup_indirect_dde(dde, ddl, i, total_len);
153 
154 	return 0;
155 }
156 
157 #define CSB_ERR(csb, msg, ...)					\
158 	pr_err("ERROR: " msg " : %02x %02x %02x %02x %08x\n",	\
159 	       ##__VA_ARGS__, (csb)->flags,			\
160 	       (csb)->cs, (csb)->cc, (csb)->ce,			\
161 	       be32_to_cpu((csb)->count))
162 
163 #define CSB_ERR_ADDR(csb, msg, ...)				\
164 	CSB_ERR(csb, msg " at %lx", ##__VA_ARGS__,		\
165 		(unsigned long)be64_to_cpu((csb)->address))
166 
167 /**
168  * wait_for_csb
169  */
wait_for_csb(struct nx842_workmem * wmem,struct coprocessor_status_block * csb)170 static int wait_for_csb(struct nx842_workmem *wmem,
171 			struct coprocessor_status_block *csb)
172 {
173 	ktime_t start = wmem->start, now = ktime_get();
174 	ktime_t timeout = ktime_add_ms(start, CSB_WAIT_MAX);
175 
176 	while (!(ACCESS_ONCE(csb->flags) & CSB_V)) {
177 		cpu_relax();
178 		now = ktime_get();
179 		if (ktime_after(now, timeout))
180 			break;
181 	}
182 
183 	/* hw has updated csb and output buffer */
184 	barrier();
185 
186 	/* check CSB flags */
187 	if (!(csb->flags & CSB_V)) {
188 		CSB_ERR(csb, "CSB still not valid after %ld us, giving up",
189 			(long)ktime_us_delta(now, start));
190 		return -ETIMEDOUT;
191 	}
192 	if (csb->flags & CSB_F) {
193 		CSB_ERR(csb, "Invalid CSB format");
194 		return -EPROTO;
195 	}
196 	if (csb->flags & CSB_CH) {
197 		CSB_ERR(csb, "Invalid CSB chaining state");
198 		return -EPROTO;
199 	}
200 
201 	/* verify CSB completion sequence is 0 */
202 	if (csb->cs) {
203 		CSB_ERR(csb, "Invalid CSB completion sequence");
204 		return -EPROTO;
205 	}
206 
207 	/* check CSB Completion Code */
208 	switch (csb->cc) {
209 	/* no error */
210 	case CSB_CC_SUCCESS:
211 		break;
212 	case CSB_CC_TPBC_GT_SPBC:
213 		/* not an error, but the compressed data is
214 		 * larger than the uncompressed data :(
215 		 */
216 		break;
217 
218 	/* input data errors */
219 	case CSB_CC_OPERAND_OVERLAP:
220 		/* input and output buffers overlap */
221 		CSB_ERR(csb, "Operand Overlap error");
222 		return -EINVAL;
223 	case CSB_CC_INVALID_OPERAND:
224 		CSB_ERR(csb, "Invalid operand");
225 		return -EINVAL;
226 	case CSB_CC_NOSPC:
227 		/* output buffer too small */
228 		return -ENOSPC;
229 	case CSB_CC_ABORT:
230 		CSB_ERR(csb, "Function aborted");
231 		return -EINTR;
232 	case CSB_CC_CRC_MISMATCH:
233 		CSB_ERR(csb, "CRC mismatch");
234 		return -EINVAL;
235 	case CSB_CC_TEMPL_INVALID:
236 		CSB_ERR(csb, "Compressed data template invalid");
237 		return -EINVAL;
238 	case CSB_CC_TEMPL_OVERFLOW:
239 		CSB_ERR(csb, "Compressed data template shows data past end");
240 		return -EINVAL;
241 
242 	/* these should not happen */
243 	case CSB_CC_INVALID_ALIGN:
244 		/* setup_ddl should have detected this */
245 		CSB_ERR_ADDR(csb, "Invalid alignment");
246 		return -EINVAL;
247 	case CSB_CC_DATA_LENGTH:
248 		/* setup_ddl should have detected this */
249 		CSB_ERR(csb, "Invalid data length");
250 		return -EINVAL;
251 	case CSB_CC_WR_TRANSLATION:
252 	case CSB_CC_TRANSLATION:
253 	case CSB_CC_TRANSLATION_DUP1:
254 	case CSB_CC_TRANSLATION_DUP2:
255 	case CSB_CC_TRANSLATION_DUP3:
256 	case CSB_CC_TRANSLATION_DUP4:
257 	case CSB_CC_TRANSLATION_DUP5:
258 	case CSB_CC_TRANSLATION_DUP6:
259 		/* should not happen, we use physical addrs */
260 		CSB_ERR_ADDR(csb, "Translation error");
261 		return -EPROTO;
262 	case CSB_CC_WR_PROTECTION:
263 	case CSB_CC_PROTECTION:
264 	case CSB_CC_PROTECTION_DUP1:
265 	case CSB_CC_PROTECTION_DUP2:
266 	case CSB_CC_PROTECTION_DUP3:
267 	case CSB_CC_PROTECTION_DUP4:
268 	case CSB_CC_PROTECTION_DUP5:
269 	case CSB_CC_PROTECTION_DUP6:
270 		/* should not happen, we use physical addrs */
271 		CSB_ERR_ADDR(csb, "Protection error");
272 		return -EPROTO;
273 	case CSB_CC_PRIVILEGE:
274 		/* shouldn't happen, we're in HYP mode */
275 		CSB_ERR(csb, "Insufficient Privilege error");
276 		return -EPROTO;
277 	case CSB_CC_EXCESSIVE_DDE:
278 		/* shouldn't happen, setup_ddl doesn't use many dde's */
279 		CSB_ERR(csb, "Too many DDEs in DDL");
280 		return -EINVAL;
281 	case CSB_CC_TRANSPORT:
282 		/* shouldn't happen, we setup CRB correctly */
283 		CSB_ERR(csb, "Invalid CRB");
284 		return -EINVAL;
285 	case CSB_CC_SEGMENTED_DDL:
286 		/* shouldn't happen, setup_ddl creates DDL right */
287 		CSB_ERR(csb, "Segmented DDL error");
288 		return -EINVAL;
289 	case CSB_CC_DDE_OVERFLOW:
290 		/* shouldn't happen, setup_ddl creates DDL right */
291 		CSB_ERR(csb, "DDE overflow error");
292 		return -EINVAL;
293 	case CSB_CC_SESSION:
294 		/* should not happen with ICSWX */
295 		CSB_ERR(csb, "Session violation error");
296 		return -EPROTO;
297 	case CSB_CC_CHAIN:
298 		/* should not happen, we don't use chained CRBs */
299 		CSB_ERR(csb, "Chained CRB error");
300 		return -EPROTO;
301 	case CSB_CC_SEQUENCE:
302 		/* should not happen, we don't use chained CRBs */
303 		CSB_ERR(csb, "CRB seqeunce number error");
304 		return -EPROTO;
305 	case CSB_CC_UNKNOWN_CODE:
306 		CSB_ERR(csb, "Unknown subfunction code");
307 		return -EPROTO;
308 
309 	/* hardware errors */
310 	case CSB_CC_RD_EXTERNAL:
311 	case CSB_CC_RD_EXTERNAL_DUP1:
312 	case CSB_CC_RD_EXTERNAL_DUP2:
313 	case CSB_CC_RD_EXTERNAL_DUP3:
314 		CSB_ERR_ADDR(csb, "Read error outside coprocessor");
315 		return -EPROTO;
316 	case CSB_CC_WR_EXTERNAL:
317 		CSB_ERR_ADDR(csb, "Write error outside coprocessor");
318 		return -EPROTO;
319 	case CSB_CC_INTERNAL:
320 		CSB_ERR(csb, "Internal error in coprocessor");
321 		return -EPROTO;
322 	case CSB_CC_PROVISION:
323 		CSB_ERR(csb, "Storage provision error");
324 		return -EPROTO;
325 	case CSB_CC_HW:
326 		CSB_ERR(csb, "Correctable hardware error");
327 		return -EPROTO;
328 
329 	default:
330 		CSB_ERR(csb, "Invalid CC %d", csb->cc);
331 		return -EPROTO;
332 	}
333 
334 	/* check Completion Extension state */
335 	if (csb->ce & CSB_CE_TERMINATION) {
336 		CSB_ERR(csb, "CSB request was terminated");
337 		return -EPROTO;
338 	}
339 	if (csb->ce & CSB_CE_INCOMPLETE) {
340 		CSB_ERR(csb, "CSB request not complete");
341 		return -EPROTO;
342 	}
343 	if (!(csb->ce & CSB_CE_TPBC)) {
344 		CSB_ERR(csb, "TPBC not provided, unknown target length");
345 		return -EPROTO;
346 	}
347 
348 	/* successful completion */
349 	pr_debug_ratelimited("Processed %u bytes in %lu us\n",
350 			     be32_to_cpu(csb->count),
351 			     (unsigned long)ktime_us_delta(now, start));
352 
353 	return 0;
354 }
355 
356 /**
357  * nx842_powernv_function - compress/decompress data using the 842 algorithm
358  *
359  * (De)compression provided by the NX842 coprocessor on IBM PowerNV systems.
360  * This compresses or decompresses the provided input buffer into the provided
361  * output buffer.
362  *
363  * Upon return from this function @outlen contains the length of the
364  * output data.  If there is an error then @outlen will be 0 and an
365  * error will be specified by the return code from this function.
366  *
367  * The @workmem buffer should only be used by one function call at a time.
368  *
369  * @in: input buffer pointer
370  * @inlen: input buffer size
371  * @out: output buffer pointer
372  * @outlenp: output buffer size pointer
373  * @workmem: working memory buffer pointer, size determined by
374  *           nx842_powernv_driver.workmem_size
375  * @fc: function code, see CCW Function Codes in nx-842.h
376  *
377  * Returns:
378  *   0		Success, output of length @outlenp stored in the buffer at @out
379  *   -ENODEV	Hardware unavailable
380  *   -ENOSPC	Output buffer is to small
381  *   -EMSGSIZE	Input buffer too large
382  *   -EINVAL	buffer constraints do not fix nx842_constraints
383  *   -EPROTO	hardware error during operation
384  *   -ETIMEDOUT	hardware did not complete operation in reasonable time
385  *   -EINTR	operation was aborted
386  */
nx842_powernv_function(const unsigned char * in,unsigned int inlen,unsigned char * out,unsigned int * outlenp,void * workmem,int fc)387 static int nx842_powernv_function(const unsigned char *in, unsigned int inlen,
388 				  unsigned char *out, unsigned int *outlenp,
389 				  void *workmem, int fc)
390 {
391 	struct coprocessor_request_block *crb;
392 	struct coprocessor_status_block *csb;
393 	struct nx842_workmem *wmem;
394 	int ret;
395 	u64 csb_addr;
396 	u32 ccw;
397 	unsigned int outlen = *outlenp;
398 
399 	wmem = PTR_ALIGN(workmem, WORKMEM_ALIGN);
400 
401 	*outlenp = 0;
402 
403 	/* shoudn't happen, we don't load without a coproc */
404 	if (!nx842_ct) {
405 		pr_err_ratelimited("coprocessor CT is 0");
406 		return -ENODEV;
407 	}
408 
409 	crb = &wmem->crb;
410 	csb = &crb->csb;
411 
412 	/* Clear any previous values */
413 	memset(crb, 0, sizeof(*crb));
414 
415 	/* set up DDLs */
416 	ret = setup_ddl(&crb->source, wmem->ddl_in,
417 			(unsigned char *)in, inlen, true);
418 	if (ret)
419 		return ret;
420 	ret = setup_ddl(&crb->target, wmem->ddl_out,
421 			out, outlen, false);
422 	if (ret)
423 		return ret;
424 
425 	/* set up CCW */
426 	ccw = 0;
427 	ccw = SET_FIELD(ccw, CCW_CT, nx842_ct);
428 	ccw = SET_FIELD(ccw, CCW_CI_842, 0); /* use 0 for hw auto-selection */
429 	ccw = SET_FIELD(ccw, CCW_FC_842, fc);
430 
431 	/* set up CRB's CSB addr */
432 	csb_addr = nx842_get_pa(csb) & CRB_CSB_ADDRESS;
433 	csb_addr |= CRB_CSB_AT; /* Addrs are phys */
434 	crb->csb_addr = cpu_to_be64(csb_addr);
435 
436 	wmem->start = ktime_get();
437 
438 	/* do ICSWX */
439 	ret = icswx(cpu_to_be32(ccw), crb);
440 
441 	pr_debug_ratelimited("icswx CR %x ccw %x crb->ccw %x\n", ret,
442 			     (unsigned int)ccw,
443 			     (unsigned int)be32_to_cpu(crb->ccw));
444 
445 	/*
446 	 * NX842 coprocessor sets 3rd bit in CR register with XER[S0].
447 	 * XER[S0] is the integer summary overflow bit which is nothing
448 	 * to do NX. Since this bit can be set with other return values,
449 	 * mask this bit.
450 	 */
451 	ret &= ~ICSWX_XERS0;
452 
453 	switch (ret) {
454 	case ICSWX_INITIATED:
455 		ret = wait_for_csb(wmem, csb);
456 		break;
457 	case ICSWX_BUSY:
458 		pr_debug_ratelimited("842 Coprocessor busy\n");
459 		ret = -EBUSY;
460 		break;
461 	case ICSWX_REJECTED:
462 		pr_err_ratelimited("ICSWX rejected\n");
463 		ret = -EPROTO;
464 		break;
465 	}
466 
467 	if (!ret)
468 		*outlenp = be32_to_cpu(csb->count);
469 
470 	return ret;
471 }
472 
473 /**
474  * nx842_powernv_compress - Compress data using the 842 algorithm
475  *
476  * Compression provided by the NX842 coprocessor on IBM PowerNV systems.
477  * The input buffer is compressed and the result is stored in the
478  * provided output buffer.
479  *
480  * Upon return from this function @outlen contains the length of the
481  * compressed data.  If there is an error then @outlen will be 0 and an
482  * error will be specified by the return code from this function.
483  *
484  * @in: input buffer pointer
485  * @inlen: input buffer size
486  * @out: output buffer pointer
487  * @outlenp: output buffer size pointer
488  * @workmem: working memory buffer pointer, size determined by
489  *           nx842_powernv_driver.workmem_size
490  *
491  * Returns: see @nx842_powernv_function()
492  */
nx842_powernv_compress(const unsigned char * in,unsigned int inlen,unsigned char * out,unsigned int * outlenp,void * wmem)493 static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen,
494 				  unsigned char *out, unsigned int *outlenp,
495 				  void *wmem)
496 {
497 	return nx842_powernv_function(in, inlen, out, outlenp,
498 				      wmem, CCW_FC_842_COMP_CRC);
499 }
500 
501 /**
502  * nx842_powernv_decompress - Decompress data using the 842 algorithm
503  *
504  * Decompression provided by the NX842 coprocessor on IBM PowerNV systems.
505  * The input buffer is decompressed and the result is stored in the
506  * provided output buffer.
507  *
508  * Upon return from this function @outlen contains the length of the
509  * decompressed data.  If there is an error then @outlen will be 0 and an
510  * error will be specified by the return code from this function.
511  *
512  * @in: input buffer pointer
513  * @inlen: input buffer size
514  * @out: output buffer pointer
515  * @outlenp: output buffer size pointer
516  * @workmem: working memory buffer pointer, size determined by
517  *           nx842_powernv_driver.workmem_size
518  *
519  * Returns: see @nx842_powernv_function()
520  */
nx842_powernv_decompress(const unsigned char * in,unsigned int inlen,unsigned char * out,unsigned int * outlenp,void * wmem)521 static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen,
522 				    unsigned char *out, unsigned int *outlenp,
523 				    void *wmem)
524 {
525 	return nx842_powernv_function(in, inlen, out, outlenp,
526 				      wmem, CCW_FC_842_DECOMP_CRC);
527 }
528 
nx842_powernv_probe(struct device_node * dn)529 static int __init nx842_powernv_probe(struct device_node *dn)
530 {
531 	struct nx842_coproc *coproc;
532 	struct property *ct_prop, *ci_prop;
533 	unsigned int ct, ci;
534 	int chip_id;
535 
536 	chip_id = of_get_ibm_chip_id(dn);
537 	if (chip_id < 0) {
538 		pr_err("ibm,chip-id missing\n");
539 		return -EINVAL;
540 	}
541 	ct_prop = of_find_property(dn, "ibm,842-coprocessor-type", NULL);
542 	if (!ct_prop) {
543 		pr_err("ibm,842-coprocessor-type missing\n");
544 		return -EINVAL;
545 	}
546 	ct = be32_to_cpu(*(unsigned int *)ct_prop->value);
547 	ci_prop = of_find_property(dn, "ibm,842-coprocessor-instance", NULL);
548 	if (!ci_prop) {
549 		pr_err("ibm,842-coprocessor-instance missing\n");
550 		return -EINVAL;
551 	}
552 	ci = be32_to_cpu(*(unsigned int *)ci_prop->value);
553 
554 	coproc = kmalloc(sizeof(*coproc), GFP_KERNEL);
555 	if (!coproc)
556 		return -ENOMEM;
557 
558 	coproc->chip_id = chip_id;
559 	coproc->ct = ct;
560 	coproc->ci = ci;
561 	INIT_LIST_HEAD(&coproc->list);
562 	list_add(&coproc->list, &nx842_coprocs);
563 
564 	pr_info("coprocessor found on chip %d, CT %d CI %d\n", chip_id, ct, ci);
565 
566 	if (!nx842_ct)
567 		nx842_ct = ct;
568 	else if (nx842_ct != ct)
569 		pr_err("NX842 chip %d, CT %d != first found CT %d\n",
570 		       chip_id, ct, nx842_ct);
571 
572 	return 0;
573 }
574 
575 static struct nx842_constraints nx842_powernv_constraints = {
576 	.alignment =	DDE_BUFFER_ALIGN,
577 	.multiple =	DDE_BUFFER_LAST_MULT,
578 	.minimum =	DDE_BUFFER_LAST_MULT,
579 	.maximum =	(DDL_LEN_MAX - 1) * PAGE_SIZE,
580 };
581 
582 static struct nx842_driver nx842_powernv_driver = {
583 	.name =		KBUILD_MODNAME,
584 	.owner =	THIS_MODULE,
585 	.workmem_size =	sizeof(struct nx842_workmem),
586 	.constraints =	&nx842_powernv_constraints,
587 	.compress =	nx842_powernv_compress,
588 	.decompress =	nx842_powernv_decompress,
589 };
590 
nx842_powernv_crypto_init(struct crypto_tfm * tfm)591 static int nx842_powernv_crypto_init(struct crypto_tfm *tfm)
592 {
593 	return nx842_crypto_init(tfm, &nx842_powernv_driver);
594 }
595 
596 static struct crypto_alg nx842_powernv_alg = {
597 	.cra_name		= "842",
598 	.cra_driver_name	= "842-nx",
599 	.cra_priority		= 300,
600 	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
601 	.cra_ctxsize		= sizeof(struct nx842_crypto_ctx),
602 	.cra_module		= THIS_MODULE,
603 	.cra_init		= nx842_powernv_crypto_init,
604 	.cra_exit		= nx842_crypto_exit,
605 	.cra_u			= { .compress = {
606 	.coa_compress		= nx842_crypto_compress,
607 	.coa_decompress		= nx842_crypto_decompress } }
608 };
609 
nx842_powernv_init(void)610 static __init int nx842_powernv_init(void)
611 {
612 	struct device_node *dn;
613 	int ret;
614 
615 	/* verify workmem size/align restrictions */
616 	BUILD_BUG_ON(WORKMEM_ALIGN % CRB_ALIGN);
617 	BUILD_BUG_ON(CRB_ALIGN % DDE_ALIGN);
618 	BUILD_BUG_ON(CRB_SIZE % DDE_ALIGN);
619 	/* verify buffer size/align restrictions */
620 	BUILD_BUG_ON(PAGE_SIZE % DDE_BUFFER_ALIGN);
621 	BUILD_BUG_ON(DDE_BUFFER_ALIGN % DDE_BUFFER_SIZE_MULT);
622 	BUILD_BUG_ON(DDE_BUFFER_SIZE_MULT % DDE_BUFFER_LAST_MULT);
623 
624 	for_each_compatible_node(dn, NULL, "ibm,power-nx")
625 		nx842_powernv_probe(dn);
626 
627 	if (!nx842_ct)
628 		return -ENODEV;
629 
630 	ret = crypto_register_alg(&nx842_powernv_alg);
631 	if (ret) {
632 		struct nx842_coproc *coproc, *n;
633 
634 		list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) {
635 			list_del(&coproc->list);
636 			kfree(coproc);
637 		}
638 
639 		return ret;
640 	}
641 
642 	return 0;
643 }
644 module_init(nx842_powernv_init);
645 
nx842_powernv_exit(void)646 static void __exit nx842_powernv_exit(void)
647 {
648 	struct nx842_coproc *coproc, *n;
649 
650 	crypto_unregister_alg(&nx842_powernv_alg);
651 
652 	list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) {
653 		list_del(&coproc->list);
654 		kfree(coproc);
655 	}
656 }
657 module_exit(nx842_powernv_exit);
658