1
2
3
4
5
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
21MODULE_LICENSE("GPL");
22MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");
23MODULE_DESCRIPTION("H/W Compression driver for IBM PowerNV processors");
24MODULE_ALIAS_CRYPTO("842");
25MODULE_ALIAS_CRYPTO("842-nx");
26
27#define WORKMEM_ALIGN (CRB_ALIGN)
28#define CSB_WAIT_MAX (5000)
29#define VAS_RETRIES (10)
30
31struct nx842_workmem {
32
33 struct coprocessor_request_block crb;
34 struct data_descriptor_entry ddl_in[DDL_LEN_MAX];
35 struct data_descriptor_entry ddl_out[DDL_LEN_MAX];
36
37
38 ktime_t start;
39
40 char padding[WORKMEM_ALIGN];
41} __packed __aligned(WORKMEM_ALIGN);
42
43struct nx_coproc {
44 unsigned int chip_id;
45 unsigned int ct;
46 unsigned int ci;
47 struct {
48 struct vas_window *rxwin;
49 int id;
50 } vas;
51 struct list_head list;
52};
53
54
55
56
57
58static DEFINE_PER_CPU(struct vas_window *, cpu_txwin);
59
60
61static LIST_HEAD(nx_coprocs);
62static unsigned int nx842_ct;
63
64
65
66
67
68#define NX_CT_GZIP (2)
69#define NX_CT_842 (3)
70
71static 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
77
78
79
80
81static 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
94
95
96
97
98
99
100static 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
116
117
118
119
120static 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
135
136
137
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
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
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
185
186
187static int wait_for_csb(struct nx842_workmem *wmem,
188 struct coprocessor_status_block *csb)
189{
190 ktime_t start = wmem->start, now = ktime_get();
191 ktime_t timeout = ktime_add_ms(start, CSB_WAIT_MAX);
192
193 while (!(READ_ONCE(csb->flags) & CSB_V)) {
194 cpu_relax();
195 now = ktime_get();
196 if (ktime_after(now, timeout))
197 break;
198 }
199
200
201 barrier();
202
203
204 if (!(csb->flags & CSB_V)) {
205 CSB_ERR(csb, "CSB still not valid after %ld us, giving up",
206 (long)ktime_us_delta(now, start));
207 return -ETIMEDOUT;
208 }
209 if (csb->flags & CSB_F) {
210 CSB_ERR(csb, "Invalid CSB format");
211 return -EPROTO;
212 }
213 if (csb->flags & CSB_CH) {
214 CSB_ERR(csb, "Invalid CSB chaining state");
215 return -EPROTO;
216 }
217
218
219 if (csb->cs) {
220 CSB_ERR(csb, "Invalid CSB completion sequence");
221 return -EPROTO;
222 }
223
224
225 switch (csb->cc) {
226
227 case CSB_CC_SUCCESS:
228 break;
229 case CSB_CC_TPBC_GT_SPBC:
230
231
232
233 break;
234
235
236 case CSB_CC_OPERAND_OVERLAP:
237
238 CSB_ERR(csb, "Operand Overlap error");
239 return -EINVAL;
240 case CSB_CC_INVALID_OPERAND:
241 CSB_ERR(csb, "Invalid operand");
242 return -EINVAL;
243 case CSB_CC_NOSPC:
244
245 return -ENOSPC;
246 case CSB_CC_ABORT:
247 CSB_ERR(csb, "Function aborted");
248 return -EINTR;
249 case CSB_CC_CRC_MISMATCH:
250 CSB_ERR(csb, "CRC mismatch");
251 return -EINVAL;
252 case CSB_CC_TEMPL_INVALID:
253 CSB_ERR(csb, "Compressed data template invalid");
254 return -EINVAL;
255 case CSB_CC_TEMPL_OVERFLOW:
256 CSB_ERR(csb, "Compressed data template shows data past end");
257 return -EINVAL;
258 case CSB_CC_EXCEED_BYTE_COUNT:
259
260
261
262
263 CSB_ERR(csb, "DDE byte count exceeds the limit");
264 return -EINVAL;
265
266
267 case CSB_CC_INVALID_ALIGN:
268
269 CSB_ERR_ADDR(csb, "Invalid alignment");
270 return -EINVAL;
271 case CSB_CC_DATA_LENGTH:
272
273 CSB_ERR(csb, "Invalid data length");
274 return -EINVAL;
275 case CSB_CC_WR_TRANSLATION:
276 case CSB_CC_TRANSLATION:
277 case CSB_CC_TRANSLATION_DUP1:
278 case CSB_CC_TRANSLATION_DUP2:
279 case CSB_CC_TRANSLATION_DUP3:
280 case CSB_CC_TRANSLATION_DUP4:
281 case CSB_CC_TRANSLATION_DUP5:
282 case CSB_CC_TRANSLATION_DUP6:
283
284 CSB_ERR_ADDR(csb, "Translation error");
285 return -EPROTO;
286 case CSB_CC_WR_PROTECTION:
287 case CSB_CC_PROTECTION:
288 case CSB_CC_PROTECTION_DUP1:
289 case CSB_CC_PROTECTION_DUP2:
290 case CSB_CC_PROTECTION_DUP3:
291 case CSB_CC_PROTECTION_DUP4:
292 case CSB_CC_PROTECTION_DUP5:
293 case CSB_CC_PROTECTION_DUP6:
294
295 CSB_ERR_ADDR(csb, "Protection error");
296 return -EPROTO;
297 case CSB_CC_PRIVILEGE:
298
299 CSB_ERR(csb, "Insufficient Privilege error");
300 return -EPROTO;
301 case CSB_CC_EXCESSIVE_DDE:
302
303 CSB_ERR(csb, "Too many DDEs in DDL");
304 return -EINVAL;
305 case CSB_CC_TRANSPORT:
306 case CSB_CC_INVALID_CRB:
307
308 CSB_ERR(csb, "Invalid CRB");
309 return -EINVAL;
310 case CSB_CC_INVALID_DDE:
311
312
313
314
315 CSB_ERR(csb, "Invalid DDE");
316 return -EINVAL;
317 case CSB_CC_SEGMENTED_DDL:
318
319 CSB_ERR(csb, "Segmented DDL error");
320 return -EINVAL;
321 case CSB_CC_DDE_OVERFLOW:
322
323 CSB_ERR(csb, "DDE overflow error");
324 return -EINVAL;
325 case CSB_CC_SESSION:
326
327 CSB_ERR(csb, "Session violation error");
328 return -EPROTO;
329 case CSB_CC_CHAIN:
330
331 CSB_ERR(csb, "Chained CRB error");
332 return -EPROTO;
333 case CSB_CC_SEQUENCE:
334
335 CSB_ERR(csb, "CRB sequence number error");
336 return -EPROTO;
337 case CSB_CC_UNKNOWN_CODE:
338 CSB_ERR(csb, "Unknown subfunction code");
339 return -EPROTO;
340
341
342 case CSB_CC_RD_EXTERNAL:
343 case CSB_CC_RD_EXTERNAL_DUP1:
344 case CSB_CC_RD_EXTERNAL_DUP2:
345 case CSB_CC_RD_EXTERNAL_DUP3:
346 CSB_ERR_ADDR(csb, "Read error outside coprocessor");
347 return -EPROTO;
348 case CSB_CC_WR_EXTERNAL:
349 CSB_ERR_ADDR(csb, "Write error outside coprocessor");
350 return -EPROTO;
351 case CSB_CC_INTERNAL:
352 CSB_ERR(csb, "Internal error in coprocessor");
353 return -EPROTO;
354 case CSB_CC_PROVISION:
355 CSB_ERR(csb, "Storage provision error");
356 return -EPROTO;
357 case CSB_CC_HW:
358 CSB_ERR(csb, "Correctable hardware error");
359 return -EPROTO;
360 case CSB_CC_HW_EXPIRED_TIMER:
361 CSB_ERR(csb, "Job did not finish within allowed time");
362 return -EPROTO;
363
364 default:
365 CSB_ERR(csb, "Invalid CC %d", csb->cc);
366 return -EPROTO;
367 }
368
369
370 if (csb->ce & CSB_CE_TERMINATION) {
371 CSB_ERR(csb, "CSB request was terminated");
372 return -EPROTO;
373 }
374 if (csb->ce & CSB_CE_INCOMPLETE) {
375 CSB_ERR(csb, "CSB request not complete");
376 return -EPROTO;
377 }
378 if (!(csb->ce & CSB_CE_TPBC)) {
379 CSB_ERR(csb, "TPBC not provided, unknown target length");
380 return -EPROTO;
381 }
382
383
384 pr_debug_ratelimited("Processed %u bytes in %lu us\n",
385 be32_to_cpu(csb->count),
386 (unsigned long)ktime_us_delta(now, start));
387
388 return 0;
389}
390
391static int nx842_config_crb(const unsigned char *in, unsigned int inlen,
392 unsigned char *out, unsigned int outlen,
393 struct nx842_workmem *wmem)
394{
395 struct coprocessor_request_block *crb;
396 struct coprocessor_status_block *csb;
397 u64 csb_addr;
398 int ret;
399
400 crb = &wmem->crb;
401 csb = &crb->csb;
402
403
404 memset(crb, 0, sizeof(*crb));
405
406
407 ret = setup_ddl(&crb->source, wmem->ddl_in,
408 (unsigned char *)in, inlen, true);
409 if (ret)
410 return ret;
411
412 ret = setup_ddl(&crb->target, wmem->ddl_out,
413 out, outlen, false);
414 if (ret)
415 return ret;
416
417
418 csb_addr = nx842_get_pa(csb) & CRB_CSB_ADDRESS;
419 csb_addr |= CRB_CSB_AT;
420 crb->csb_addr = cpu_to_be64(csb_addr);
421
422 return 0;
423}
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456static int nx842_exec_icswx(const unsigned char *in, unsigned int inlen,
457 unsigned char *out, unsigned int *outlenp,
458 void *workmem, int fc)
459{
460 struct coprocessor_request_block *crb;
461 struct coprocessor_status_block *csb;
462 struct nx842_workmem *wmem;
463 int ret;
464 u32 ccw;
465 unsigned int outlen = *outlenp;
466
467 wmem = PTR_ALIGN(workmem, WORKMEM_ALIGN);
468
469 *outlenp = 0;
470
471
472 if (!nx842_ct) {
473 pr_err_ratelimited("coprocessor CT is 0");
474 return -ENODEV;
475 }
476
477 ret = nx842_config_crb(in, inlen, out, outlen, wmem);
478 if (ret)
479 return ret;
480
481 crb = &wmem->crb;
482 csb = &crb->csb;
483
484
485 ccw = 0;
486 ccw = SET_FIELD(CCW_CT, ccw, nx842_ct);
487 ccw = SET_FIELD(CCW_CI_842, ccw, 0);
488 ccw = SET_FIELD(CCW_FC_842, ccw, fc);
489
490 wmem->start = ktime_get();
491
492
493 ret = icswx(cpu_to_be32(ccw), crb);
494
495 pr_debug_ratelimited("icswx CR %x ccw %x crb->ccw %x\n", ret,
496 (unsigned int)ccw,
497 (unsigned int)be32_to_cpu(crb->ccw));
498
499
500
501
502
503
504
505 ret &= ~ICSWX_XERS0;
506
507 switch (ret) {
508 case ICSWX_INITIATED:
509 ret = wait_for_csb(wmem, csb);
510 break;
511 case ICSWX_BUSY:
512 pr_debug_ratelimited("842 Coprocessor busy\n");
513 ret = -EBUSY;
514 break;
515 case ICSWX_REJECTED:
516 pr_err_ratelimited("ICSWX rejected\n");
517 ret = -EPROTO;
518 break;
519 }
520
521 if (!ret)
522 *outlenp = be32_to_cpu(csb->count);
523
524 return ret;
525}
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559static int nx842_exec_vas(const unsigned char *in, unsigned int inlen,
560 unsigned char *out, unsigned int *outlenp,
561 void *workmem, int fc)
562{
563 struct coprocessor_request_block *crb;
564 struct coprocessor_status_block *csb;
565 struct nx842_workmem *wmem;
566 struct vas_window *txwin;
567 int ret, i = 0;
568 u32 ccw;
569 unsigned int outlen = *outlenp;
570
571 wmem = PTR_ALIGN(workmem, WORKMEM_ALIGN);
572
573 *outlenp = 0;
574
575 crb = &wmem->crb;
576 csb = &crb->csb;
577
578 ret = nx842_config_crb(in, inlen, out, outlen, wmem);
579 if (ret)
580 return ret;
581
582 ccw = 0;
583 ccw = SET_FIELD(CCW_FC_842, ccw, fc);
584 crb->ccw = cpu_to_be32(ccw);
585
586 do {
587 wmem->start = ktime_get();
588 preempt_disable();
589 txwin = this_cpu_read(cpu_txwin);
590
591
592
593
594
595 vas_copy_crb(crb, 0);
596
597
598
599
600
601 ret = vas_paste_crb(txwin, 0, 1);
602 preempt_enable();
603
604
605
606 } while (ret && (i++ < VAS_RETRIES));
607
608 if (ret) {
609 pr_err_ratelimited("VAS copy/paste failed\n");
610 return ret;
611 }
612
613 ret = wait_for_csb(wmem, csb);
614 if (!ret)
615 *outlenp = be32_to_cpu(csb->count);
616
617 return ret;
618}
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640static int nx842_powernv_compress(const unsigned char *in, unsigned int inlen,
641 unsigned char *out, unsigned int *outlenp,
642 void *wmem)
643{
644 return nx842_powernv_exec(in, inlen, out, outlenp,
645 wmem, CCW_FC_842_COMP_CRC);
646}
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668static int nx842_powernv_decompress(const unsigned char *in, unsigned int inlen,
669 unsigned char *out, unsigned int *outlenp,
670 void *wmem)
671{
672 return nx842_powernv_exec(in, inlen, out, outlenp,
673 wmem, CCW_FC_842_DECOMP_CRC);
674}
675
676static inline void nx_add_coprocs_list(struct nx_coproc *coproc,
677 int chipid)
678{
679 coproc->chip_id = chipid;
680 INIT_LIST_HEAD(&coproc->list);
681 list_add(&coproc->list, &nx_coprocs);
682}
683
684static struct vas_window *nx_alloc_txwin(struct nx_coproc *coproc)
685{
686 struct vas_window *txwin = NULL;
687 struct vas_tx_win_attr txattr;
688
689
690
691
692
693 vas_init_tx_win_attr(&txattr, coproc->ct);
694 txattr.lpid = 0;
695
696
697
698
699 txwin = vas_tx_win_open(coproc->vas.id, coproc->ct, &txattr);
700 if (IS_ERR(txwin))
701 pr_err("ibm,nx-842: Can not open TX window: %ld\n",
702 PTR_ERR(txwin));
703
704 return txwin;
705}
706
707
708
709
710
711
712
713static int nx_open_percpu_txwins(void)
714{
715 struct nx_coproc *coproc, *n;
716 unsigned int i, chip_id;
717
718 for_each_possible_cpu(i) {
719 struct vas_window *txwin = NULL;
720
721 chip_id = cpu_to_chip_id(i);
722
723 list_for_each_entry_safe(coproc, n, &nx_coprocs, list) {
724
725
726
727
728
729
730 if (coproc->ct != VAS_COP_TYPE_842_HIPRI)
731 continue;
732
733 if (coproc->chip_id == chip_id) {
734 txwin = nx_alloc_txwin(coproc);
735 if (IS_ERR(txwin))
736 return PTR_ERR(txwin);
737
738 per_cpu(cpu_txwin, i) = txwin;
739 break;
740 }
741 }
742
743 if (!per_cpu(cpu_txwin, i)) {
744
745 pr_err("NX engine is not available for CPU %d\n", i);
746 return -EINVAL;
747 }
748 }
749
750 return 0;
751}
752
753static int __init nx_set_ct(struct nx_coproc *coproc, const char *priority,
754 int high, int normal)
755{
756 if (!strcmp(priority, "High"))
757 coproc->ct = high;
758 else if (!strcmp(priority, "Normal"))
759 coproc->ct = normal;
760 else {
761 pr_err("Invalid RxFIFO priority value\n");
762 return -EINVAL;
763 }
764
765 return 0;
766}
767
768static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id,
769 int vasid, int type, int *ct)
770{
771 struct vas_window *rxwin = NULL;
772 struct vas_rx_win_attr rxattr;
773 u32 lpid, pid, tid, fifo_size;
774 struct nx_coproc *coproc;
775 u64 rx_fifo;
776 const char *priority;
777 int ret;
778
779 ret = of_property_read_u64(dn, "rx-fifo-address", &rx_fifo);
780 if (ret) {
781 pr_err("Missing rx-fifo-address property\n");
782 return ret;
783 }
784
785 ret = of_property_read_u32(dn, "rx-fifo-size", &fifo_size);
786 if (ret) {
787 pr_err("Missing rx-fifo-size property\n");
788 return ret;
789 }
790
791 ret = of_property_read_u32(dn, "lpid", &lpid);
792 if (ret) {
793 pr_err("Missing lpid property\n");
794 return ret;
795 }
796
797 ret = of_property_read_u32(dn, "pid", &pid);
798 if (ret) {
799 pr_err("Missing pid property\n");
800 return ret;
801 }
802
803 ret = of_property_read_u32(dn, "tid", &tid);
804 if (ret) {
805 pr_err("Missing tid property\n");
806 return ret;
807 }
808
809 ret = of_property_read_string(dn, "priority", &priority);
810 if (ret) {
811 pr_err("Missing priority property\n");
812 return ret;
813 }
814
815 coproc = kzalloc(sizeof(*coproc), GFP_KERNEL);
816 if (!coproc)
817 return -ENOMEM;
818
819 if (type == NX_CT_842)
820 ret = nx_set_ct(coproc, priority, VAS_COP_TYPE_842_HIPRI,
821 VAS_COP_TYPE_842);
822 else if (type == NX_CT_GZIP)
823 ret = nx_set_ct(coproc, priority, VAS_COP_TYPE_GZIP_HIPRI,
824 VAS_COP_TYPE_GZIP);
825
826 if (ret)
827 goto err_out;
828
829 vas_init_rx_win_attr(&rxattr, coproc->ct);
830 rxattr.rx_fifo = (void *)rx_fifo;
831 rxattr.rx_fifo_size = fifo_size;
832 rxattr.lnotify_lpid = lpid;
833 rxattr.lnotify_pid = pid;
834 rxattr.lnotify_tid = tid;
835
836
837
838
839 rxattr.wcreds_max = fifo_size / CRB_SIZE;
840
841
842
843
844
845 rxwin = vas_rx_win_open(vasid, coproc->ct, &rxattr);
846 if (IS_ERR(rxwin)) {
847 ret = PTR_ERR(rxwin);
848 pr_err("setting RxFIFO with VAS failed: %d\n",
849 ret);
850 goto err_out;
851 }
852
853 coproc->vas.rxwin = rxwin;
854 coproc->vas.id = vasid;
855 nx_add_coprocs_list(coproc, chip_id);
856
857
858
859
860
861
862
863
864 *ct = pid;
865
866 return 0;
867
868err_out:
869 kfree(coproc);
870 return ret;
871}
872
873static int __init nx_coproc_init(int chip_id, int ct_842, int ct_gzip)
874{
875 int ret = 0;
876
877 if (opal_check_token(OPAL_NX_COPROC_INIT)) {
878 ret = opal_nx_coproc_init(chip_id, ct_842);
879
880 if (!ret)
881 ret = opal_nx_coproc_init(chip_id, ct_gzip);
882
883 if (ret) {
884 ret = opal_error_code(ret);
885 pr_err("Failed to initialize NX for chip(%d): %d\n",
886 chip_id, ret);
887 }
888 } else
889 pr_warn("Firmware doesn't support NX initialization\n");
890
891 return ret;
892}
893
894static int __init find_nx_device_tree(struct device_node *dn, int chip_id,
895 int vasid, int type, char *devname,
896 int *ct)
897{
898 int ret = 0;
899
900 if (of_device_is_compatible(dn, devname)) {
901 ret = vas_cfg_coproc_info(dn, chip_id, vasid, type, ct);
902 if (ret)
903 of_node_put(dn);
904 }
905
906 return ret;
907}
908
909static int __init nx_powernv_probe_vas(struct device_node *pn)
910{
911 int chip_id, vasid, ret = 0;
912 int ct_842 = 0, ct_gzip = 0;
913 struct device_node *dn;
914
915 chip_id = of_get_ibm_chip_id(pn);
916 if (chip_id < 0) {
917 pr_err("ibm,chip-id missing\n");
918 return -EINVAL;
919 }
920
921 vasid = chip_to_vas_id(chip_id);
922 if (vasid < 0) {
923 pr_err("Unable to map chip_id %d to vasid\n", chip_id);
924 return -EINVAL;
925 }
926
927 for_each_child_of_node(pn, dn) {
928 ret = find_nx_device_tree(dn, chip_id, vasid, NX_CT_842,
929 "ibm,p9-nx-842", &ct_842);
930
931 if (!ret)
932 ret = find_nx_device_tree(dn, chip_id, vasid,
933 NX_CT_GZIP, "ibm,p9-nx-gzip", &ct_gzip);
934
935 if (ret)
936 return ret;
937 }
938
939 if (!ct_842 || !ct_gzip) {
940 pr_err("NX FIFO nodes are missing\n");
941 return -EINVAL;
942 }
943
944
945
946
947 ret = nx_coproc_init(chip_id, ct_842, ct_gzip);
948
949 return ret;
950}
951
952static int __init nx842_powernv_probe(struct device_node *dn)
953{
954 struct nx_coproc *coproc;
955 unsigned int ct, ci;
956 int chip_id;
957
958 chip_id = of_get_ibm_chip_id(dn);
959 if (chip_id < 0) {
960 pr_err("ibm,chip-id missing\n");
961 return -EINVAL;
962 }
963
964 if (of_property_read_u32(dn, "ibm,842-coprocessor-type", &ct)) {
965 pr_err("ibm,842-coprocessor-type missing\n");
966 return -EINVAL;
967 }
968
969 if (of_property_read_u32(dn, "ibm,842-coprocessor-instance", &ci)) {
970 pr_err("ibm,842-coprocessor-instance missing\n");
971 return -EINVAL;
972 }
973
974 coproc = kzalloc(sizeof(*coproc), GFP_KERNEL);
975 if (!coproc)
976 return -ENOMEM;
977
978 coproc->ct = ct;
979 coproc->ci = ci;
980 nx_add_coprocs_list(coproc, chip_id);
981
982 pr_info("coprocessor found on chip %d, CT %d CI %d\n", chip_id, ct, ci);
983
984 if (!nx842_ct)
985 nx842_ct = ct;
986 else if (nx842_ct != ct)
987 pr_err("NX842 chip %d, CT %d != first found CT %d\n",
988 chip_id, ct, nx842_ct);
989
990 return 0;
991}
992
993static void nx_delete_coprocs(void)
994{
995 struct nx_coproc *coproc, *n;
996 struct vas_window *txwin;
997 int i;
998
999
1000
1001
1002 for_each_possible_cpu(i) {
1003 txwin = per_cpu(cpu_txwin, i);
1004 if (txwin)
1005 vas_win_close(txwin);
1006
1007 per_cpu(cpu_txwin, i) = NULL;
1008 }
1009
1010 list_for_each_entry_safe(coproc, n, &nx_coprocs, list) {
1011 if (coproc->vas.rxwin)
1012 vas_win_close(coproc->vas.rxwin);
1013
1014 list_del(&coproc->list);
1015 kfree(coproc);
1016 }
1017}
1018
1019static struct nx842_constraints nx842_powernv_constraints = {
1020 .alignment = DDE_BUFFER_ALIGN,
1021 .multiple = DDE_BUFFER_LAST_MULT,
1022 .minimum = DDE_BUFFER_LAST_MULT,
1023 .maximum = (DDL_LEN_MAX - 1) * PAGE_SIZE,
1024};
1025
1026static struct nx842_driver nx842_powernv_driver = {
1027 .name = KBUILD_MODNAME,
1028 .owner = THIS_MODULE,
1029 .workmem_size = sizeof(struct nx842_workmem),
1030 .constraints = &nx842_powernv_constraints,
1031 .compress = nx842_powernv_compress,
1032 .decompress = nx842_powernv_decompress,
1033};
1034
1035static int nx842_powernv_crypto_init(struct crypto_tfm *tfm)
1036{
1037 return nx842_crypto_init(tfm, &nx842_powernv_driver);
1038}
1039
1040static struct crypto_alg nx842_powernv_alg = {
1041 .cra_name = "842",
1042 .cra_driver_name = "842-nx",
1043 .cra_priority = 300,
1044 .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
1045 .cra_ctxsize = sizeof(struct nx842_crypto_ctx),
1046 .cra_module = THIS_MODULE,
1047 .cra_init = nx842_powernv_crypto_init,
1048 .cra_exit = nx842_crypto_exit,
1049 .cra_u = { .compress = {
1050 .coa_compress = nx842_crypto_compress,
1051 .coa_decompress = nx842_crypto_decompress } }
1052};
1053
1054static __init int nx_compress_powernv_init(void)
1055{
1056 struct device_node *dn;
1057 int ret;
1058
1059
1060 BUILD_BUG_ON(WORKMEM_ALIGN % CRB_ALIGN);
1061 BUILD_BUG_ON(CRB_ALIGN % DDE_ALIGN);
1062 BUILD_BUG_ON(CRB_SIZE % DDE_ALIGN);
1063
1064 BUILD_BUG_ON(PAGE_SIZE % DDE_BUFFER_ALIGN);
1065 BUILD_BUG_ON(DDE_BUFFER_ALIGN % DDE_BUFFER_SIZE_MULT);
1066 BUILD_BUG_ON(DDE_BUFFER_SIZE_MULT % DDE_BUFFER_LAST_MULT);
1067
1068 for_each_compatible_node(dn, NULL, "ibm,power9-nx") {
1069 ret = nx_powernv_probe_vas(dn);
1070 if (ret) {
1071 nx_delete_coprocs();
1072 of_node_put(dn);
1073 return ret;
1074 }
1075 }
1076
1077 if (list_empty(&nx_coprocs)) {
1078 for_each_compatible_node(dn, NULL, "ibm,power-nx")
1079 nx842_powernv_probe(dn);
1080
1081 if (!nx842_ct)
1082 return -ENODEV;
1083
1084 nx842_powernv_exec = nx842_exec_icswx;
1085 } else {
1086
1087
1088
1089
1090
1091
1092
1093 ret = vas_register_coproc_api(THIS_MODULE, VAS_COP_TYPE_GZIP,
1094 "nx-gzip");
1095
1096
1097
1098
1099
1100 if (!ret)
1101 ret = nx_open_percpu_txwins();
1102
1103 if (ret) {
1104 nx_delete_coprocs();
1105 return ret;
1106 }
1107
1108 nx842_powernv_exec = nx842_exec_vas;
1109 }
1110
1111 ret = crypto_register_alg(&nx842_powernv_alg);
1112 if (ret) {
1113 nx_delete_coprocs();
1114 return ret;
1115 }
1116
1117 return 0;
1118}
1119module_init(nx_compress_powernv_init);
1120
1121static void __exit nx_compress_powernv_exit(void)
1122{
1123
1124
1125
1126
1127
1128
1129 if (!nx842_ct)
1130 vas_unregister_coproc_api();
1131
1132 crypto_unregister_alg(&nx842_powernv_alg);
1133
1134 nx_delete_coprocs();
1135}
1136module_exit(nx_compress_powernv_exit);
1137