]> Git Repo - linux.git/blob - drivers/crypto/nx/nx-common-powernv.c
drm/tests: Remove slow tests
[linux.git] / drivers / crypto / nx / nx-common-powernv.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Driver for IBM PowerNV compression accelerator
4  *
5  * Copyright (C) 2015 Dan Streetman, IBM Corp
6  */
7
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9
10 #include "nx-842.h"
11
12 #include <linux/timer.h>
13
14 #include <asm/prom.h>
15 #include <asm/icswx.h>
16 #include <asm/vas.h>
17 #include <asm/reg.h>
18 #include <asm/opal-api.h>
19 #include <asm/opal.h>
20
21 MODULE_LICENSE("GPL");
22 MODULE_AUTHOR("Dan Streetman <[email protected]>");
23 MODULE_DESCRIPTION("H/W Compression driver for IBM PowerNV processors");
24 MODULE_ALIAS_CRYPTO("842");
25 MODULE_ALIAS_CRYPTO("842-nx");
26
27 #define WORKMEM_ALIGN   (CRB_ALIGN)
28 #define CSB_WAIT_MAX    (5000) /* ms */
29 #define VAS_RETRIES     (10)
30
31 struct nx842_workmem {
32         /* Below fields must be properly aligned */
33         struct coprocessor_request_block crb; /* CRB_ALIGN align */
34         struct data_descriptor_entry ddl_in[DDL_LEN_MAX]; /* DDE_ALIGN align */
35         struct data_descriptor_entry ddl_out[DDL_LEN_MAX]; /* DDE_ALIGN align */
36         /* Above fields must be properly aligned */
37
38         ktime_t start;
39
40         char padding[WORKMEM_ALIGN]; /* unused, to allow alignment */
41 } __packed __aligned(WORKMEM_ALIGN);
42
43 struct nx_coproc {
44         unsigned int chip_id;
45         unsigned int ct;        /* Can be 842 or GZIP high/normal*/
46         unsigned int ci;        /* Coprocessor instance, used with icswx */
47         struct {
48                 struct vas_window *rxwin;
49                 int id;
50         } vas;
51         struct list_head list;
52 };
53
54 /*
55  * Send the request to NX engine on the chip for the corresponding CPU
56  * where the process is executing. Use with VAS function.
57  */
58 static DEFINE_PER_CPU(struct vas_window *, cpu_txwin);
59
60 /* no cpu hotplug on powernv, so this list never changes after init */
61 static LIST_HEAD(nx_coprocs);
62 static unsigned int nx842_ct;   /* used in icswx function */
63
64 /*
65  * Using same values as in skiboot or coprocessor type representing
66  * in NX workbook.
67  */
68 #define NX_CT_GZIP      (2)     /* on P9 and later */
69 #define NX_CT_842       (3)
70
71 static int (*nx842_powernv_exec)(const unsigned char *in,
72                                 unsigned int inlen, unsigned char *out,
73                                 unsigned int *outlenp, void *workmem, int fc);
74
75 /*
76  * setup_indirect_dde - Setup an indirect DDE
77  *
78  * The DDE is setup with the DDE count, byte count, and address of
79  * first direct DDE in the list.
80  */
81 static void setup_indirect_dde(struct data_descriptor_entry *dde,
82                                struct data_descriptor_entry *ddl,
83                                unsigned int dde_count, unsigned int byte_count)
84 {
85         dde->flags = 0;
86         dde->count = dde_count;
87         dde->index = 0;
88         dde->length = cpu_to_be32(byte_count);
89         dde->address = cpu_to_be64(nx842_get_pa(ddl));
90 }
91
92 /*
93  * setup_direct_dde - Setup single DDE from buffer
94  *
95  * The DDE is setup with the buffer and length.  The buffer must be properly
96  * aligned.  The used length is returned.
97  * Returns:
98  *   N    Successfully set up DDE with N bytes
99  */
100 static unsigned int setup_direct_dde(struct data_descriptor_entry *dde,
101                                      unsigned long pa, unsigned int len)
102 {
103         unsigned int l = min_t(unsigned int, len, LEN_ON_PAGE(pa));
104
105         dde->flags = 0;
106         dde->count = 0;
107         dde->index = 0;
108         dde->length = cpu_to_be32(l);
109         dde->address = cpu_to_be64(pa);
110
111         return l;
112 }
113
114 /*
115  * setup_ddl - Setup DDL from buffer
116  *
117  * Returns:
118  *   0          Successfully set up DDL
119  */
120 static int setup_ddl(struct data_descriptor_entry *dde,
121                      struct data_descriptor_entry *ddl,
122                      unsigned char *buf, unsigned int len,
123                      bool in)
124 {
125         unsigned long pa = nx842_get_pa(buf);
126         int i, ret, total_len = len;
127
128         if (!IS_ALIGNED(pa, DDE_BUFFER_ALIGN)) {
129                 pr_debug("%s buffer pa 0x%lx not 0x%x-byte aligned\n",
130                          in ? "input" : "output", pa, DDE_BUFFER_ALIGN);
131                 return -EINVAL;
132         }
133
134         /* only need to check last mult; since buffer must be
135          * DDE_BUFFER_ALIGN aligned, and that is a multiple of
136          * DDE_BUFFER_SIZE_MULT, and pre-last page DDE buffers
137          * are guaranteed a multiple of DDE_BUFFER_SIZE_MULT.
138          */
139         if (len % DDE_BUFFER_LAST_MULT) {
140                 pr_debug("%s buffer len 0x%x not a multiple of 0x%x\n",
141                          in ? "input" : "output", len, DDE_BUFFER_LAST_MULT);
142                 if (in)
143                         return -EINVAL;
144                 len = round_down(len, DDE_BUFFER_LAST_MULT);
145         }
146
147         /* use a single direct DDE */
148         if (len <= LEN_ON_PAGE(pa)) {
149                 ret = setup_direct_dde(dde, pa, len);
150                 WARN_ON(ret < len);
151                 return 0;
152         }
153
154         /* use the DDL */
155         for (i = 0; i < DDL_LEN_MAX && len > 0; i++) {
156                 ret = setup_direct_dde(&ddl[i], pa, len);
157                 buf += ret;
158                 len -= ret;
159                 pa = nx842_get_pa(buf);
160         }
161
162         if (len > 0) {
163                 pr_debug("0x%x total %s bytes 0x%x too many for DDL.\n",
164                          total_len, in ? "input" : "output", len);
165                 if (in)
166                         return -EMSGSIZE;
167                 total_len -= len;
168         }
169         setup_indirect_dde(dde, ddl, i, total_len);
170
171         return 0;
172 }
173
174 #define CSB_ERR(csb, msg, ...)                                  \
175         pr_err("ERROR: " msg " : %02x %02x %02x %02x %08x\n",   \
176                ##__VA_ARGS__, (csb)->flags,                     \
177                (csb)->cs, (csb)->cc, (csb)->ce,                 \
178                be32_to_cpu((csb)->count))
179
180 #define CSB_ERR_ADDR(csb, msg, ...)                             \
181         CSB_ERR(csb, msg " at %lx", ##__VA_ARGS__,              \
182                 (unsigned long)be64_to_cpu((csb)->address))
183
184 static int wait_for_csb(struct nx842_workmem *wmem,
185                         struct coprocessor_status_block *csb)
186 {
187         ktime_t start = wmem->start, now = ktime_get();
188         ktime_t timeout = ktime_add_ms(start, CSB_WAIT_MAX);
189
190         while (!(READ_ONCE(csb->flags) & CSB_V)) {
191                 cpu_relax();
192                 now = ktime_get();
193                 if (ktime_after(now, timeout))
194                         break;
195         }
196
197         /* hw has updated csb and output buffer */
198         barrier();
199
200         /* check CSB flags */
201         if (!(csb->flags & CSB_V)) {
202                 CSB_ERR(csb, "CSB still not valid after %ld us, giving up",
203                         (long)ktime_us_delta(now, start));
204                 return -ETIMEDOUT;
205         }
206         if (csb->flags & CSB_F) {
207                 CSB_ERR(csb, "Invalid CSB format");
208                 return -EPROTO;
209         }
210         if (csb->flags & CSB_CH) {
211                 CSB_ERR(csb, "Invalid CSB chaining state");
212                 return -EPROTO;
213         }
214
215         /* verify CSB completion sequence is 0 */
216         if (csb->cs) {
217                 CSB_ERR(csb, "Invalid CSB completion sequence");
218                 return -EPROTO;
219         }
220
221         /* check CSB Completion Code */
222         switch (csb->cc) {
223         /* no error */
224         case CSB_CC_SUCCESS:
225                 break;
226         case CSB_CC_TPBC_GT_SPBC:
227                 /* not an error, but the compressed data is
228                  * larger than the uncompressed data :(
229                  */
230                 break;
231
232         /* input data errors */
233         case CSB_CC_OPERAND_OVERLAP:
234                 /* input and output buffers overlap */
235                 CSB_ERR(csb, "Operand Overlap error");
236                 return -EINVAL;
237         case CSB_CC_INVALID_OPERAND:
238                 CSB_ERR(csb, "Invalid operand");
239                 return -EINVAL;
240         case CSB_CC_NOSPC:
241                 /* output buffer too small */
242                 return -ENOSPC;
243         case CSB_CC_ABORT:
244                 CSB_ERR(csb, "Function aborted");
245                 return -EINTR;
246         case CSB_CC_CRC_MISMATCH:
247                 CSB_ERR(csb, "CRC mismatch");
248                 return -EINVAL;
249         case CSB_CC_TEMPL_INVALID:
250                 CSB_ERR(csb, "Compressed data template invalid");
251                 return -EINVAL;
252         case CSB_CC_TEMPL_OVERFLOW:
253                 CSB_ERR(csb, "Compressed data template shows data past end");
254                 return -EINVAL;
255         case CSB_CC_EXCEED_BYTE_COUNT:  /* P9 or later */
256                 /*
257                  * DDE byte count exceeds the limit specified in Maximum
258                  * byte count register.
259                  */
260                 CSB_ERR(csb, "DDE byte count exceeds the limit");
261                 return -EINVAL;
262
263         /* these should not happen */
264         case CSB_CC_INVALID_ALIGN:
265                 /* setup_ddl should have detected this */
266                 CSB_ERR_ADDR(csb, "Invalid alignment");
267                 return -EINVAL;
268         case CSB_CC_DATA_LENGTH:
269                 /* setup_ddl should have detected this */
270                 CSB_ERR(csb, "Invalid data length");
271                 return -EINVAL;
272         case CSB_CC_WR_TRANSLATION:
273         case CSB_CC_TRANSLATION:
274         case CSB_CC_TRANSLATION_DUP1:
275         case CSB_CC_TRANSLATION_DUP2:
276         case CSB_CC_TRANSLATION_DUP3:
277         case CSB_CC_TRANSLATION_DUP4:
278         case CSB_CC_TRANSLATION_DUP5:
279         case CSB_CC_TRANSLATION_DUP6:
280                 /* should not happen, we use physical addrs */
281                 CSB_ERR_ADDR(csb, "Translation error");
282                 return -EPROTO;
283         case CSB_CC_WR_PROTECTION:
284         case CSB_CC_PROTECTION:
285         case CSB_CC_PROTECTION_DUP1:
286         case CSB_CC_PROTECTION_DUP2:
287         case CSB_CC_PROTECTION_DUP3:
288         case CSB_CC_PROTECTION_DUP4:
289         case CSB_CC_PROTECTION_DUP5:
290         case CSB_CC_PROTECTION_DUP6:
291                 /* should not happen, we use physical addrs */
292                 CSB_ERR_ADDR(csb, "Protection error");
293                 return -EPROTO;
294         case CSB_CC_PRIVILEGE:
295                 /* shouldn't happen, we're in HYP mode */
296                 CSB_ERR(csb, "Insufficient Privilege error");
297                 return -EPROTO;
298         case CSB_CC_EXCESSIVE_DDE:
299                 /* shouldn't happen, setup_ddl doesn't use many dde's */
300                 CSB_ERR(csb, "Too many DDEs in DDL");
301                 return -EINVAL;
302         case CSB_CC_TRANSPORT:
303         case CSB_CC_INVALID_CRB:        /* P9 or later */
304                 /* shouldn't happen, we setup CRB correctly */
305                 CSB_ERR(csb, "Invalid CRB");
306                 return -EINVAL;
307         case CSB_CC_INVALID_DDE:        /* P9 or later */
308                 /*
309                  * shouldn't happen, setup_direct/indirect_dde creates
310                  * DDE right
311                  */
312                 CSB_ERR(csb, "Invalid DDE");
313                 return -EINVAL;
314         case CSB_CC_SEGMENTED_DDL:
315                 /* shouldn't happen, setup_ddl creates DDL right */
316                 CSB_ERR(csb, "Segmented DDL error");
317                 return -EINVAL;
318         case CSB_CC_DDE_OVERFLOW:
319                 /* shouldn't happen, setup_ddl creates DDL right */
320                 CSB_ERR(csb, "DDE overflow error");
321                 return -EINVAL;
322         case CSB_CC_SESSION:
323                 /* should not happen with ICSWX */
324                 CSB_ERR(csb, "Session violation error");
325                 return -EPROTO;
326         case CSB_CC_CHAIN:
327                 /* should not happen, we don't use chained CRBs */
328                 CSB_ERR(csb, "Chained CRB error");
329                 return -EPROTO;
330         case CSB_CC_SEQUENCE:
331                 /* should not happen, we don't use chained CRBs */
332                 CSB_ERR(csb, "CRB sequence number error");
333                 return -EPROTO;
334         case CSB_CC_UNKNOWN_CODE:
335                 CSB_ERR(csb, "Unknown subfunction code");
336                 return -EPROTO;
337
338         /* hardware errors */
339         case CSB_CC_RD_EXTERNAL:
340         case CSB_CC_RD_EXTERNAL_DUP1:
341         case CSB_CC_RD_EXTERNAL_DUP2:
342         case CSB_CC_RD_EXTERNAL_DUP3:
343                 CSB_ERR_ADDR(csb, "Read error outside coprocessor");
344                 return -EPROTO;
345         case CSB_CC_WR_EXTERNAL:
346                 CSB_ERR_ADDR(csb, "Write error outside coprocessor");
347                 return -EPROTO;
348         case CSB_CC_INTERNAL:
349                 CSB_ERR(csb, "Internal error in coprocessor");
350                 return -EPROTO;
351         case CSB_CC_PROVISION:
352                 CSB_ERR(csb, "Storage provision error");
353                 return -EPROTO;
354         case CSB_CC_HW:
355                 CSB_ERR(csb, "Correctable hardware error");
356                 return -EPROTO;
357         case CSB_CC_HW_EXPIRED_TIMER:   /* P9 or later */
358                 CSB_ERR(csb, "Job did not finish within allowed time");
359                 return -EPROTO;
360
361         default:
362                 CSB_ERR(csb, "Invalid CC %d", csb->cc);
363                 return -EPROTO;
364         }
365
366         /* check Completion Extension state */
367         if (csb->ce & CSB_CE_TERMINATION) {
368                 CSB_ERR(csb, "CSB request was terminated");
369                 return -EPROTO;
370         }
371         if (csb->ce & CSB_CE_INCOMPLETE) {
372                 CSB_ERR(csb, "CSB request not complete");
373                 return -EPROTO;
374         }
375         if (!(csb->ce & CSB_CE_TPBC)) {
376                 CSB_ERR(csb, "TPBC not provided, unknown target length");
377                 return -EPROTO;
378         }
379
380         /* successful completion */
381         pr_debug_ratelimited("Processed %u bytes in %lu us\n",
382                              be32_to_cpu(csb->count),
383                              (unsigned long)ktime_us_delta(now, start));
384
385         return 0;
386 }
387
388 static int nx842_config_crb(const unsigned char *in, unsigned int inlen,
389                         unsigned char *out, unsigned int outlen,
390                         struct nx842_workmem *wmem)
391 {
392         struct coprocessor_request_block *crb;
393         struct coprocessor_status_block *csb;
394         u64 csb_addr;
395         int ret;
396
397         crb = &wmem->crb;
398         csb = &crb->csb;
399
400         /* Clear any previous values */
401         memset(crb, 0, sizeof(*crb));
402
403         /* set up DDLs */
404         ret = setup_ddl(&crb->source, wmem->ddl_in,
405                         (unsigned char *)in, inlen, true);
406         if (ret)
407                 return ret;
408
409         ret = setup_ddl(&crb->target, wmem->ddl_out,
410                         out, outlen, false);
411         if (ret)
412                 return ret;
413
414         /* set up CRB's CSB addr */
415         csb_addr = nx842_get_pa(csb) & CRB_CSB_ADDRESS;
416         csb_addr |= CRB_CSB_AT; /* Addrs are phys */
417         crb->csb_addr = cpu_to_be64(csb_addr);
418
419         return 0;
420 }
421
422 /**
423  * nx842_exec_icswx - compress/decompress data using the 842 algorithm
424  *
425  * (De)compression provided by the NX842 coprocessor on IBM PowerNV systems.
426  * This compresses or decompresses the provided input buffer into the provided
427  * output buffer.
428  *
429  * Upon return from this function @outlen contains the length of the
430  * output data.  If there is an error then @outlen will be 0 and an
431  * error will be specified by the return code from this function.
432  *
433  * The @workmem buffer should only be used by one function call at a time.
434  *
435  * @in: input buffer pointer
436  * @inlen: input buffer size
437  * @out: output buffer pointer
438  * @outlenp: output buffer size pointer
439  * @workmem: working memory buffer pointer, size determined by
440  *           nx842_powernv_driver.workmem_size
441  * @fc: function code, see CCW Function Codes in nx-842.h
442  *
443  * Returns:
444  *   0          Success, output of length @outlenp stored in the buffer at @out
445  *   -ENODEV    Hardware unavailable
446  *   -ENOSPC    Output buffer is to small
447  *   -EMSGSIZE  Input buffer too large
448  *   -EINVAL    buffer constraints do not fix nx842_constraints
449  *   -EPROTO    hardware error during operation
450  *   -ETIMEDOUT hardware did not complete operation in reasonable time
451  *   -EINTR     operation was aborted
452  */
453 static int nx842_exec_icswx(const unsigned char *in, unsigned int inlen,
454                                   unsigned char *out, unsigned int *outlenp,
455                                   void *workmem, int fc)
456 {
457         struct coprocessor_request_block *crb;
458         struct coprocessor_status_block *csb;
459         struct nx842_workmem *wmem;
460         int ret;
461         u32 ccw;
462         unsigned int outlen = *outlenp;
463
464         wmem = PTR_ALIGN(workmem, WORKMEM_ALIGN);
465
466         *outlenp = 0;
467
468         /* shoudn't happen, we don't load without a coproc */
469         if (!nx842_ct) {
470                 pr_err_ratelimited("coprocessor CT is 0");
471                 return -ENODEV;
472         }
473
474         ret = nx842_config_crb(in, inlen, out, outlen, wmem);
475         if (ret)
476                 return ret;
477
478         crb = &wmem->crb;
479         csb = &crb->csb;
480
481         /* set up CCW */
482         ccw = 0;
483         ccw = SET_FIELD(CCW_CT, ccw, nx842_ct);
484         ccw = SET_FIELD(CCW_CI_842, ccw, 0); /* use 0 for hw auto-selection */
485         ccw = SET_FIELD(CCW_FC_842, ccw, fc);
486
487         wmem->start = ktime_get();
488
489         /* do ICSWX */
490         ret = icswx(cpu_to_be32(ccw), crb);
491
492         pr_debug_ratelimited("icswx CR %x ccw %x crb->ccw %x\n", ret,
493                              (unsigned int)ccw,
494                              (unsigned int)be32_to_cpu(crb->ccw));
495
496         /*
497          * NX842 coprocessor sets 3rd bit in CR register with XER[S0].
498          * XER[S0] is the integer summary overflow bit which is nothing
499          * to do NX. Since this bit can be set with other return values,
500          * mask this bit.
501          */
502         ret &= ~ICSWX_XERS0;
503
504         switch (ret) {
505         case ICSWX_INITIATED:
506                 ret = wait_for_csb(wmem, csb);
507                 break;
508         case ICSWX_BUSY:
509                 pr_debug_ratelimited("842 Coprocessor busy\n");
510                 ret = -EBUSY;
511                 break;
512         case ICSWX_REJECTED:
513                 pr_err_ratelimited("ICSWX rejected\n");
514                 ret = -EPROTO;
515                 break;
516         }
517
518         if (!ret)
519                 *outlenp = be32_to_cpu(csb->count);
520
521         return ret;
522 }
523
524 /**
525  * nx842_exec_vas - compress/decompress data using the 842 algorithm
526  *
527  * (De)compression provided by the NX842 coprocessor on IBM PowerNV systems.
528  * This compresses or decompresses the provided input buffer into the provided
529  * output buffer.
530  *
531  * Upon return from this function @outlen contains the length of the
532  * output data.  If there is an error then @outlen will be 0 and an
533  * error will be specified by the return code from this function.
534  *
535  * The @workmem buffer should only be used by one function call at a time.
536  *
537  * @in: input buffer pointer
538  * @inlen: input buffer size
539  * @out: output buffer pointer
540  * @outlenp: output buffer size pointer
541  * @workmem: working memory buffer pointer, size determined by
542  *           nx842_powernv_driver.workmem_size
543  * @fc: function code, see CCW Function Codes in nx-842.h
544  *
545  * Returns:
546  *   0          Success, output of length @outlenp stored in the buffer
547  *              at @out
548  *   -ENODEV    Hardware unavailable
549  *   -ENOSPC    Output buffer is to small
550  *   -EMSGSIZE  Input buffer too large
551  *   -EINVAL    buffer constraints do not fix nx842_constraints
552  *   -EPROTO    hardware error during operation
553  *   -ETIMEDOUT hardware did not complete operation in reasonable time
554  *   -EINTR     operation was aborted
555  */
556 static int nx842_exec_vas(const unsigned char *in, unsigned int inlen,
557                                   unsigned char *out, unsigned int *outlenp,
558                                   void *workmem, int fc)
559 {
560         struct coprocessor_request_block *crb;
561         struct coprocessor_status_block *csb;
562         struct nx842_workmem *wmem;
563         struct vas_window *txwin;
564         int ret, i = 0;
565         u32 ccw;
566         unsigned int outlen = *outlenp;
567
568         wmem = PTR_ALIGN(workmem, WORKMEM_ALIGN);
569
570         *outlenp = 0;
571
572         crb = &wmem->crb;
573         csb = &crb->csb;
574
575         ret = nx842_config_crb(in, inlen, out, outlen, wmem);
576         if (ret)
577                 return ret;
578
579         ccw = 0;
580         ccw = SET_FIELD(CCW_FC_842, ccw, fc);
581         crb->ccw = cpu_to_be32(ccw);
582
583         do {
584                 wmem->start = ktime_get();
585                 preempt_disable();
586                 txwin = this_cpu_read(cpu_txwin);
587
588                 /*
589                  * VAS copy CRB into L2 cache. Refer <asm/vas.h>.
590                  * @crb and @offset.
591                  */
592                 vas_copy_crb(crb, 0);
593
594                 /*
595                  * VAS paste previously copied CRB to NX.
596                  * @txwin, @offset and @last (must be true).
597                  */
598                 ret = vas_paste_crb(txwin, 0, 1);
599                 preempt_enable();
600                 /*
601                  * Retry copy/paste function for VAS failures.
602                  */
603         } while (ret && (i++ < VAS_RETRIES));
604
605         if (ret) {
606                 pr_err_ratelimited("VAS copy/paste failed\n");
607                 return ret;
608         }
609
610         ret = wait_for_csb(wmem, csb);
611         if (!ret)
612                 *outlenp = be32_to_cpu(csb->count);
613
614         return ret;
615 }
616
617 /**
618  * nx842_powernv_compress - Compress data using the 842 algorithm
619  *
620  * Compression provided by the NX842 coprocessor on IBM PowerNV systems.
621  * The input buffer is compressed and the result is stored in the
622  * provided output buffer.
623  *
624  * Upon return from this function @outlen contains the length of the
625  * compressed data.  If there is an error then @outlen will be 0 and an
626  * error will be specified by the return code from this function.
627  *
628  * @in: input buffer pointer
629  * @inlen: input buffer size
630  * @out: output buffer pointer
631  * @outlenp: output buffer size pointer
632  * @wmem: working memory buffer pointer, size determined by
633  *        nx842_powernv_driver.workmem_size
634  *
635  * Returns: see @nx842_powernv_exec()
636  */
637 static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen,
638                                   unsigned char *out, unsigned int *outlenp,
639                                   void *wmem)
640 {
641         return nx842_powernv_exec(in, inlen, out, outlenp,
642                                       wmem, CCW_FC_842_COMP_CRC);
643 }
644
645 /**
646  * nx842_powernv_decompress - Decompress data using the 842 algorithm
647  *
648  * Decompression provided by the NX842 coprocessor on IBM PowerNV systems.
649  * The input buffer is decompressed and the result is stored in the
650  * provided output buffer.
651  *
652  * Upon return from this function @outlen contains the length of the
653  * decompressed data.  If there is an error then @outlen will be 0 and an
654  * error will be specified by the return code from this function.
655  *
656  * @in: input buffer pointer
657  * @inlen: input buffer size
658  * @out: output buffer pointer
659  * @outlenp: output buffer size pointer
660  * @wmem: working memory buffer pointer, size determined by
661  *        nx842_powernv_driver.workmem_size
662  *
663  * Returns: see @nx842_powernv_exec()
664  */
665 static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen,
666                                     unsigned char *out, unsigned int *outlenp,
667                                     void *wmem)
668 {
669         return nx842_powernv_exec(in, inlen, out, outlenp,
670                                       wmem, CCW_FC_842_DECOMP_CRC);
671 }
672
673 static inline void nx_add_coprocs_list(struct nx_coproc *coproc,
674                                         int chipid)
675 {
676         coproc->chip_id = chipid;
677         INIT_LIST_HEAD(&coproc->list);
678         list_add(&coproc->list, &nx_coprocs);
679 }
680
681 static struct vas_window *nx_alloc_txwin(struct nx_coproc *coproc)
682 {
683         struct vas_window *txwin = NULL;
684         struct vas_tx_win_attr txattr;
685
686         /*
687          * Kernel requests will be high priority. So open send
688          * windows only for high priority RxFIFO entries.
689          */
690         vas_init_tx_win_attr(&txattr, coproc->ct);
691         txattr.lpid = 0;        /* lpid is 0 for kernel requests */
692
693         /*
694          * Open a VAS send window which is used to send request to NX.
695          */
696         txwin = vas_tx_win_open(coproc->vas.id, coproc->ct, &txattr);
697         if (IS_ERR(txwin))
698                 pr_err("ibm,nx-842: Can not open TX window: %ld\n",
699                                 PTR_ERR(txwin));
700
701         return txwin;
702 }
703
704 /*
705  * Identify chip ID for each CPU, open send wndow for the corresponding NX
706  * engine and save txwin in percpu cpu_txwin.
707  * cpu_txwin is used in copy/paste operation for each compression /
708  * decompression request.
709  */
710 static int nx_open_percpu_txwins(void)
711 {
712         struct nx_coproc *coproc, *n;
713         unsigned int i, chip_id;
714
715         for_each_possible_cpu(i) {
716                 struct vas_window *txwin = NULL;
717
718                 chip_id = cpu_to_chip_id(i);
719
720                 list_for_each_entry_safe(coproc, n, &nx_coprocs, list) {
721                         /*
722                          * Kernel requests use only high priority FIFOs. So
723                          * open send windows for these FIFOs.
724                          * GZIP is not supported in kernel right now.
725                          */
726
727                         if (coproc->ct != VAS_COP_TYPE_842_HIPRI)
728                                 continue;
729
730                         if (coproc->chip_id == chip_id) {
731                                 txwin = nx_alloc_txwin(coproc);
732                                 if (IS_ERR(txwin))
733                                         return PTR_ERR(txwin);
734
735                                 per_cpu(cpu_txwin, i) = txwin;
736                                 break;
737                         }
738                 }
739
740                 if (!per_cpu(cpu_txwin, i)) {
741                         /* shouldn't happen, Each chip will have NX engine */
742                         pr_err("NX engine is not available for CPU %d\n", i);
743                         return -EINVAL;
744                 }
745         }
746
747         return 0;
748 }
749
750 static int __init nx_set_ct(struct nx_coproc *coproc, const char *priority,
751                                 int high, int normal)
752 {
753         if (!strcmp(priority, "High"))
754                 coproc->ct = high;
755         else if (!strcmp(priority, "Normal"))
756                 coproc->ct = normal;
757         else {
758                 pr_err("Invalid RxFIFO priority value\n");
759                 return -EINVAL;
760         }
761
762         return 0;
763 }
764
765 static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id,
766                                         int vasid, int type, int *ct)
767 {
768         struct vas_window *rxwin = NULL;
769         struct vas_rx_win_attr rxattr;
770         u32 lpid, pid, tid, fifo_size;
771         struct nx_coproc *coproc;
772         u64 rx_fifo;
773         const char *priority;
774         int ret;
775
776         ret = of_property_read_u64(dn, "rx-fifo-address", &rx_fifo);
777         if (ret) {
778                 pr_err("Missing rx-fifo-address property\n");
779                 return ret;
780         }
781
782         ret = of_property_read_u32(dn, "rx-fifo-size", &fifo_size);
783         if (ret) {
784                 pr_err("Missing rx-fifo-size property\n");
785                 return ret;
786         }
787
788         ret = of_property_read_u32(dn, "lpid", &lpid);
789         if (ret) {
790                 pr_err("Missing lpid property\n");
791                 return ret;
792         }
793
794         ret = of_property_read_u32(dn, "pid", &pid);
795         if (ret) {
796                 pr_err("Missing pid property\n");
797                 return ret;
798         }
799
800         ret = of_property_read_u32(dn, "tid", &tid);
801         if (ret) {
802                 pr_err("Missing tid property\n");
803                 return ret;
804         }
805
806         ret = of_property_read_string(dn, "priority", &priority);
807         if (ret) {
808                 pr_err("Missing priority property\n");
809                 return ret;
810         }
811
812         coproc = kzalloc(sizeof(*coproc), GFP_KERNEL);
813         if (!coproc)
814                 return -ENOMEM;
815
816         if (type == NX_CT_842)
817                 ret = nx_set_ct(coproc, priority, VAS_COP_TYPE_842_HIPRI,
818                         VAS_COP_TYPE_842);
819         else if (type == NX_CT_GZIP)
820                 ret = nx_set_ct(coproc, priority, VAS_COP_TYPE_GZIP_HIPRI,
821                                 VAS_COP_TYPE_GZIP);
822
823         if (ret)
824                 goto err_out;
825
826         vas_init_rx_win_attr(&rxattr, coproc->ct);
827         rxattr.rx_fifo = rx_fifo;
828         rxattr.rx_fifo_size = fifo_size;
829         rxattr.lnotify_lpid = lpid;
830         rxattr.lnotify_pid = pid;
831         rxattr.lnotify_tid = tid;
832         /*
833          * Maximum RX window credits can not be more than #CRBs in
834          * RxFIFO. Otherwise, can get checkstop if RxFIFO overruns.
835          */
836         rxattr.wcreds_max = fifo_size / CRB_SIZE;
837
838         /*
839          * Open a VAS receice window which is used to configure RxFIFO
840          * for NX.
841          */
842         rxwin = vas_rx_win_open(vasid, coproc->ct, &rxattr);
843         if (IS_ERR(rxwin)) {
844                 ret = PTR_ERR(rxwin);
845                 pr_err("setting RxFIFO with VAS failed: %d\n",
846                         ret);
847                 goto err_out;
848         }
849
850         coproc->vas.rxwin = rxwin;
851         coproc->vas.id = vasid;
852         nx_add_coprocs_list(coproc, chip_id);
853
854         /*
855          * (lpid, pid, tid) combination has to be unique for each
856          * coprocessor instance in the system. So to make it
857          * unique, skiboot uses coprocessor type such as 842 or
858          * GZIP for pid and provides this value to kernel in pid
859          * device-tree property.
860          */
861         *ct = pid;
862
863         return 0;
864
865 err_out:
866         kfree(coproc);
867         return ret;
868 }
869
870 static int __init nx_coproc_init(int chip_id, int ct_842, int ct_gzip)
871 {
872         int ret = 0;
873
874         if (opal_check_token(OPAL_NX_COPROC_INIT)) {
875                 ret = opal_nx_coproc_init(chip_id, ct_842);
876
877                 if (!ret)
878                         ret = opal_nx_coproc_init(chip_id, ct_gzip);
879
880                 if (ret) {
881                         ret = opal_error_code(ret);
882                         pr_err("Failed to initialize NX for chip(%d): %d\n",
883                                 chip_id, ret);
884                 }
885         } else
886                 pr_warn("Firmware doesn't support NX initialization\n");
887
888         return ret;
889 }
890
891 static int __init find_nx_device_tree(struct device_node *dn, int chip_id,
892                                         int vasid, int type, char *devname,
893                                         int *ct)
894 {
895         int ret = 0;
896
897         if (of_device_is_compatible(dn, devname)) {
898                 ret  = vas_cfg_coproc_info(dn, chip_id, vasid, type, ct);
899                 if (ret)
900                         of_node_put(dn);
901         }
902
903         return ret;
904 }
905
906 static int __init nx_powernv_probe_vas(struct device_node *pn)
907 {
908         int chip_id, vasid, ret = 0;
909         int ct_842 = 0, ct_gzip = 0;
910         struct device_node *dn;
911
912         chip_id = of_get_ibm_chip_id(pn);
913         if (chip_id < 0) {
914                 pr_err("ibm,chip-id missing\n");
915                 return -EINVAL;
916         }
917
918         vasid = chip_to_vas_id(chip_id);
919         if (vasid < 0) {
920                 pr_err("Unable to map chip_id %d to vasid\n", chip_id);
921                 return -EINVAL;
922         }
923
924         for_each_child_of_node(pn, dn) {
925                 ret = find_nx_device_tree(dn, chip_id, vasid, NX_CT_842,
926                                         "ibm,p9-nx-842", &ct_842);
927
928                 if (!ret)
929                         ret = find_nx_device_tree(dn, chip_id, vasid,
930                                 NX_CT_GZIP, "ibm,p9-nx-gzip", &ct_gzip);
931
932                 if (ret) {
933                         of_node_put(dn);
934                         return ret;
935                 }
936         }
937
938         if (!ct_842 || !ct_gzip) {
939                 pr_err("NX FIFO nodes are missing\n");
940                 return -EINVAL;
941         }
942
943         /*
944          * Initialize NX instance for both high and normal priority FIFOs.
945          */
946         ret = nx_coproc_init(chip_id, ct_842, ct_gzip);
947
948         return ret;
949 }
950
951 static int __init nx842_powernv_probe(struct device_node *dn)
952 {
953         struct nx_coproc *coproc;
954         unsigned int ct, ci;
955         int chip_id;
956
957         chip_id = of_get_ibm_chip_id(dn);
958         if (chip_id < 0) {
959                 pr_err("ibm,chip-id missing\n");
960                 return -EINVAL;
961         }
962
963         if (of_property_read_u32(dn, "ibm,842-coprocessor-type", &ct)) {
964                 pr_err("ibm,842-coprocessor-type missing\n");
965                 return -EINVAL;
966         }
967
968         if (of_property_read_u32(dn, "ibm,842-coprocessor-instance", &ci)) {
969                 pr_err("ibm,842-coprocessor-instance missing\n");
970                 return -EINVAL;
971         }
972
973         coproc = kzalloc(sizeof(*coproc), GFP_KERNEL);
974         if (!coproc)
975                 return -ENOMEM;
976
977         coproc->ct = ct;
978         coproc->ci = ci;
979         nx_add_coprocs_list(coproc, chip_id);
980
981         pr_info("coprocessor found on chip %d, CT %d CI %d\n", chip_id, ct, ci);
982
983         if (!nx842_ct)
984                 nx842_ct = ct;
985         else if (nx842_ct != ct)
986                 pr_err("NX842 chip %d, CT %d != first found CT %d\n",
987                        chip_id, ct, nx842_ct);
988
989         return 0;
990 }
991
992 static void nx_delete_coprocs(void)
993 {
994         struct nx_coproc *coproc, *n;
995         struct vas_window *txwin;
996         int i;
997
998         /*
999          * close percpu txwins that are opened for the corresponding coproc.
1000          */
1001         for_each_possible_cpu(i) {
1002                 txwin = per_cpu(cpu_txwin, i);
1003                 if (txwin)
1004                         vas_win_close(txwin);
1005
1006                 per_cpu(cpu_txwin, i) = NULL;
1007         }
1008
1009         list_for_each_entry_safe(coproc, n, &nx_coprocs, list) {
1010                 if (coproc->vas.rxwin)
1011                         vas_win_close(coproc->vas.rxwin);
1012
1013                 list_del(&coproc->list);
1014                 kfree(coproc);
1015         }
1016 }
1017
1018 static struct nx842_constraints nx842_powernv_constraints = {
1019         .alignment =    DDE_BUFFER_ALIGN,
1020         .multiple =     DDE_BUFFER_LAST_MULT,
1021         .minimum =      DDE_BUFFER_LAST_MULT,
1022         .maximum =      (DDL_LEN_MAX - 1) * PAGE_SIZE,
1023 };
1024
1025 static struct nx842_driver nx842_powernv_driver = {
1026         .name =         KBUILD_MODNAME,
1027         .owner =        THIS_MODULE,
1028         .workmem_size = sizeof(struct nx842_workmem),
1029         .constraints =  &nx842_powernv_constraints,
1030         .compress =     nx842_powernv_compress,
1031         .decompress =   nx842_powernv_decompress,
1032 };
1033
1034 static int nx842_powernv_crypto_init(struct crypto_tfm *tfm)
1035 {
1036         return nx842_crypto_init(tfm, &nx842_powernv_driver);
1037 }
1038
1039 static struct crypto_alg nx842_powernv_alg = {
1040         .cra_name               = "842",
1041         .cra_driver_name        = "842-nx",
1042         .cra_priority           = 300,
1043         .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
1044         .cra_ctxsize            = sizeof(struct nx842_crypto_ctx),
1045         .cra_module             = THIS_MODULE,
1046         .cra_init               = nx842_powernv_crypto_init,
1047         .cra_exit               = nx842_crypto_exit,
1048         .cra_u                  = { .compress = {
1049         .coa_compress           = nx842_crypto_compress,
1050         .coa_decompress         = nx842_crypto_decompress } }
1051 };
1052
1053 static __init int nx_compress_powernv_init(void)
1054 {
1055         struct device_node *dn;
1056         int ret;
1057
1058         /* verify workmem size/align restrictions */
1059         BUILD_BUG_ON(WORKMEM_ALIGN % CRB_ALIGN);
1060         BUILD_BUG_ON(CRB_ALIGN % DDE_ALIGN);
1061         BUILD_BUG_ON(CRB_SIZE % DDE_ALIGN);
1062         /* verify buffer size/align restrictions */
1063         BUILD_BUG_ON(PAGE_SIZE % DDE_BUFFER_ALIGN);
1064         BUILD_BUG_ON(DDE_BUFFER_ALIGN % DDE_BUFFER_SIZE_MULT);
1065         BUILD_BUG_ON(DDE_BUFFER_SIZE_MULT % DDE_BUFFER_LAST_MULT);
1066
1067         for_each_compatible_node(dn, NULL, "ibm,power9-nx") {
1068                 ret = nx_powernv_probe_vas(dn);
1069                 if (ret) {
1070                         nx_delete_coprocs();
1071                         of_node_put(dn);
1072                         return ret;
1073                 }
1074         }
1075
1076         if (list_empty(&nx_coprocs)) {
1077                 for_each_compatible_node(dn, NULL, "ibm,power-nx")
1078                         nx842_powernv_probe(dn);
1079
1080                 if (!nx842_ct)
1081                         return -ENODEV;
1082
1083                 nx842_powernv_exec = nx842_exec_icswx;
1084         } else {
1085                 /*
1086                  * Register VAS user space API for NX GZIP so
1087                  * that user space can use GZIP engine.
1088                  * Using high FIFO priority for kernel requests and
1089                  * normal FIFO priority is assigned for userspace.
1090                  * 842 compression is supported only in kernel.
1091                  */
1092                 ret = vas_register_api_powernv(THIS_MODULE, VAS_COP_TYPE_GZIP,
1093                                                "nx-gzip");
1094
1095                 /*
1096                  * GZIP is not supported in kernel right now.
1097                  * So open tx windows only for 842.
1098                  */
1099                 if (!ret)
1100                         ret = nx_open_percpu_txwins();
1101
1102                 if (ret) {
1103                         nx_delete_coprocs();
1104                         return ret;
1105                 }
1106
1107                 nx842_powernv_exec = nx842_exec_vas;
1108         }
1109
1110         ret = crypto_register_alg(&nx842_powernv_alg);
1111         if (ret) {
1112                 nx_delete_coprocs();
1113                 return ret;
1114         }
1115
1116         return 0;
1117 }
1118 module_init(nx_compress_powernv_init);
1119
1120 static void __exit nx_compress_powernv_exit(void)
1121 {
1122         /*
1123          * GZIP engine is supported only in power9 or later and nx842_ct
1124          * is used on power8 (icswx).
1125          * VAS API for NX GZIP is registered during init for user space
1126          * use. So delete this API use for GZIP engine.
1127          */
1128         if (!nx842_ct)
1129                 vas_unregister_api_powernv();
1130
1131         crypto_unregister_alg(&nx842_powernv_alg);
1132
1133         nx_delete_coprocs();
1134 }
1135 module_exit(nx_compress_powernv_exit);
This page took 0.098165 seconds and 4 git commands to generate.