aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Streetman <ddstreet@ieee.org>2015-05-07 13:49:19 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-05-11 03:06:47 -0400
commit99182a42b7ef3d5e4180992ce01befd9e87526d2 (patch)
tree56b0d4e29202a01f0c400b8a2db12ad29eaa11e4
parent959e6659b6f74ec1fa4d391a3b88d63dc0189f36 (diff)
crypto: nx - add PowerNV platform NX-842 driver
Add driver for NX-842 hardware on the PowerNV platform. This allows the use of the 842 compression hardware coprocessor on the PowerNV platform. Signed-off-by: Dan Streetman <ddstreet@ieee.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/nx/Kconfig10
-rw-r--r--drivers/crypto/nx/Makefile2
-rw-r--r--drivers/crypto/nx/nx-842-powernv.c625
-rw-r--r--drivers/crypto/nx/nx-842-pseries.c9
-rw-r--r--drivers/crypto/nx/nx-842.c4
-rw-r--r--drivers/crypto/nx/nx-842.h97
-rw-r--r--include/linux/nx842.h6
7 files changed, 741 insertions, 12 deletions
diff --git a/drivers/crypto/nx/Kconfig b/drivers/crypto/nx/Kconfig
index 34013f7d46c8..ee9e25956241 100644
--- a/drivers/crypto/nx/Kconfig
+++ b/drivers/crypto/nx/Kconfig
@@ -40,4 +40,14 @@ config CRYPTO_DEV_NX_COMPRESS_PSERIES
40 algorithm. This supports NX hardware on the pSeries platform. 40 algorithm. This supports NX hardware on the pSeries platform.
41 If you choose 'M' here, this module will be called nx_compress_pseries. 41 If you choose 'M' here, this module will be called nx_compress_pseries.
42 42
43config CRYPTO_DEV_NX_COMPRESS_POWERNV
44 tristate "Compression acceleration support on PowerNV platform"
45 depends on PPC_POWERNV
46 default y
47 help
48 Support for PowerPC Nest (NX) compression acceleration. This
49 module supports acceleration for compressing memory with the 842
50 algorithm. This supports NX hardware on the PowerNV platform.
51 If you choose 'M' here, this module will be called nx_compress_powernv.
52
43endif 53endif
diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile
index 5d9f4bc15209..6619787423b3 100644
--- a/drivers/crypto/nx/Makefile
+++ b/drivers/crypto/nx/Makefile
@@ -12,5 +12,7 @@ nx-crypto-objs := nx.o \
12 12
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
15nx-compress-objs := nx-842.o 16nx-compress-objs := nx-842.o
16nx-compress-pseries-objs := nx-842-pseries.o 17nx-compress-pseries-objs := nx-842-pseries.o
18nx-compress-powernv-objs := nx-842-powernv.o
diff --git a/drivers/crypto/nx/nx-842-powernv.c b/drivers/crypto/nx/nx-842-powernv.c
new file mode 100644
index 000000000000..6a9fb8b2d05b
--- /dev/null
+++ b/drivers/crypto/nx/nx-842-powernv.c
@@ -0,0 +1,625 @@
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#define MODULE_NAME NX842_POWERNV_MODULE_NAME
27MODULE_LICENSE("GPL");
28MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");
29MODULE_DESCRIPTION("842 H/W Compression driver for IBM PowerNV processors");
30
31#define WORKMEM_ALIGN (CRB_ALIGN)
32#define CSB_WAIT_MAX (5000) /* ms */
33
34struct nx842_workmem {
35 /* Below fields must be properly aligned */
36 struct coprocessor_request_block crb; /* CRB_ALIGN align */
37 struct data_descriptor_entry ddl_in[DDL_LEN_MAX]; /* DDE_ALIGN align */
38 struct data_descriptor_entry ddl_out[DDL_LEN_MAX]; /* DDE_ALIGN align */
39 /* Above fields must be properly aligned */
40
41 ktime_t start;
42
43 char padding[WORKMEM_ALIGN]; /* unused, to allow alignment */
44} __packed __aligned(WORKMEM_ALIGN);
45
46struct nx842_coproc {
47 unsigned int chip_id;
48 unsigned int ct;
49 unsigned int ci;
50 struct list_head list;
51};
52
53/* no cpu hotplug on powernv, so this list never changes after init */
54static LIST_HEAD(nx842_coprocs);
55static unsigned int nx842_ct;
56
57/**
58 * setup_indirect_dde - Setup an indirect DDE
59 *
60 * The DDE is setup with the the DDE count, byte count, and address of
61 * first direct DDE in the list.
62 */
63static void setup_indirect_dde(struct data_descriptor_entry *dde,
64 struct data_descriptor_entry *ddl,
65 unsigned int dde_count, unsigned int byte_count)
66{
67 dde->flags = 0;
68 dde->count = dde_count;
69 dde->index = 0;
70 dde->length = cpu_to_be32(byte_count);
71 dde->address = cpu_to_be64(nx842_get_pa(ddl));
72}
73
74/**
75 * setup_direct_dde - Setup single DDE from buffer
76 *
77 * The DDE is setup with the buffer and length. The buffer must be properly
78 * aligned. The used length is returned.
79 * Returns:
80 * N Successfully set up DDE with N bytes
81 */
82static unsigned int setup_direct_dde(struct data_descriptor_entry *dde,
83 unsigned long pa, unsigned int len)
84{
85 unsigned int l = min_t(unsigned int, len, LEN_ON_PAGE(pa));
86
87 dde->flags = 0;
88 dde->count = 0;
89 dde->index = 0;
90 dde->length = cpu_to_be32(l);
91 dde->address = cpu_to_be64(pa);
92
93 return l;
94}
95
96/**
97 * setup_ddl - Setup DDL from buffer
98 *
99 * Returns:
100 * 0 Successfully set up DDL
101 */
102static int setup_ddl(struct data_descriptor_entry *dde,
103 struct data_descriptor_entry *ddl,
104 unsigned char *buf, unsigned int len,
105 bool in)
106{
107 unsigned long pa = nx842_get_pa(buf);
108 int i, ret, total_len = len;
109
110 if (!IS_ALIGNED(pa, DDE_BUFFER_ALIGN)) {
111 pr_debug("%s buffer pa 0x%lx not 0x%x-byte aligned\n",
112 in ? "input" : "output", pa, DDE_BUFFER_ALIGN);
113 return -EINVAL;
114 }
115
116 /* only need to check last mult; since buffer must be
117 * DDE_BUFFER_ALIGN aligned, and that is a multiple of
118 * DDE_BUFFER_SIZE_MULT, and pre-last page DDE buffers
119 * are guaranteed a multiple of DDE_BUFFER_SIZE_MULT.
120 */
121 if (len % DDE_BUFFER_LAST_MULT) {
122 pr_debug("%s buffer len 0x%x not a multiple of 0x%x\n",
123 in ? "input" : "output", len, DDE_BUFFER_LAST_MULT);
124 if (in)
125 return -EINVAL;
126 len = round_down(len, DDE_BUFFER_LAST_MULT);
127 }
128
129 /* use a single direct DDE */
130 if (len <= LEN_ON_PAGE(pa)) {
131 ret = setup_direct_dde(dde, pa, len);
132 WARN_ON(ret < len);
133 return 0;
134 }
135
136 /* use the DDL */
137 for (i = 0; i < DDL_LEN_MAX && len > 0; i++) {
138 ret = setup_direct_dde(&ddl[i], pa, len);
139 buf += ret;
140 len -= ret;
141 pa = nx842_get_pa(buf);
142 }
143
144 if (len > 0) {
145 pr_debug("0x%x total %s bytes 0x%x too many for DDL.\n",
146 total_len, in ? "input" : "output", len);
147 if (in)
148 return -EMSGSIZE;
149 total_len -= len;
150 }
151 setup_indirect_dde(dde, ddl, i, total_len);
152
153 return 0;
154}
155
156#define CSB_ERR(csb, msg, ...) \
157 pr_err("ERROR: " msg " : %02x %02x %02x %02x %08x\n", \
158 ##__VA_ARGS__, (csb)->flags, \
159 (csb)->cs, (csb)->cc, (csb)->ce, \
160 be32_to_cpu((csb)->count))
161
162#define CSB_ERR_ADDR(csb, msg, ...) \
163 CSB_ERR(csb, msg " at %lx", ##__VA_ARGS__, \
164 (unsigned long)be64_to_cpu((csb)->address))
165
166/**
167 * wait_for_csb
168 */
169static int wait_for_csb(struct nx842_workmem *wmem,
170 struct coprocessor_status_block *csb)
171{
172 ktime_t start = wmem->start, now = ktime_get();
173 ktime_t timeout = ktime_add_ms(start, CSB_WAIT_MAX);
174
175 while (!(ACCESS_ONCE(csb->flags) & CSB_V)) {
176 cpu_relax();
177 now = ktime_get();
178 if (ktime_after(now, timeout))
179 break;
180 }
181
182 /* hw has updated csb and output buffer */
183 barrier();
184
185 /* check CSB flags */
186 if (!(csb->flags & CSB_V)) {
187 CSB_ERR(csb, "CSB still not valid after %ld us, giving up",
188 (long)ktime_us_delta(now, start));
189 return -ETIMEDOUT;
190 }
191 if (csb->flags & CSB_F) {
192 CSB_ERR(csb, "Invalid CSB format");
193 return -EPROTO;
194 }
195 if (csb->flags & CSB_CH) {
196 CSB_ERR(csb, "Invalid CSB chaining state");
197 return -EPROTO;
198 }
199
200 /* verify CSB completion sequence is 0 */
201 if (csb->cs) {
202 CSB_ERR(csb, "Invalid CSB completion sequence");
203 return -EPROTO;
204 }
205
206 /* check CSB Completion Code */
207 switch (csb->cc) {
208 /* no error */
209 case CSB_CC_SUCCESS:
210 break;
211 case CSB_CC_TPBC_GT_SPBC:
212 /* not an error, but the compressed data is
213 * larger than the uncompressed data :(
214 */
215 break;
216
217 /* input data errors */
218 case CSB_CC_OPERAND_OVERLAP:
219 /* input and output buffers overlap */
220 CSB_ERR(csb, "Operand Overlap error");
221 return -EINVAL;
222 case CSB_CC_INVALID_OPERAND:
223 CSB_ERR(csb, "Invalid operand");
224 return -EINVAL;
225 case CSB_CC_NOSPC:
226 /* output buffer too small */
227 return -ENOSPC;
228 case CSB_CC_ABORT:
229 CSB_ERR(csb, "Function aborted");
230 return -EINTR;
231 case CSB_CC_CRC_MISMATCH:
232 CSB_ERR(csb, "CRC mismatch");
233 return -EINVAL;
234 case CSB_CC_TEMPL_INVALID:
235 CSB_ERR(csb, "Compressed data template invalid");
236 return -EINVAL;
237 case CSB_CC_TEMPL_OVERFLOW:
238 CSB_ERR(csb, "Compressed data template shows data past end");
239 return -EINVAL;
240
241 /* these should not happen */
242 case CSB_CC_INVALID_ALIGN:
243 /* setup_ddl should have detected this */
244 CSB_ERR_ADDR(csb, "Invalid alignment");
245 return -EINVAL;
246 case CSB_CC_DATA_LENGTH:
247 /* setup_ddl should have detected this */
248 CSB_ERR(csb, "Invalid data length");
249 return -EINVAL;
250 case CSB_CC_WR_TRANSLATION:
251 case CSB_CC_TRANSLATION:
252 case CSB_CC_TRANSLATION_DUP1:
253 case CSB_CC_TRANSLATION_DUP2:
254 case CSB_CC_TRANSLATION_DUP3:
255 case CSB_CC_TRANSLATION_DUP4:
256 case CSB_CC_TRANSLATION_DUP5:
257 case CSB_CC_TRANSLATION_DUP6:
258 /* should not happen, we use physical addrs */
259 CSB_ERR_ADDR(csb, "Translation error");
260 return -EPROTO;
261 case CSB_CC_WR_PROTECTION:
262 case CSB_CC_PROTECTION:
263 case CSB_CC_PROTECTION_DUP1:
264 case CSB_CC_PROTECTION_DUP2:
265 case CSB_CC_PROTECTION_DUP3:
266 case CSB_CC_PROTECTION_DUP4:
267 case CSB_CC_PROTECTION_DUP5:
268 case CSB_CC_PROTECTION_DUP6:
269 /* should not happen, we use physical addrs */
270 CSB_ERR_ADDR(csb, "Protection error");
271 return -EPROTO;
272 case CSB_CC_PRIVILEGE:
273 /* shouldn't happen, we're in HYP mode */
274 CSB_ERR(csb, "Insufficient Privilege error");
275 return -EPROTO;
276 case CSB_CC_EXCESSIVE_DDE:
277 /* shouldn't happen, setup_ddl doesn't use many dde's */
278 CSB_ERR(csb, "Too many DDEs in DDL");
279 return -EINVAL;
280 case CSB_CC_TRANSPORT:
281 /* shouldn't happen, we setup CRB correctly */
282 CSB_ERR(csb, "Invalid CRB");
283 return -EINVAL;
284 case CSB_CC_SEGMENTED_DDL:
285 /* shouldn't happen, setup_ddl creates DDL right */
286 CSB_ERR(csb, "Segmented DDL error");
287 return -EINVAL;
288 case CSB_CC_DDE_OVERFLOW:
289 /* shouldn't happen, setup_ddl creates DDL right */
290 CSB_ERR(csb, "DDE overflow error");
291 return -EINVAL;
292 case CSB_CC_SESSION:
293 /* should not happen with ICSWX */
294 CSB_ERR(csb, "Session violation error");
295 return -EPROTO;
296 case CSB_CC_CHAIN:
297 /* should not happen, we don't use chained CRBs */
298 CSB_ERR(csb, "Chained CRB error");
299 return -EPROTO;
300 case CSB_CC_SEQUENCE:
301 /* should not happen, we don't use chained CRBs */
302 CSB_ERR(csb, "CRB seqeunce number error");
303 return -EPROTO;
304 case CSB_CC_UNKNOWN_CODE:
305 CSB_ERR(csb, "Unknown subfunction code");
306 return -EPROTO;
307
308 /* hardware errors */
309 case CSB_CC_RD_EXTERNAL:
310 case CSB_CC_RD_EXTERNAL_DUP1:
311 case CSB_CC_RD_EXTERNAL_DUP2:
312 case CSB_CC_RD_EXTERNAL_DUP3:
313 CSB_ERR_ADDR(csb, "Read error outside coprocessor");
314 return -EPROTO;
315 case CSB_CC_WR_EXTERNAL:
316 CSB_ERR_ADDR(csb, "Write error outside coprocessor");
317 return -EPROTO;
318 case CSB_CC_INTERNAL:
319 CSB_ERR(csb, "Internal error in coprocessor");
320 return -EPROTO;
321 case CSB_CC_PROVISION:
322 CSB_ERR(csb, "Storage provision error");
323 return -EPROTO;
324 case CSB_CC_HW:
325 CSB_ERR(csb, "Correctable hardware error");
326 return -EPROTO;
327
328 default:
329 CSB_ERR(csb, "Invalid CC %d", csb->cc);
330 return -EPROTO;
331 }
332
333 /* check Completion Extension state */
334 if (csb->ce & CSB_CE_TERMINATION) {
335 CSB_ERR(csb, "CSB request was terminated");
336 return -EPROTO;
337 }
338 if (csb->ce & CSB_CE_INCOMPLETE) {
339 CSB_ERR(csb, "CSB request not complete");
340 return -EPROTO;
341 }
342 if (!(csb->ce & CSB_CE_TPBC)) {
343 CSB_ERR(csb, "TPBC not provided, unknown target length");
344 return -EPROTO;
345 }
346
347 /* successful completion */
348 pr_debug_ratelimited("Processed %u bytes in %lu us\n", csb->count,
349 (unsigned long)ktime_us_delta(now, start));
350
351 return 0;
352}
353
354/**
355 * nx842_powernv_function - compress/decompress data using the 842 algorithm
356 *
357 * (De)compression provided by the NX842 coprocessor on IBM PowerNV systems.
358 * This compresses or decompresses the provided input buffer into the provided
359 * output buffer.
360 *
361 * Upon return from this function @outlen contains the length of the
362 * output data. If there is an error then @outlen will be 0 and an
363 * error will be specified by the return code from this function.
364 *
365 * The @workmem buffer should only be used by one function call at a time.
366 *
367 * @in: input buffer pointer
368 * @inlen: input buffer size
369 * @out: output buffer pointer
370 * @outlenp: output buffer size pointer
371 * @workmem: working memory buffer pointer, must be at least NX842_MEM_COMPRESS
372 * @fc: function code, see CCW Function Codes in nx-842.h
373 *
374 * Returns:
375 * 0 Success, output of length @outlenp stored in the buffer at @out
376 * -ENODEV Hardware unavailable
377 * -ENOSPC Output buffer is to small
378 * -EMSGSIZE Input buffer too large
379 * -EINVAL buffer constraints do not fix nx842_constraints
380 * -EPROTO hardware error during operation
381 * -ETIMEDOUT hardware did not complete operation in reasonable time
382 * -EINTR operation was aborted
383 */
384static int nx842_powernv_function(const unsigned char *in, unsigned int inlen,
385 unsigned char *out, unsigned int *outlenp,
386 void *workmem, int fc)
387{
388 struct coprocessor_request_block *crb;
389 struct coprocessor_status_block *csb;
390 struct nx842_workmem *wmem;
391 int ret;
392 u64 csb_addr;
393 u32 ccw;
394 unsigned int outlen = *outlenp;
395
396 wmem = PTR_ALIGN(workmem, WORKMEM_ALIGN);
397
398 *outlenp = 0;
399
400 /* shoudn't happen, we don't load without a coproc */
401 if (!nx842_ct) {
402 pr_err_ratelimited("coprocessor CT is 0");
403 return -ENODEV;
404 }
405
406 crb = &wmem->crb;
407 csb = &crb->csb;
408
409 /* Clear any previous values */
410 memset(crb, 0, sizeof(*crb));
411
412 /* set up DDLs */
413 ret = setup_ddl(&crb->source, wmem->ddl_in,
414 (unsigned char *)in, inlen, true);
415 if (ret)
416 return ret;
417 ret = setup_ddl(&crb->target, wmem->ddl_out,
418 out, outlen, false);
419 if (ret)
420 return ret;
421
422 /* set up CCW */
423 ccw = 0;
424 ccw = SET_FIELD(ccw, CCW_CT, nx842_ct);
425 ccw = SET_FIELD(ccw, CCW_CI_842, 0); /* use 0 for hw auto-selection */
426 ccw = SET_FIELD(ccw, CCW_FC_842, fc);
427
428 /* set up CRB's CSB addr */
429 csb_addr = nx842_get_pa(csb) & CRB_CSB_ADDRESS;
430 csb_addr |= CRB_CSB_AT; /* Addrs are phys */
431 crb->csb_addr = cpu_to_be64(csb_addr);
432
433 wmem->start = ktime_get();
434
435 /* do ICSWX */
436 ret = icswx(cpu_to_be32(ccw), crb);
437
438 pr_debug_ratelimited("icswx CR %x ccw %x crb->ccw %x\n", ret,
439 (unsigned int)ccw,
440 (unsigned int)be32_to_cpu(crb->ccw));
441
442 switch (ret) {
443 case ICSWX_INITIATED:
444 ret = wait_for_csb(wmem, csb);
445 break;
446 case ICSWX_BUSY:
447 pr_debug_ratelimited("842 Coprocessor busy\n");
448 ret = -EBUSY;
449 break;
450 case ICSWX_REJECTED:
451 pr_err_ratelimited("ICSWX rejected\n");
452 ret = -EPROTO;
453 break;
454 default:
455 pr_err_ratelimited("Invalid ICSWX return code %x\n", ret);
456 ret = -EPROTO;
457 break;
458 }
459
460 if (!ret)
461 *outlenp = be32_to_cpu(csb->count);
462
463 return ret;
464}
465
466/**
467 * nx842_powernv_compress - Compress data using the 842 algorithm
468 *
469 * Compression provided by the NX842 coprocessor on IBM PowerNV systems.
470 * The input buffer is compressed and the result is stored in the
471 * provided output buffer.
472 *
473 * Upon return from this function @outlen contains the length of the
474 * compressed data. If there is an error then @outlen will be 0 and an
475 * error will be specified by the return code from this function.
476 *
477 * @in: input buffer pointer
478 * @inlen: input buffer size
479 * @out: output buffer pointer
480 * @outlenp: output buffer size pointer
481 * @workmem: working memory buffer pointer, must be at least NX842_MEM_COMPRESS
482 *
483 * Returns: see @nx842_powernv_function()
484 */
485static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen,
486 unsigned char *out, unsigned int *outlenp,
487 void *wmem)
488{
489 return nx842_powernv_function(in, inlen, out, outlenp,
490 wmem, CCW_FC_842_COMP_NOCRC);
491}
492
493/**
494 * nx842_powernv_decompress - Decompress data using the 842 algorithm
495 *
496 * Decompression provided by the NX842 coprocessor on IBM PowerNV systems.
497 * The input buffer is decompressed and the result is stored in the
498 * provided output buffer.
499 *
500 * Upon return from this function @outlen contains the length of the
501 * decompressed data. If there is an error then @outlen will be 0 and an
502 * error will be specified by the return code from this function.
503 *
504 * @in: input buffer pointer
505 * @inlen: input buffer size
506 * @out: output buffer pointer
507 * @outlenp: output buffer size pointer
508 * @workmem: working memory buffer pointer, must be at least NX842_MEM_COMPRESS
509 *
510 * Returns: see @nx842_powernv_function()
511 */
512static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen,
513 unsigned char *out, unsigned int *outlenp,
514 void *wmem)
515{
516 return nx842_powernv_function(in, inlen, out, outlenp,
517 wmem, CCW_FC_842_DECOMP_NOCRC);
518}
519
520static int __init nx842_powernv_probe(struct device_node *dn)
521{
522 struct nx842_coproc *coproc;
523 struct property *ct_prop, *ci_prop;
524 unsigned int ct, ci;
525 int chip_id;
526
527 chip_id = of_get_ibm_chip_id(dn);
528 if (chip_id < 0) {
529 pr_err("ibm,chip-id missing\n");
530 return -EINVAL;
531 }
532 ct_prop = of_find_property(dn, "ibm,842-coprocessor-type", NULL);
533 if (!ct_prop) {
534 pr_err("ibm,842-coprocessor-type missing\n");
535 return -EINVAL;
536 }
537 ct = be32_to_cpu(*(unsigned int *)ct_prop->value);
538 ci_prop = of_find_property(dn, "ibm,842-coprocessor-instance", NULL);
539 if (!ci_prop) {
540 pr_err("ibm,842-coprocessor-instance missing\n");
541 return -EINVAL;
542 }
543 ci = be32_to_cpu(*(unsigned int *)ci_prop->value);
544
545 coproc = kmalloc(sizeof(*coproc), GFP_KERNEL);
546 if (!coproc)
547 return -ENOMEM;
548
549 coproc->chip_id = chip_id;
550 coproc->ct = ct;
551 coproc->ci = ci;
552 INIT_LIST_HEAD(&coproc->list);
553 list_add(&coproc->list, &nx842_coprocs);
554
555 pr_info("coprocessor found on chip %d, CT %d CI %d\n", chip_id, ct, ci);
556
557 if (!nx842_ct)
558 nx842_ct = ct;
559 else if (nx842_ct != ct)
560 pr_err("NX842 chip %d, CT %d != first found CT %d\n",
561 chip_id, ct, nx842_ct);
562
563 return 0;
564}
565
566static struct nx842_constraints nx842_powernv_constraints = {
567 .alignment = DDE_BUFFER_ALIGN,
568 .multiple = DDE_BUFFER_LAST_MULT,
569 .minimum = DDE_BUFFER_LAST_MULT,
570 .maximum = (DDL_LEN_MAX - 1) * PAGE_SIZE,
571};
572
573static struct nx842_driver nx842_powernv_driver = {
574 .owner = THIS_MODULE,
575 .constraints = &nx842_powernv_constraints,
576 .compress = nx842_powernv_compress,
577 .decompress = nx842_powernv_decompress,
578};
579
580static __init int nx842_powernv_init(void)
581{
582 struct device_node *dn;
583
584 /* verify workmem size/align restrictions */
585 BUILD_BUG_ON(sizeof(struct nx842_workmem) > NX842_MEM_COMPRESS);
586 BUILD_BUG_ON(WORKMEM_ALIGN % CRB_ALIGN);
587 BUILD_BUG_ON(CRB_ALIGN % DDE_ALIGN);
588 BUILD_BUG_ON(CRB_SIZE % DDE_ALIGN);
589 /* verify buffer size/align restrictions */
590 BUILD_BUG_ON(PAGE_SIZE % DDE_BUFFER_ALIGN);
591 BUILD_BUG_ON(DDE_BUFFER_ALIGN % DDE_BUFFER_SIZE_MULT);
592 BUILD_BUG_ON(DDE_BUFFER_SIZE_MULT % DDE_BUFFER_LAST_MULT);
593
594 pr_info("loading\n");
595
596 for_each_compatible_node(dn, NULL, NX842_POWERNV_COMPAT_NAME)
597 nx842_powernv_probe(dn);
598
599 if (!nx842_ct) {
600 pr_err("no coprocessors found\n");
601 return -ENODEV;
602 }
603
604 nx842_register_driver(&nx842_powernv_driver);
605
606 pr_info("loaded\n");
607
608 return 0;
609}
610module_init(nx842_powernv_init);
611
612static void __exit nx842_powernv_exit(void)
613{
614 struct nx842_coproc *coproc, *n;
615
616 nx842_unregister_driver(&nx842_powernv_driver);
617
618 list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) {
619 list_del(&coproc->list);
620 kfree(coproc);
621 }
622
623 pr_info("unloaded\n");
624}
625module_exit(nx842_powernv_exit);
diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c
index cb481d81df06..6db99924652c 100644
--- a/drivers/crypto/nx/nx-842-pseries.c
+++ b/drivers/crypto/nx/nx-842-pseries.c
@@ -160,15 +160,6 @@ static inline unsigned long nx842_get_scatterlist_size(
160 return sl->entry_nr * sizeof(struct nx842_slentry); 160 return sl->entry_nr * sizeof(struct nx842_slentry);
161} 161}
162 162
163static inline unsigned long nx842_get_pa(void *addr)
164{
165 if (is_vmalloc_addr(addr))
166 return page_to_phys(vmalloc_to_page(addr))
167 + offset_in_page(addr);
168 else
169 return __pa(addr);
170}
171
172static int nx842_build_scatterlist(unsigned long buf, int len, 163static int nx842_build_scatterlist(unsigned long buf, int len,
173 struct nx842_scatterlist *sl) 164 struct nx842_scatterlist *sl)
174{ 165{
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c
index 160fe2d97336..bf2823ceaf4e 100644
--- a/drivers/crypto/nx/nx-842.c
+++ b/drivers/crypto/nx/nx-842.c
@@ -164,7 +164,9 @@ static __init int nx842_init(void)
164{ 164{
165 pr_info("loading\n"); 165 pr_info("loading\n");
166 166
167 if (of_find_compatible_node(NULL, NULL, NX842_PSERIES_COMPAT_NAME)) 167 if (of_find_compatible_node(NULL, NULL, NX842_POWERNV_COMPAT_NAME))
168 request_module_nowait(NX842_POWERNV_MODULE_NAME);
169 else if (of_find_compatible_node(NULL, NULL, NX842_PSERIES_COMPAT_NAME))
168 request_module_nowait(NX842_PSERIES_MODULE_NAME); 170 request_module_nowait(NX842_PSERIES_MODULE_NAME);
169 else 171 else
170 pr_err("no nx842 driver found.\n"); 172 pr_err("no nx842 driver found.\n");
diff --git a/drivers/crypto/nx/nx-842.h b/drivers/crypto/nx/nx-842.h
index c6ceb0f1d04c..84b15b7448bb 100644
--- a/drivers/crypto/nx/nx-842.h
+++ b/drivers/crypto/nx/nx-842.h
@@ -5,9 +5,104 @@
5#include <linux/kernel.h> 5#include <linux/kernel.h>
6#include <linux/module.h> 6#include <linux/module.h>
7#include <linux/nx842.h> 7#include <linux/nx842.h>
8#include <linux/sw842.h>
8#include <linux/of.h> 9#include <linux/of.h>
9#include <linux/slab.h> 10#include <linux/slab.h>
10#include <linux/io.h> 11#include <linux/io.h>
12#include <linux/mm.h>
13#include <linux/ratelimit.h>
14
15/* Restrictions on Data Descriptor List (DDL) and Entry (DDE) buffers
16 *
17 * From NX P8 workbook, sec 4.9.1 "842 details"
18 * Each DDE buffer is 128 byte aligned
19 * Each DDE buffer size is a multiple of 32 bytes (except the last)
20 * The last DDE buffer size is a multiple of 8 bytes
21 */
22#define DDE_BUFFER_ALIGN (128)
23#define DDE_BUFFER_SIZE_MULT (32)
24#define DDE_BUFFER_LAST_MULT (8)
25
26/* Arbitrary DDL length limit
27 * Allows max buffer size of MAX-1 to MAX pages
28 * (depending on alignment)
29 */
30#define DDL_LEN_MAX (17)
31
32/* CCW 842 CI/FC masks
33 * NX P8 workbook, section 4.3.1, figure 4-6
34 * "CI/FC Boundary by NX CT type"
35 */
36#define CCW_CI_842 (0x00003ff8)
37#define CCW_FC_842 (0x00000007)
38
39/* CCW Function Codes (FC) for 842
40 * NX P8 workbook, section 4.9, table 4-28
41 * "Function Code Definitions for 842 Memory Compression"
42 */
43#define CCW_FC_842_COMP_NOCRC (0)
44#define CCW_FC_842_COMP_CRC (1)
45#define CCW_FC_842_DECOMP_NOCRC (2)
46#define CCW_FC_842_DECOMP_CRC (3)
47#define CCW_FC_842_MOVE (4)
48
49/* CSB CC Error Types for 842
50 * NX P8 workbook, section 4.10.3, table 4-30
51 * "Reported Error Types Summary Table"
52 */
53/* These are all duplicates of existing codes defined in icswx.h. */
54#define CSB_CC_TRANSLATION_DUP1 (80)
55#define CSB_CC_TRANSLATION_DUP2 (82)
56#define CSB_CC_TRANSLATION_DUP3 (84)
57#define CSB_CC_TRANSLATION_DUP4 (86)
58#define CSB_CC_TRANSLATION_DUP5 (92)
59#define CSB_CC_TRANSLATION_DUP6 (94)
60#define CSB_CC_PROTECTION_DUP1 (81)
61#define CSB_CC_PROTECTION_DUP2 (83)
62#define CSB_CC_PROTECTION_DUP3 (85)
63#define CSB_CC_PROTECTION_DUP4 (87)
64#define CSB_CC_PROTECTION_DUP5 (93)
65#define CSB_CC_PROTECTION_DUP6 (95)
66#define CSB_CC_RD_EXTERNAL_DUP1 (89)
67#define CSB_CC_RD_EXTERNAL_DUP2 (90)
68#define CSB_CC_RD_EXTERNAL_DUP3 (91)
69/* These are specific to NX */
70/* 842 codes */
71#define CSB_CC_TPBC_GT_SPBC (64) /* no error, but >1 comp ratio */
72#define CSB_CC_CRC_MISMATCH (65) /* decomp crc mismatch */
73#define CSB_CC_TEMPL_INVALID (66) /* decomp invalid template value */
74#define CSB_CC_TEMPL_OVERFLOW (67) /* decomp template shows data after end */
75/* sym crypt codes */
76#define CSB_CC_DECRYPT_OVERFLOW (64)
77/* asym crypt codes */
78#define CSB_CC_MINV_OVERFLOW (128)
79/* These are reserved for hypervisor use */
80#define CSB_CC_HYP_RESERVE_START (240)
81#define CSB_CC_HYP_RESERVE_END (253)
82#define CSB_CC_HYP_NO_HW (254)
83#define CSB_CC_HYP_HANG_ABORTED (255)
84
85/* CCB Completion Modes (CM) for 842
86 * NX P8 workbook, section 4.3, figure 4-5
87 * "CRB Details - Normal Cop_Req (CL=00, C=1)"
88 */
89#define CCB_CM_EXTRA_WRITE (CCB_CM0_ALL_COMPLETIONS & CCB_CM12_STORE)
90#define CCB_CM_INTERRUPT (CCB_CM0_ALL_COMPLETIONS & CCB_CM12_INTERRUPT)
91
92#define LEN_ON_PAGE(pa) (PAGE_SIZE - ((pa) & ~PAGE_MASK))
93
94static inline unsigned long nx842_get_pa(void *addr)
95{
96 if (!is_vmalloc_addr(addr))
97 return __pa(addr);
98
99 return page_to_phys(vmalloc_to_page(addr)) + offset_in_page(addr);
100}
101
102/* Get/Set bit fields */
103#define MASK_LSH(m) (__builtin_ffsl(m) - 1)
104#define GET_FIELD(v, m) (((v) & (m)) >> MASK_LSH(m))
105#define SET_FIELD(v, m, val) (((v) & ~(m)) | (((val) << MASK_LSH(m)) & (m)))
11 106
12struct nx842_driver { 107struct nx842_driver {
13 struct module *owner; 108 struct module *owner;
@@ -27,6 +122,8 @@ void nx842_unregister_driver(struct nx842_driver *driver);
27 122
28 123
29/* To allow the main nx-compress module to load platform module */ 124/* To allow the main nx-compress module to load platform module */
125#define NX842_POWERNV_MODULE_NAME "nx-compress-powernv"
126#define NX842_POWERNV_COMPAT_NAME "ibm,power-nx"
30#define NX842_PSERIES_MODULE_NAME "nx-compress-pseries" 127#define NX842_PSERIES_MODULE_NAME "nx-compress-pseries"
31#define NX842_PSERIES_COMPAT_NAME "ibm,compression" 128#define NX842_PSERIES_COMPAT_NAME "ibm,compression"
32 129
diff --git a/include/linux/nx842.h b/include/linux/nx842.h
index aa1a97e90dea..4ddf68d9c0d4 100644
--- a/include/linux/nx842.h
+++ b/include/linux/nx842.h
@@ -1,9 +1,11 @@
1#ifndef __NX842_H__ 1#ifndef __NX842_H__
2#define __NX842_H__ 2#define __NX842_H__
3 3
4#define __NX842_PSERIES_MEM_COMPRESS ((PAGE_SIZE * 2) + 10240) 4#define __NX842_PSERIES_MEM_COMPRESS (10240)
5#define __NX842_POWERNV_MEM_COMPRESS (1024)
5 6
6#define NX842_MEM_COMPRESS __NX842_PSERIES_MEM_COMPRESS 7#define NX842_MEM_COMPRESS (max_t(unsigned int, \
8 __NX842_PSERIES_MEM_COMPRESS, __NX842_POWERNV_MEM_COMPRESS))
7 9
8struct nx842_constraints { 10struct nx842_constraints {
9 int alignment; 11 int alignment;