This source file includes following definitions.
- target_rw
- nfp6000_nbi_dma
- nfp6000_nbi_stats
- nfp6000_nbi_tm
- nfp6000_nbi_ppc
- nfp6000_nbi
- nfp6000_mu_common
- nfp6000_mu_ctm
- nfp6000_mu_emu
- nfp6000_mu_imu
- nfp6000_mu
- nfp6000_ila
- nfp6000_pci
- nfp6000_crypto
- nfp6000_cap_xpb
- nfp6000_cls
- nfp_target_pushpull
- nfp_decode_basic
- nfp_encode_basic_qdr
- nfp_encode_basic_search
- nfp_encode_basic
- nfp_encode_mu
- nfp_cppat_addr_encode
- nfp_target_cpp
1
2
3
4
5
6
7
8
9
10
11
12 #define pr_fmt(fmt) "NFP target: " fmt
13
14 #include <linux/bitops.h>
15 #include <linux/kernel.h>
16 #include <linux/printk.h>
17
18 #include "nfp_cpp.h"
19
20 #include "nfp6000/nfp6000.h"
21
22 #define P32 1
23 #define P64 2
24
25
26
27
28
29 #define AT(_action, _token, _pull, _push) \
30 case NFP_CPP_ID(0, (_action), (_token)): \
31 return PUSHPULL((_pull), (_push))
32
33 static int target_rw(u32 cpp_id, int pp, int start, int len)
34 {
35 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
36 AT(0, 0, 0, pp);
37 AT(1, 0, pp, 0);
38 AT(NFP_CPP_ACTION_RW, 0, pp, pp);
39 default:
40 return -EINVAL;
41 }
42 }
43
44 static int nfp6000_nbi_dma(u32 cpp_id)
45 {
46 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
47 AT(0, 0, 0, P64);
48 AT(1, 0, P64, 0);
49 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
50 default:
51 return -EINVAL;
52 }
53 }
54
55 static int nfp6000_nbi_stats(u32 cpp_id)
56 {
57 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
58 AT(0, 0, 0, P32);
59 AT(1, 0, P32, 0);
60 AT(NFP_CPP_ACTION_RW, 0, P32, P32);
61 default:
62 return -EINVAL;
63 }
64 }
65
66 static int nfp6000_nbi_tm(u32 cpp_id)
67 {
68 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
69 AT(0, 0, 0, P64);
70 AT(1, 0, P64, 0);
71 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
72 default:
73 return -EINVAL;
74 }
75 }
76
77 static int nfp6000_nbi_ppc(u32 cpp_id)
78 {
79 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
80 AT(0, 0, 0, P64);
81 AT(1, 0, P64, 0);
82 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
83 default:
84 return -EINVAL;
85 }
86 }
87
88 static int nfp6000_nbi(u32 cpp_id, u64 address)
89 {
90 u64 rel_addr = address & 0x3fFFFF;
91
92 if (rel_addr < (1 << 20))
93 return nfp6000_nbi_dma(cpp_id);
94 if (rel_addr < (2 << 20))
95 return nfp6000_nbi_stats(cpp_id);
96 if (rel_addr < (3 << 20))
97 return nfp6000_nbi_tm(cpp_id);
98 return nfp6000_nbi_ppc(cpp_id);
99 }
100
101
102
103
104 static int nfp6000_mu_common(u32 cpp_id)
105 {
106 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
107 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
108 AT(NFP_CPP_ACTION_RW, 1, P64, P64);
109 AT(NFP_CPP_ACTION_RW, 2, P64, P64);
110 AT(NFP_CPP_ACTION_RW, 3, P64, P64);
111 AT(0, 0, 0, P64);
112 AT(0, 1, 0, P64);
113 AT(0, 2, 0, P64);
114 AT(0, 3, 0, P64);
115 AT(1, 0, P64, 0);
116 AT(1, 1, P64, 0);
117 AT(1, 2, P64, 0);
118 AT(1, 3, P64, 0);
119 AT(3, 0, 0, P32);
120 AT(3, 2, P32, 0);
121 AT(4, 0, P32, 0);
122 AT(4, 2, 0, 0);
123 AT(4, 3, 0, P32);
124 AT(5, 0, P32, 0);
125 AT(5, 3, 0, P32);
126 AT(6, 0, P32, 0);
127 AT(6, 3, 0, P32);
128 AT(7, 0, P32, 0);
129 AT(7, 3, 0, P32);
130 AT(8, 0, P32, 0);
131 AT(8, 3, 0, P32);
132 AT(9, 0, P32, 0);
133 AT(9, 3, 0, P32);
134 AT(10, 0, P32, 0);
135 AT(10, 3, 0, P32);
136 AT(13, 0, 0, P32);
137 AT(13, 1, 0, P32);
138 AT(13, 2, P32, 0);
139 AT(15, 0, P32, 0);
140 AT(15, 3, 0, P32);
141 AT(28, 0, 0, P32);
142 AT(28, 1, 0, P32);
143 AT(28, 2, 0, P32);
144 AT(28, 3, 0, P32);
145 AT(31, 0, P32, 0);
146 AT(31, 1, P32, 0);
147 AT(31, 2, P32, 0);
148 AT(31, 3, P32, 0);
149 default:
150 return -EINVAL;
151 }
152 }
153
154 static int nfp6000_mu_ctm(u32 cpp_id)
155 {
156 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
157 AT(16, 1, 0, P32);
158 AT(17, 1, 0, P32);
159 AT(17, 3, 0, P64);
160 AT(18, 2, 0, P64);
161 AT(18, 3, 0, P64);
162 AT(21, 0, 0, P64);
163 AT(21, 1, 0, P64);
164 AT(21, 2, 0, P64);
165 AT(21, 3, 0, P64);
166 default:
167 return nfp6000_mu_common(cpp_id);
168 }
169 }
170
171 static int nfp6000_mu_emu(u32 cpp_id)
172 {
173 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
174 AT(18, 0, 0, P32);
175 AT(18, 1, 0, P32);
176 AT(18, 2, P32, 0);
177 AT(18, 3, P32, 0);
178 AT(20, 2, P32, 0);
179 AT(21, 0, 0, P32);
180 AT(21, 1, 0, P32);
181 AT(21, 2, 0, P32);
182 AT(22, 0, 0, P32);
183 AT(22, 1, 0, P32);
184 AT(22, 2, 0, P32);
185 default:
186 return nfp6000_mu_common(cpp_id);
187 }
188 }
189
190 static int nfp6000_mu_imu(u32 cpp_id)
191 {
192 return nfp6000_mu_common(cpp_id);
193 }
194
195 static int nfp6000_mu(u32 cpp_id, u64 address)
196 {
197 int pp;
198
199 if (address < 0x2000000000ULL)
200 pp = nfp6000_mu_ctm(cpp_id);
201 else if (address < 0x8000000000ULL)
202 pp = nfp6000_mu_emu(cpp_id);
203 else if (address < 0x9800000000ULL)
204 pp = nfp6000_mu_ctm(cpp_id);
205 else if (address < 0x9C00000000ULL)
206 pp = nfp6000_mu_emu(cpp_id);
207 else if (address < 0xA000000000ULL)
208 pp = nfp6000_mu_imu(cpp_id);
209 else
210 pp = nfp6000_mu_ctm(cpp_id);
211
212 return pp;
213 }
214
215 static int nfp6000_ila(u32 cpp_id)
216 {
217 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
218 AT(0, 1, 0, P32);
219 AT(2, 0, 0, P32);
220 AT(3, 0, P32, 0);
221 default:
222 return target_rw(cpp_id, P32, 48, 4);
223 }
224 }
225
226 static int nfp6000_pci(u32 cpp_id)
227 {
228 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
229 AT(2, 0, 0, P32);
230 AT(3, 0, P32, 0);
231 default:
232 return target_rw(cpp_id, P32, 4, 4);
233 }
234 }
235
236 static int nfp6000_crypto(u32 cpp_id)
237 {
238 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
239 AT(2, 0, P64, 0);
240 default:
241 return target_rw(cpp_id, P64, 12, 4);
242 }
243 }
244
245 static int nfp6000_cap_xpb(u32 cpp_id)
246 {
247 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
248 AT(0, 1, 0, P32);
249 AT(0, 2, P32, 0);
250 AT(1, 1, P32, 0);
251 AT(1, 2, P32, 0);
252 AT(2, 0, 0, P32);
253 AT(2, 1, 0, P32);
254 AT(2, 2, 0, P32);
255 AT(2, 3, 0, P32);
256 AT(3, 0, P32, 0);
257 AT(3, 1, P32, 0);
258 AT(3, 2, P32, 0);
259 AT(3, 3, P32, 0);
260 AT(NFP_CPP_ACTION_RW, 1, P32, P32);
261 default:
262 return target_rw(cpp_id, P32, 1, 63);
263 }
264 }
265
266 static int nfp6000_cls(u32 cpp_id)
267 {
268 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
269 AT(0, 3, P32, 0);
270 AT(2, 0, P32, 0);
271 AT(2, 1, P32, 0);
272 AT(4, 0, P32, 0);
273 AT(4, 1, P32, 0);
274 AT(6, 0, P32, 0);
275 AT(6, 1, P32, 0);
276 AT(6, 2, P32, 0);
277 AT(8, 2, P32, 0);
278 AT(8, 3, P32, 0);
279 AT(9, 0, 0, P32);
280 AT(9, 1, 0, P32);
281 AT(9, 2, 0, P32);
282 AT(9, 3, 0, P32);
283 AT(10, 0, P32, 0);
284 AT(10, 2, P32, 0);
285 AT(14, 0, P32, 0);
286 AT(15, 1, 0, P32);
287 AT(17, 2, P32, 0);
288 AT(24, 0, 0, P32);
289 AT(24, 1, P32, 0);
290 AT(25, 0, 0, P32);
291 AT(25, 1, P32, 0);
292 default:
293 return target_rw(cpp_id, P32, 0, 64);
294 }
295 }
296
297 int nfp_target_pushpull(u32 cpp_id, u64 address)
298 {
299 switch (NFP_CPP_ID_TARGET_of(cpp_id)) {
300 case NFP_CPP_TARGET_NBI:
301 return nfp6000_nbi(cpp_id, address);
302 case NFP_CPP_TARGET_QDR:
303 return target_rw(cpp_id, P32, 24, 4);
304 case NFP_CPP_TARGET_ILA:
305 return nfp6000_ila(cpp_id);
306 case NFP_CPP_TARGET_MU:
307 return nfp6000_mu(cpp_id, address);
308 case NFP_CPP_TARGET_PCIE:
309 return nfp6000_pci(cpp_id);
310 case NFP_CPP_TARGET_ARM:
311 if (address < 0x10000)
312 return target_rw(cpp_id, P64, 1, 1);
313 else
314 return target_rw(cpp_id, P32, 1, 1);
315 case NFP_CPP_TARGET_CRYPTO:
316 return nfp6000_crypto(cpp_id);
317 case NFP_CPP_TARGET_CT_XPB:
318 return nfp6000_cap_xpb(cpp_id);
319 case NFP_CPP_TARGET_CLS:
320 return nfp6000_cls(cpp_id);
321 case 0:
322 return target_rw(cpp_id, P32, 4, 4);
323 default:
324 return -EINVAL;
325 }
326 }
327
328 #undef AT
329 #undef P32
330 #undef P64
331
332
333
334
335
336
337
338
339
340
341 #define _NIC_NFP6000_MU_LOCALITY_DIRECT 2
342
343 static int nfp_decode_basic(u64 addr, int *dest_island, int cpp_tgt,
344 int mode, bool addr40, int isld1, int isld0)
345 {
346 int iid_lsb, idx_lsb;
347
348
349 if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
350 return -EINVAL;
351
352 switch (mode) {
353 case 0:
354
355
356
357
358
359
360
361
362 iid_lsb = addr40 ? 34 : 26;
363 *dest_island = (addr >> iid_lsb) & 0x3F;
364 return 0;
365 case 1:
366
367
368
369
370
371
372
373
374 idx_lsb = addr40 ? 39 : 31;
375 if (addr & BIT_ULL(idx_lsb))
376 *dest_island = isld1;
377 else
378 *dest_island = isld0;
379
380 return 0;
381 case 2:
382
383
384
385
386
387
388
389
390
391
392 isld0 &= ~1;
393 isld1 &= ~1;
394
395 idx_lsb = addr40 ? 39 : 31;
396 iid_lsb = idx_lsb - 1;
397
398 if (addr & BIT_ULL(idx_lsb))
399 *dest_island = isld1 | (int)((addr >> iid_lsb) & 1);
400 else
401 *dest_island = isld0 | (int)((addr >> iid_lsb) & 1);
402
403 return 0;
404 case 3:
405
406
407
408
409
410
411
412
413
414 isld0 &= ~3;
415 isld1 &= ~3;
416
417 idx_lsb = addr40 ? 39 : 31;
418 iid_lsb = idx_lsb - 2;
419
420 if (addr & BIT_ULL(idx_lsb))
421 *dest_island = isld1 | (int)((addr >> iid_lsb) & 3);
422 else
423 *dest_island = isld0 | (int)((addr >> iid_lsb) & 3);
424
425 return 0;
426 default:
427 return -EINVAL;
428 }
429 }
430
431 static int nfp_encode_basic_qdr(u64 addr, int dest_island, int cpp_tgt,
432 int mode, bool addr40, int isld1, int isld0)
433 {
434 int v, ret;
435
436
437 ret = nfp_decode_basic(addr, &v, cpp_tgt, mode, addr40, isld1, isld0);
438 if (ret)
439 return ret;
440
441
442 if (dest_island != -1 && dest_island != v)
443 return -EINVAL;
444
445
446 return 0;
447 }
448
449
450
451
452
453 static int nfp_encode_basic_search(u64 *addr, int dest_island, int *isld,
454 int iid_lsb, int idx_lsb, int v_max)
455 {
456 int i, v;
457
458 for (i = 0; i < 2; i++)
459 for (v = 0; v < v_max; v++) {
460 if (dest_island != (isld[i] | v))
461 continue;
462
463 *addr &= ~GENMASK_ULL(idx_lsb, iid_lsb);
464 *addr |= ((u64)i << idx_lsb);
465 *addr |= ((u64)v << iid_lsb);
466 return 0;
467 }
468
469 return -ENODEV;
470 }
471
472
473
474
475 static int nfp_encode_basic(u64 *addr, int dest_island, int cpp_tgt,
476 int mode, bool addr40, int isld1, int isld0)
477 {
478 int iid_lsb, idx_lsb;
479 int isld[2];
480 u64 v64;
481
482 isld[0] = isld0;
483 isld[1] = isld1;
484
485
486 if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
487 return -EINVAL;
488
489 switch (mode) {
490 case 0:
491 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
492
493
494
495
496 return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
497 mode, addr40, isld1, isld0);
498
499 iid_lsb = addr40 ? 34 : 26;
500
501 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
502 *addr &= ~v64;
503 *addr |= ((u64)dest_island << iid_lsb) & v64;
504 return 0;
505 case 1:
506 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
507 return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
508 mode, addr40, isld1, isld0);
509
510 idx_lsb = addr40 ? 39 : 31;
511 if (dest_island == isld0) {
512
513 *addr &= ~BIT_ULL(idx_lsb);
514 return 0;
515 }
516
517 if (dest_island == isld1) {
518
519 *addr |= BIT_ULL(idx_lsb);
520 return 0;
521 }
522
523 return -ENODEV;
524 case 2:
525
526
527
528 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
529
530
531
532
533 return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
534 mode, addr40, isld1, isld0);
535
536
537
538
539
540 isld[0] &= ~1;
541 isld[1] &= ~1;
542
543 idx_lsb = addr40 ? 39 : 31;
544 iid_lsb = idx_lsb - 1;
545
546 return nfp_encode_basic_search(addr, dest_island, isld,
547 iid_lsb, idx_lsb, 2);
548 case 3:
549 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
550
551
552
553
554 return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
555 mode, addr40, isld1, isld0);
556
557 isld[0] &= ~3;
558 isld[1] &= ~3;
559
560 idx_lsb = addr40 ? 39 : 31;
561 iid_lsb = idx_lsb - 2;
562
563 return nfp_encode_basic_search(addr, dest_island, isld,
564 iid_lsb, idx_lsb, 4);
565 default:
566 return -EINVAL;
567 }
568 }
569
570 static int nfp_encode_mu(u64 *addr, int dest_island, int mode,
571 bool addr40, int isld1, int isld0)
572 {
573 int iid_lsb, idx_lsb, locality_lsb;
574 int isld[2];
575 u64 v64;
576 int da;
577
578 isld[0] = isld0;
579 isld[1] = isld1;
580 locality_lsb = nfp_cppat_mu_locality_lsb(mode, addr40);
581
582 if (((*addr >> locality_lsb) & 3) == _NIC_NFP6000_MU_LOCALITY_DIRECT)
583 da = 1;
584 else
585 da = 0;
586
587 switch (mode) {
588 case 0:
589 iid_lsb = addr40 ? 32 : 24;
590 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
591 *addr &= ~v64;
592 *addr |= (((u64)dest_island) << iid_lsb) & v64;
593 return 0;
594 case 1:
595 if (da) {
596 iid_lsb = addr40 ? 32 : 24;
597 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
598 *addr &= ~v64;
599 *addr |= (((u64)dest_island) << iid_lsb) & v64;
600 return 0;
601 }
602
603 idx_lsb = addr40 ? 37 : 29;
604 if (dest_island == isld0) {
605 *addr &= ~BIT_ULL(idx_lsb);
606 return 0;
607 }
608
609 if (dest_island == isld1) {
610 *addr |= BIT_ULL(idx_lsb);
611 return 0;
612 }
613
614 return -ENODEV;
615 case 2:
616 if (da) {
617 iid_lsb = addr40 ? 32 : 24;
618 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
619 *addr &= ~v64;
620 *addr |= (((u64)dest_island) << iid_lsb) & v64;
621 return 0;
622 }
623
624
625
626
627
628 isld[0] &= ~1;
629 isld[1] &= ~1;
630
631 idx_lsb = addr40 ? 37 : 29;
632 iid_lsb = idx_lsb - 1;
633
634 return nfp_encode_basic_search(addr, dest_island, isld,
635 iid_lsb, idx_lsb, 2);
636 case 3:
637
638
639
640
641
642
643
644
645 if (dest_island > 0 && (dest_island < 24 || dest_island > 26)) {
646 *addr |= ((u64)_NIC_NFP6000_MU_LOCALITY_DIRECT)
647 << locality_lsb;
648 da = 1;
649 }
650
651 if (da) {
652 iid_lsb = addr40 ? 32 : 24;
653 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
654 *addr &= ~v64;
655 *addr |= (((u64)dest_island) << iid_lsb) & v64;
656 return 0;
657 }
658
659 isld[0] &= ~3;
660 isld[1] &= ~3;
661
662 idx_lsb = addr40 ? 37 : 29;
663 iid_lsb = idx_lsb - 2;
664
665 return nfp_encode_basic_search(addr, dest_island, isld,
666 iid_lsb, idx_lsb, 4);
667 default:
668 return -EINVAL;
669 }
670 }
671
672 static int nfp_cppat_addr_encode(u64 *addr, int dest_island, int cpp_tgt,
673 int mode, bool addr40, int isld1, int isld0)
674 {
675 switch (cpp_tgt) {
676 case NFP_CPP_TARGET_NBI:
677 case NFP_CPP_TARGET_QDR:
678 case NFP_CPP_TARGET_ILA:
679 case NFP_CPP_TARGET_PCIE:
680 case NFP_CPP_TARGET_ARM:
681 case NFP_CPP_TARGET_CRYPTO:
682 case NFP_CPP_TARGET_CLS:
683 return nfp_encode_basic(addr, dest_island, cpp_tgt, mode,
684 addr40, isld1, isld0);
685
686 case NFP_CPP_TARGET_MU:
687 return nfp_encode_mu(addr, dest_island, mode,
688 addr40, isld1, isld0);
689
690 case NFP_CPP_TARGET_CT_XPB:
691 if (mode != 1 || addr40)
692 return -EINVAL;
693 *addr &= ~GENMASK_ULL(29, 24);
694 *addr |= ((u64)dest_island << 24) & GENMASK_ULL(29, 24);
695 return 0;
696 default:
697 return -EINVAL;
698 }
699 }
700
701 int nfp_target_cpp(u32 cpp_island_id, u64 cpp_island_address,
702 u32 *cpp_target_id, u64 *cpp_target_address,
703 const u32 *imb_table)
704 {
705 const int island = NFP_CPP_ID_ISLAND_of(cpp_island_id);
706 const int target = NFP_CPP_ID_TARGET_of(cpp_island_id);
707 u32 imb;
708 int err;
709
710 if (target < 0 || target >= 16) {
711 pr_err("Invalid CPP target: %d\n", target);
712 return -EINVAL;
713 }
714
715 if (island == 0) {
716
717 *cpp_target_id = cpp_island_id;
718 *cpp_target_address = cpp_island_address;
719 return 0;
720 }
721
722
723 if (!imb_table)
724 return -EINVAL;
725
726 imb = imb_table[target];
727
728 *cpp_target_address = cpp_island_address;
729 err = nfp_cppat_addr_encode(cpp_target_address, island, target,
730 ((imb >> 13) & 7), ((imb >> 12) & 1),
731 ((imb >> 6) & 0x3f), ((imb >> 0) & 0x3f));
732 if (err) {
733 pr_err("Can't encode CPP address: %d\n", err);
734 return err;
735 }
736
737 *cpp_target_id = NFP_CPP_ID(target,
738 NFP_CPP_ID_ACTION_of(cpp_island_id),
739 NFP_CPP_ID_TOKEN_of(cpp_island_id));
740
741 return 0;
742 }