1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
34
35#include <linux/slab.h>
36
37#include "fman_keygen.h"
38
39
40#define FMAN_MAX_NUM_OF_HW_PORTS 64
41
42
43#define FM_KG_MAX_NUM_OF_SCHEMES 32
44
45
46#define FM_KG_NUM_OF_GENERIC_REGS 8
47
48
49#define DUMMY_PORT_ID 0
50
51
52#define KG_SCH_DEF_USE_KGSE_DV_0 2
53#define KG_SCH_DEF_USE_KGSE_DV_1 3
54
55
56#define FM_KG_KGAR_NUM_SHIFT 16
57#define KG_SCH_DEF_L4_PORT_SHIFT 8
58#define KG_SCH_DEF_IP_ADDR_SHIFT 18
59#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
60
61
62
63
64#define FM_KG_KGGCR_EN 0x80000000
65
66
67#define FM_KG_KGAR_GO 0x80000000
68#define FM_KG_KGAR_READ 0x40000000
69#define FM_KG_KGAR_WRITE 0x00000000
70#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
71#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000
72
73#define FM_KG_KGAR_ERR 0x20000000
74#define FM_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
75#define FM_KG_KGAR_SEL_PORT_ENTRY 0x02000000
76#define FM_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
77#define FM_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
78
79
80#define FM_EX_KG_DOUBLE_ECC 0x80000000
81#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000
82
83
84#define KG_SCH_MODE_EN 0x80000000
85#define KG_SCH_VSP_NO_KSP_EN 0x80000000
86#define KG_SCH_HASH_CONFIG_SYM 0x40000000
87
88
89#define KG_SCH_KN_PORT_ID 0x80000000
90#define KG_SCH_KN_MACDST 0x40000000
91#define KG_SCH_KN_MACSRC 0x20000000
92#define KG_SCH_KN_TCI1 0x10000000
93#define KG_SCH_KN_TCI2 0x08000000
94#define KG_SCH_KN_ETYPE 0x04000000
95#define KG_SCH_KN_PPPSID 0x02000000
96#define KG_SCH_KN_PPPID 0x01000000
97#define KG_SCH_KN_MPLS1 0x00800000
98#define KG_SCH_KN_MPLS2 0x00400000
99#define KG_SCH_KN_MPLS_LAST 0x00200000
100#define KG_SCH_KN_IPSRC1 0x00100000
101#define KG_SCH_KN_IPDST1 0x00080000
102#define KG_SCH_KN_PTYPE1 0x00040000
103#define KG_SCH_KN_IPTOS_TC1 0x00020000
104#define KG_SCH_KN_IPV6FL1 0x00010000
105#define KG_SCH_KN_IPSRC2 0x00008000
106#define KG_SCH_KN_IPDST2 0x00004000
107#define KG_SCH_KN_PTYPE2 0x00002000
108#define KG_SCH_KN_IPTOS_TC2 0x00001000
109#define KG_SCH_KN_IPV6FL2 0x00000800
110#define KG_SCH_KN_GREPTYPE 0x00000400
111#define KG_SCH_KN_IPSEC_SPI 0x00000200
112#define KG_SCH_KN_IPSEC_NH 0x00000100
113#define KG_SCH_KN_IPPID 0x00000080
114#define KG_SCH_KN_L4PSRC 0x00000004
115#define KG_SCH_KN_L4PDST 0x00000002
116#define KG_SCH_KN_TFLG 0x00000001
117
118
119#define NIA_ENG_BMI 0x00500000
120#define NIA_BMI_AC_ENQ_FRAME 0x00000002
121#define ENQUEUE_KG_DFLT_NIA (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
122
123
124
125
126
127
128
129#define DEFAULT_HASH_DIST_FQID_SHIFT 0
130
131
132#define DEFAULT_HASH_SHIFT 0
133
134
135
136
137
138
139
140
141
142#define DEFAULT_SYMMETRIC_HASH false
143
144
145#define DEFAULT_HASH_KEY_EXTRACT_FIELDS \
146 (KG_SCH_KN_IPSRC1 | KG_SCH_KN_IPDST1 | \
147 KG_SCH_KN_L4PSRC | KG_SCH_KN_L4PDST | \
148 KG_SCH_KN_IPSEC_SPI)
149
150
151
152
153
154#define DEFAULT_HASH_KEY_IPv4_ADDR 0x0A0A0A0A
155
156#define DEFAULT_HASH_KEY_L4_PORT 0x0B0B0B0B
157
158
159
160
161struct fman_kg_scheme_regs {
162 u32 kgse_mode;
163 u32 kgse_ekfc;
164 u32 kgse_ekdv;
165 u32 kgse_bmch;
166 u32 kgse_bmcl;
167 u32 kgse_fqb;
168 u32 kgse_hc;
169 u32 kgse_ppc;
170 u32 kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
171
172 u32 kgse_spc;
173
174 u32 kgse_dv0;
175 u32 kgse_dv1;
176 u32 kgse_ccbs;
177
178 u32 kgse_mv;
179 u32 kgse_om;
180 u32 kgse_vsp;
181
182};
183
184
185struct fman_kg_pe_regs {
186 u32 fmkg_pe_sp;
187 u32 fmkg_pe_cpp;
188
189};
190
191
192
193
194
195struct fman_kg_regs {
196 u32 fmkg_gcr;
197 u32 res004;
198 u32 res008;
199 u32 fmkg_eer;
200 u32 fmkg_eeer;
201 u32 res014;
202 u32 res018;
203 u32 fmkg_seer;
204 u32 fmkg_seeer;
205 u32 fmkg_gsr;
206 u32 fmkg_tpc;
207 u32 fmkg_serc;
208 u32 res030[4];
209 u32 fmkg_fdor;
210 u32 fmkg_gdv0r;
211 u32 fmkg_gdv1r;
212 u32 res04c[6];
213 u32 fmkg_feer;
214 u32 res068[38];
215 union {
216 u32 fmkg_indirect[63];
217 struct fman_kg_scheme_regs fmkg_sch;
218 struct fman_kg_pe_regs fmkg_pe;
219 };
220 u32 fmkg_ar;
221};
222
223
224struct keygen_scheme {
225 bool used;
226 u8 hw_port_id;
227
228
229
230
231
232 u32 base_fqid;
233
234
235
236
237
238
239 u32 hash_fqid_count;
240
241
242
243
244 bool use_hashing;
245 bool symmetric_hash;
246 u8 hashShift;
247
248
249
250
251
252 u32 match_vector;
253};
254
255
256struct fman_keygen {
257 struct keygen_scheme schemes[FM_KG_MAX_NUM_OF_SCHEMES];
258
259 struct fman_kg_regs __iomem *keygen_regs;
260};
261
262
263
264
265
266
267
268
269
270
271
272static int keygen_write_ar_wait(struct fman_kg_regs __iomem *regs, u32 fmkg_ar)
273{
274 iowrite32be(fmkg_ar, ®s->fmkg_ar);
275
276
277 while (fmkg_ar & FM_KG_KGAR_GO)
278 fmkg_ar = ioread32be(®s->fmkg_ar);
279
280 if (fmkg_ar & FM_KG_KGAR_ERR)
281 return -EINVAL;
282
283 return 0;
284}
285
286
287
288
289
290
291
292
293
294
295
296static u32 build_ar_scheme(u8 scheme_id, bool update_counter, bool write)
297{
298 u32 rw = (u32)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
299
300 return (u32)(FM_KG_KGAR_GO |
301 rw |
302 FM_KG_KGAR_SEL_SCHEME_ENTRY |
303 DUMMY_PORT_ID |
304 ((u32)scheme_id << FM_KG_KGAR_NUM_SHIFT) |
305 (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
306}
307
308
309
310
311
312
313
314
315
316
317static u32 build_ar_bind_scheme(u8 hwport_id, bool write)
318{
319 u32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;
320
321 return (u32)(FM_KG_KGAR_GO |
322 rw |
323 FM_KG_KGAR_SEL_PORT_ENTRY |
324 hwport_id |
325 FM_KG_KGAR_SEL_PORT_WSEL_SP);
326}
327
328
329
330
331
332
333
334
335
336
337
338static void keygen_write_sp(struct fman_kg_regs __iomem *regs, u32 sp, bool add)
339{
340 u32 tmp;
341
342 tmp = ioread32be(®s->fmkg_pe.fmkg_pe_sp);
343
344 if (add)
345 tmp |= sp;
346 else
347 tmp &= ~sp;
348
349 iowrite32be(tmp, ®s->fmkg_pe.fmkg_pe_sp);
350}
351
352
353
354
355
356
357
358
359
360
361static u32 build_ar_bind_cls_plan(u8 hwport_id, bool write)
362{
363 u32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;
364
365 return (u32)(FM_KG_KGAR_GO |
366 rw |
367 FM_KG_KGAR_SEL_PORT_ENTRY |
368 hwport_id |
369 FM_KG_KGAR_SEL_PORT_WSEL_CPP);
370}
371
372
373
374
375
376
377
378
379
380
381static void keygen_write_cpp(struct fman_kg_regs __iomem *regs, u32 cpp)
382{
383 iowrite32be(cpp, ®s->fmkg_pe.fmkg_pe_cpp);
384}
385
386
387
388
389
390
391
392
393
394
395
396
397static int keygen_write_scheme(struct fman_kg_regs __iomem *regs, u8 scheme_id,
398 struct fman_kg_scheme_regs *scheme_regs,
399 bool update_counter)
400{
401 u32 ar_reg;
402 int err, i;
403
404
405 iowrite32be(scheme_regs->kgse_mode, ®s->fmkg_sch.kgse_mode);
406 iowrite32be(scheme_regs->kgse_ekfc, ®s->fmkg_sch.kgse_ekfc);
407 iowrite32be(scheme_regs->kgse_ekdv, ®s->fmkg_sch.kgse_ekdv);
408 iowrite32be(scheme_regs->kgse_bmch, ®s->fmkg_sch.kgse_bmch);
409 iowrite32be(scheme_regs->kgse_bmcl, ®s->fmkg_sch.kgse_bmcl);
410 iowrite32be(scheme_regs->kgse_fqb, ®s->fmkg_sch.kgse_fqb);
411 iowrite32be(scheme_regs->kgse_hc, ®s->fmkg_sch.kgse_hc);
412 iowrite32be(scheme_regs->kgse_ppc, ®s->fmkg_sch.kgse_ppc);
413 iowrite32be(scheme_regs->kgse_spc, ®s->fmkg_sch.kgse_spc);
414 iowrite32be(scheme_regs->kgse_dv0, ®s->fmkg_sch.kgse_dv0);
415 iowrite32be(scheme_regs->kgse_dv1, ®s->fmkg_sch.kgse_dv1);
416 iowrite32be(scheme_regs->kgse_ccbs, ®s->fmkg_sch.kgse_ccbs);
417 iowrite32be(scheme_regs->kgse_mv, ®s->fmkg_sch.kgse_mv);
418 iowrite32be(scheme_regs->kgse_om, ®s->fmkg_sch.kgse_om);
419 iowrite32be(scheme_regs->kgse_vsp, ®s->fmkg_sch.kgse_vsp);
420
421 for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
422 iowrite32be(scheme_regs->kgse_gec[i],
423 ®s->fmkg_sch.kgse_gec[i]);
424
425
426 ar_reg = build_ar_scheme(scheme_id, update_counter, true);
427 err = keygen_write_ar_wait(regs, ar_reg);
428 if (err != 0) {
429 pr_err("Writing Action Register failed\n");
430 return err;
431 }
432
433 return err;
434}
435
436
437
438
439
440
441
442
443
444
445static int get_free_scheme_id(struct fman_keygen *keygen, u8 *scheme_id)
446{
447 u8 i;
448
449 for (i = 0; i < FM_KG_MAX_NUM_OF_SCHEMES; i++)
450 if (!keygen->schemes[i].used) {
451 *scheme_id = i;
452 return 0;
453 }
454
455 return -EINVAL;
456}
457
458
459
460
461
462
463
464
465
466
467static struct keygen_scheme *get_scheme(struct fman_keygen *keygen,
468 u8 scheme_id)
469{
470 if (scheme_id >= FM_KG_MAX_NUM_OF_SCHEMES)
471 return NULL;
472 return &keygen->schemes[scheme_id];
473}
474
475
476
477
478
479
480
481
482
483
484
485static int keygen_bind_port_to_schemes(struct fman_keygen *keygen,
486 u8 scheme_id,
487 bool bind)
488{
489 struct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;
490 struct keygen_scheme *scheme;
491 u32 ar_reg;
492 u32 schemes_vector = 0;
493 int err;
494
495 scheme = get_scheme(keygen, scheme_id);
496 if (!scheme) {
497 pr_err("Requested Scheme does not exist\n");
498 return -EINVAL;
499 }
500 if (!scheme->used) {
501 pr_err("Cannot bind port to an invalid scheme\n");
502 return -EINVAL;
503 }
504
505 schemes_vector |= 1 << (31 - scheme_id);
506
507 ar_reg = build_ar_bind_scheme(scheme->hw_port_id, false);
508 err = keygen_write_ar_wait(keygen_regs, ar_reg);
509 if (err != 0) {
510 pr_err("Reading Action Register failed\n");
511 return err;
512 }
513
514 keygen_write_sp(keygen_regs, schemes_vector, bind);
515
516 ar_reg = build_ar_bind_scheme(scheme->hw_port_id, true);
517 err = keygen_write_ar_wait(keygen_regs, ar_reg);
518 if (err != 0) {
519 pr_err("Writing Action Register failed\n");
520 return err;
521 }
522
523 return 0;
524}
525
526
527
528
529
530
531
532
533
534
535
536static int keygen_scheme_setup(struct fman_keygen *keygen, u8 scheme_id,
537 bool enable)
538{
539 struct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;
540 struct fman_kg_scheme_regs scheme_regs;
541 struct keygen_scheme *scheme;
542 u32 tmp_reg;
543 int err;
544
545 scheme = get_scheme(keygen, scheme_id);
546 if (!scheme) {
547 pr_err("Requested Scheme does not exist\n");
548 return -EINVAL;
549 }
550 if (enable && scheme->used) {
551 pr_err("The requested Scheme is already used\n");
552 return -EINVAL;
553 }
554
555
556 memset(&scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
557
558
559 tmp_reg = 0;
560
561 if (enable) {
562
563 tmp_reg |= KG_SCH_MODE_EN;
564
565 tmp_reg |= ENQUEUE_KG_DFLT_NIA;
566 }
567
568 scheme_regs.kgse_mode = tmp_reg;
569
570 scheme_regs.kgse_mv = scheme->match_vector;
571
572
573
574
575 scheme_regs.kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
576
577
578
579 if (scheme->use_hashing) {
580
581 scheme_regs.kgse_ekfc = DEFAULT_HASH_KEY_EXTRACT_FIELDS;
582
583
584 tmp_reg = 0;
585 tmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_0 <<
586 KG_SCH_DEF_IP_ADDR_SHIFT);
587 tmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_1 <<
588 KG_SCH_DEF_L4_PORT_SHIFT);
589 scheme_regs.kgse_ekdv = tmp_reg;
590
591
592 scheme_regs.kgse_dv0 = DEFAULT_HASH_KEY_IPv4_ADDR;
593
594 scheme_regs.kgse_dv1 = DEFAULT_HASH_KEY_L4_PORT;
595
596
597 tmp_reg = 0;
598 tmp_reg |= ((scheme->hash_fqid_count - 1) <<
599 DEFAULT_HASH_DIST_FQID_SHIFT);
600 tmp_reg |= scheme->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
601
602 if (scheme->symmetric_hash) {
603
604
605
606
607
608 tmp_reg |= KG_SCH_HASH_CONFIG_SYM;
609 }
610 scheme_regs.kgse_hc = tmp_reg;
611 } else {
612 scheme_regs.kgse_ekfc = 0;
613 scheme_regs.kgse_hc = 0;
614 scheme_regs.kgse_ekdv = 0;
615 scheme_regs.kgse_dv0 = 0;
616 scheme_regs.kgse_dv1 = 0;
617 }
618
619
620 tmp_reg = 0;
621 tmp_reg |= scheme->base_fqid;
622 scheme_regs.kgse_fqb = tmp_reg;
623
624
625 scheme_regs.kgse_bmch = 0;
626 scheme_regs.kgse_bmcl = 0;
627 scheme_regs.kgse_spc = 0;
628
629
630 err = keygen_write_scheme(keygen_regs, scheme_id, &scheme_regs, true);
631 if (err != 0) {
632 pr_err("Writing scheme registers failed\n");
633 return err;
634 }
635
636
637 scheme->used = enable;
638
639 return 0;
640}
641
642
643
644
645
646
647
648
649
650
651
652struct fman_keygen *keygen_init(struct fman_kg_regs __iomem *keygen_regs)
653{
654 struct fman_keygen *keygen;
655 u32 ar;
656 int i;
657
658
659 keygen = kzalloc(sizeof(*keygen), GFP_KERNEL);
660 if (!keygen)
661 return NULL;
662
663 keygen->keygen_regs = keygen_regs;
664
665
666
667
668 iowrite32be(ENQUEUE_KG_DFLT_NIA, &keygen_regs->fmkg_gcr);
669
670 iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
671 &keygen_regs->fmkg_eer);
672
673 iowrite32be(0, &keygen_regs->fmkg_fdor);
674 iowrite32be(0, &keygen_regs->fmkg_gdv0r);
675 iowrite32be(0, &keygen_regs->fmkg_gdv1r);
676
677
678
679
680 for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
681
682 keygen_write_sp(keygen_regs, 0xffffffff, false);
683 ar = build_ar_bind_scheme(i, true);
684 keygen_write_ar_wait(keygen_regs, ar);
685
686
687 keygen_write_cpp(keygen_regs, 0);
688 ar = build_ar_bind_cls_plan(i, true);
689 keygen_write_ar_wait(keygen_regs, ar);
690 }
691
692
693 iowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seer);
694 iowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seeer);
695
696
697 iowrite32be(ioread32be(&keygen_regs->fmkg_gcr) | FM_KG_KGGCR_EN,
698 &keygen_regs->fmkg_gcr);
699
700 return keygen;
701}
702EXPORT_SYMBOL(keygen_init);
703
704
705
706
707
708
709
710
711
712
713
714
715int keygen_port_hashing_init(struct fman_keygen *keygen, u8 hw_port_id,
716 u32 hash_base_fqid, u32 hash_size)
717{
718 struct keygen_scheme *scheme;
719 u8 scheme_id;
720 int err;
721
722
723 if (hash_base_fqid == 0 || (hash_base_fqid & ~0x00FFFFFF)) {
724 pr_err("Base FQID must be between 1 and 2^24-1\n");
725 return -EINVAL;
726 }
727 if (hash_size == 0 || (hash_size & (hash_size - 1)) != 0) {
728 pr_err("Hash size must be power of two\n");
729 return -EINVAL;
730 }
731
732
733 err = get_free_scheme_id(keygen, &scheme_id);
734 if (err) {
735 pr_err("The maximum number of available Schemes has been exceeded\n");
736 return -EINVAL;
737 }
738
739
740
741 scheme = get_scheme(keygen, scheme_id);
742 if (!scheme) {
743 pr_err("Requested Scheme does not exist\n");
744 return -EINVAL;
745 }
746 if (scheme->used) {
747 pr_err("The requested Scheme is already used\n");
748 return -EINVAL;
749 }
750
751
752
753
754 memset(scheme, 0, sizeof(struct keygen_scheme));
755
756
757 scheme->hw_port_id = hw_port_id;
758 scheme->use_hashing = true;
759 scheme->base_fqid = hash_base_fqid;
760 scheme->hash_fqid_count = hash_size;
761 scheme->symmetric_hash = DEFAULT_SYMMETRIC_HASH;
762 scheme->hashShift = DEFAULT_HASH_SHIFT;
763
764
765
766
767 scheme->match_vector = 0;
768
769 err = keygen_scheme_setup(keygen, scheme_id, true);
770 if (err != 0) {
771 pr_err("Scheme setup failed\n");
772 return err;
773 }
774
775
776 err = keygen_bind_port_to_schemes(keygen, scheme_id, true);
777 if (err != 0) {
778 pr_err("Binding port to schemes failed\n");
779 return err;
780 }
781
782 return 0;
783}
784EXPORT_SYMBOL(keygen_port_hashing_init);
785