1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/* Copyright (C) 2015-2018 Netronome Systems, Inc. */
3
4/*
5 * nfp_target.c
6 * CPP Access Width Decoder
7 * Authors: Jakub Kicinski <jakub.kicinski@netronome.com>
8 * Jason McMullan <jason.mcmullan@netronome.com>
9 * Francois H. Theron <francois.theron@netronome.com>
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/* This structure ONLY includes items that can be done with a read or write of
26 * 32-bit or 64-bit words. All others are not listed.
27 */
28
29#define AT(_action, _token, _pull, _push) \
30 case NFP_CPP_ID(0, (_action), (_token)): \
31 return PUSHPULL((_pull), (_push))
32
33static 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
44static int nfp6000_nbi_dma(u32 cpp_id)
45{
46 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
47 AT(0, 0, 0, P64); /* ReadNbiDma */
48 AT(1, 0, P64, 0); /* WriteNbiDma */
49 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
50 default:
51 return -EINVAL;
52 }
53}
54
55static int nfp6000_nbi_stats(u32 cpp_id)
56{
57 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
58 AT(0, 0, 0, P32); /* ReadNbiStats */
59 AT(1, 0, P32, 0); /* WriteNbiStats */
60 AT(NFP_CPP_ACTION_RW, 0, P32, P32);
61 default:
62 return -EINVAL;
63 }
64}
65
66static int nfp6000_nbi_tm(u32 cpp_id)
67{
68 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
69 AT(0, 0, 0, P64); /* ReadNbiTM */
70 AT(1, 0, P64, 0); /* WriteNbiTM */
71 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
72 default:
73 return -EINVAL;
74 }
75}
76
77static int nfp6000_nbi_ppc(u32 cpp_id)
78{
79 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
80 AT(0, 0, 0, P64); /* ReadNbiPreclassifier */
81 AT(1, 0, P64, 0); /* WriteNbiPreclassifier */
82 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
83 default:
84 return -EINVAL;
85 }
86}
87
88static 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/* This structure ONLY includes items that can be done with a read or write of
102 * 32-bit or 64-bit words. All others are not listed.
103 */
104static 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); /* read_be/write_be */
108 AT(NFP_CPP_ACTION_RW, 1, P64, P64); /* read_le/write_le */
109 AT(NFP_CPP_ACTION_RW, 2, P64, P64); /* read_swap_be/write_swap_be */
110 AT(NFP_CPP_ACTION_RW, 3, P64, P64); /* read_swap_le/write_swap_le */
111 AT(0, 0, 0, P64); /* read_be */
112 AT(0, 1, 0, P64); /* read_le */
113 AT(0, 2, 0, P64); /* read_swap_be */
114 AT(0, 3, 0, P64); /* read_swap_le */
115 AT(1, 0, P64, 0); /* write_be */
116 AT(1, 1, P64, 0); /* write_le */
117 AT(1, 2, P64, 0); /* write_swap_be */
118 AT(1, 3, P64, 0); /* write_swap_le */
119 AT(3, 0, 0, P32); /* atomic_read */
120 AT(3, 2, P32, 0); /* mask_compare_write */
121 AT(4, 0, P32, 0); /* atomic_write */
122 AT(4, 2, 0, 0); /* atomic_write_imm */
123 AT(4, 3, 0, P32); /* swap_imm */
124 AT(5, 0, P32, 0); /* set */
125 AT(5, 3, 0, P32); /* test_set_imm */
126 AT(6, 0, P32, 0); /* clr */
127 AT(6, 3, 0, P32); /* test_clr_imm */
128 AT(7, 0, P32, 0); /* add */
129 AT(7, 3, 0, P32); /* test_add_imm */
130 AT(8, 0, P32, 0); /* addsat */
131 AT(8, 3, 0, P32); /* test_subsat_imm */
132 AT(9, 0, P32, 0); /* sub */
133 AT(9, 3, 0, P32); /* test_sub_imm */
134 AT(10, 0, P32, 0); /* subsat */
135 AT(10, 3, 0, P32); /* test_subsat_imm */
136 AT(13, 0, 0, P32); /* microq128_get */
137 AT(13, 1, 0, P32); /* microq128_pop */
138 AT(13, 2, P32, 0); /* microq128_put */
139 AT(15, 0, P32, 0); /* xor */
140 AT(15, 3, 0, P32); /* test_xor_imm */
141 AT(28, 0, 0, P32); /* read32_be */
142 AT(28, 1, 0, P32); /* read32_le */
143 AT(28, 2, 0, P32); /* read32_swap_be */
144 AT(28, 3, 0, P32); /* read32_swap_le */
145 AT(31, 0, P32, 0); /* write32_be */
146 AT(31, 1, P32, 0); /* write32_le */
147 AT(31, 2, P32, 0); /* write32_swap_be */
148 AT(31, 3, P32, 0); /* write32_swap_le */
149 default:
150 return -EINVAL;
151 }
152}
153
154static int nfp6000_mu_ctm(u32 cpp_id)
155{
156 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
157 AT(16, 1, 0, P32); /* packet_read_packet_status */
158 AT(17, 1, 0, P32); /* packet_credit_get */
159 AT(17, 3, 0, P64); /* packet_add_thread */
160 AT(18, 2, 0, P64); /* packet_free_and_return_pointer */
161 AT(18, 3, 0, P64); /* packet_return_pointer */
162 AT(21, 0, 0, P64); /* pe_dma_to_memory_indirect */
163 AT(21, 1, 0, P64); /* pe_dma_to_memory_indirect_swap */
164 AT(21, 2, 0, P64); /* pe_dma_to_memory_indirect_free */
165 AT(21, 3, 0, P64); /* pe_dma_to_memory_indirect_free_swap */
166 default:
167 return nfp6000_mu_common(cpp_id);
168 }
169}
170
171static int nfp6000_mu_emu(u32 cpp_id)
172{
173 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
174 AT(18, 0, 0, P32); /* read_queue */
175 AT(18, 1, 0, P32); /* read_queue_ring */
176 AT(18, 2, P32, 0); /* write_queue */
177 AT(18, 3, P32, 0); /* write_queue_ring */
178 AT(20, 2, P32, 0); /* journal */
179 AT(21, 0, 0, P32); /* get */
180 AT(21, 1, 0, P32); /* get_eop */
181 AT(21, 2, 0, P32); /* get_freely */
182 AT(22, 0, 0, P32); /* pop */
183 AT(22, 1, 0, P32); /* pop_eop */
184 AT(22, 2, 0, P32); /* pop_freely */
185 default:
186 return nfp6000_mu_common(cpp_id);
187 }
188}
189
190static int nfp6000_mu_imu(u32 cpp_id)
191{
192 return nfp6000_mu_common(cpp_id);
193}
194
195static 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
215static int nfp6000_ila(u32 cpp_id)
216{
217 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
218 AT(0, 1, 0, P32); /* read_check_error */
219 AT(2, 0, 0, P32); /* read_int */
220 AT(3, 0, P32, 0); /* write_int */
221 default:
222 return target_rw(cpp_id, P32, start: 48, len: 4);
223 }
224}
225
226static 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, start: 4, len: 4);
233 }
234}
235
236static 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, start: 12, len: 4);
242 }
243}
244
245static int nfp6000_cap_xpb(u32 cpp_id)
246{
247 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
248 AT(0, 1, 0, P32); /* RingGet */
249 AT(0, 2, P32, 0); /* Interthread Signal */
250 AT(1, 1, P32, 0); /* RingPut */
251 AT(1, 2, P32, 0); /* CTNNWr */
252 AT(2, 0, 0, P32); /* ReflectRd, signal none */
253 AT(2, 1, 0, P32); /* ReflectRd, signal self */
254 AT(2, 2, 0, P32); /* ReflectRd, signal remote */
255 AT(2, 3, 0, P32); /* ReflectRd, signal both */
256 AT(3, 0, P32, 0); /* ReflectWr, signal none */
257 AT(3, 1, P32, 0); /* ReflectWr, signal self */
258 AT(3, 2, P32, 0); /* ReflectWr, signal remote */
259 AT(3, 3, P32, 0); /* ReflectWr, signal both */
260 AT(NFP_CPP_ACTION_RW, 1, P32, P32);
261 default:
262 return target_rw(cpp_id, P32, start: 1, len: 63);
263 }
264}
265
266static int nfp6000_cls(u32 cpp_id)
267{
268 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
269 AT(0, 3, P32, 0); /* xor */
270 AT(2, 0, P32, 0); /* set */
271 AT(2, 1, P32, 0); /* clr */
272 AT(4, 0, P32, 0); /* add */
273 AT(4, 1, P32, 0); /* add64 */
274 AT(6, 0, P32, 0); /* sub */
275 AT(6, 1, P32, 0); /* sub64 */
276 AT(6, 2, P32, 0); /* subsat */
277 AT(8, 2, P32, 0); /* hash_mask */
278 AT(8, 3, P32, 0); /* hash_clear */
279 AT(9, 0, 0, P32); /* ring_get */
280 AT(9, 1, 0, P32); /* ring_pop */
281 AT(9, 2, 0, P32); /* ring_get_freely */
282 AT(9, 3, 0, P32); /* ring_pop_freely */
283 AT(10, 0, P32, 0); /* ring_put */
284 AT(10, 2, P32, 0); /* ring_journal */
285 AT(14, 0, P32, 0); /* reflect_write_sig_local */
286 AT(15, 1, 0, P32); /* reflect_read_sig_local */
287 AT(17, 2, P32, 0); /* statisic */
288 AT(24, 0, 0, P32); /* ring_read */
289 AT(24, 1, P32, 0); /* ring_write */
290 AT(25, 0, 0, P32); /* ring_workq_add_thread */
291 AT(25, 1, P32, 0); /* ring_workq_add_work */
292 default:
293 return target_rw(cpp_id, P32, start: 0, len: 64);
294 }
295}
296
297int nfp_target_pushpull(u32 cpp_id, u64 address)
298{
299 switch (NFP_CPP_ID_TARGET_of(id: 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, start: 24, len: 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, start: 1, len: 1);
313 else
314 return target_rw(cpp_id, P32, start: 1, len: 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, start: 4, len: 4);
323 default:
324 return -EINVAL;
325 }
326}
327
328#undef AT
329#undef P32
330#undef P64
331
332/* All magic NFP-6xxx IMB 'mode' numbers here are from:
333 * Databook (1 August 2013)
334 * - System Overview and Connectivity
335 * -- Internal Connectivity
336 * --- Distributed Switch Fabric - Command Push/Pull (DSF-CPP) Bus
337 * ---- CPP addressing
338 * ----- Table 3.6. CPP Address Translation Mode Commands
339 */
340
341#define _NIC_NFP6000_MU_LOCALITY_DIRECT 2
342
343static 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 /* This function doesn't handle MU or CTXBP */
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 /* For VQDR, in this mode for 32-bit addressing
355 * it would be islands 0, 16, 32 and 48 depending on channel
356 * and upper address bits.
357 * Since those are not all valid islands, most decode
358 * cases would result in bad island IDs, but we do them
359 * anyway since this is decoding an address that is already
360 * assumed to be used as-is to get to sram.
361 */
362 iid_lsb = addr40 ? 34 : 26;
363 *dest_island = (addr >> iid_lsb) & 0x3F;
364 return 0;
365 case 1:
366 /* For VQDR 32-bit, this would decode as:
367 * Channel 0: island#0
368 * Channel 1: island#0
369 * Channel 2: island#1
370 * Channel 3: island#1
371 * That would be valid as long as both islands
372 * have VQDR. Let's allow this.
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 /* For VQDR 32-bit:
383 * Channel 0: (island#0 | 0)
384 * Channel 1: (island#0 | 1)
385 * Channel 2: (island#1 | 0)
386 * Channel 3: (island#1 | 1)
387 *
388 * Make sure we compare against isldN values
389 * by clearing the LSB.
390 * This is what the silicon does.
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 /* In this mode the data address starts to affect the island ID
406 * so rather not allow it. In some really specific case
407 * one could use this to send the upper half of the
408 * VQDR channel to another MU, but this is getting very
409 * specific.
410 * However, as above for mode 0, this is the decoder
411 * and the caller should validate the resulting IID.
412 * This blindly does what the silicon would do.
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
431static 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 /* Full Island ID and channel bits overlap? */
437 ret = nfp_decode_basic(addr, dest_island: &v, cpp_tgt, mode, addr40, isld1, isld0);
438 if (ret)
439 return ret;
440
441 /* The current address won't go where expected? */
442 if (dest_island != -1 && dest_island != v)
443 return -EINVAL;
444
445 /* If dest_island was -1, we don't care where it goes. */
446 return 0;
447}
448
449/* Try each option, take first one that fits.
450 * Not sure if we would want to do some smarter
451 * searching and prefer 0 or non-0 island IDs.
452 */
453static 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/* For VQDR, we may not modify the Channel bits, which might overlap
473 * with the Index bit. When it does, we need to ensure that isld0 == isld1.
474 */
475static 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 /* This function doesn't handle MU or CTXBP */
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 /* In this specific mode we'd rather not modify
493 * the address but we can verify if the existing
494 * contents will point to a valid island.
495 */
496 return nfp_encode_basic_qdr(addr: *addr, dest_island: cpp_tgt, cpp_tgt: dest_island,
497 mode, addr40, isld1, isld0);
498
499 iid_lsb = addr40 ? 34 : 26;
500 /* <39:34> or <31:26> */
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: *addr, dest_island: cpp_tgt, cpp_tgt: dest_island,
508 mode, addr40, isld1, isld0);
509
510 idx_lsb = addr40 ? 39 : 31;
511 if (dest_island == isld0) {
512 /* Only need to clear the Index bit */
513 *addr &= ~BIT_ULL(idx_lsb);
514 return 0;
515 }
516
517 if (dest_island == isld1) {
518 /* Only need to set the Index bit */
519 *addr |= BIT_ULL(idx_lsb);
520 return 0;
521 }
522
523 return -ENODEV;
524 case 2:
525 /* iid<0> = addr<30> = channel<0>
526 * channel<1> = addr<31> = Index
527 */
528 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
529 /* Special case where we allow channel bits to
530 * be set before hand and with them select an island.
531 * So we need to confirm that it's at least plausible.
532 */
533 return nfp_encode_basic_qdr(addr: *addr, dest_island: cpp_tgt, cpp_tgt: dest_island,
534 mode, addr40, isld1, isld0);
535
536 /* Make sure we compare against isldN values
537 * by clearing the LSB.
538 * This is what the silicon does.
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, v_max: 2);
548 case 3:
549 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
550 /* iid<0> = addr<29> = data
551 * iid<1> = addr<30> = channel<0>
552 * channel<1> = addr<31> = Index
553 */
554 return nfp_encode_basic_qdr(addr: *addr, dest_island: cpp_tgt, 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, v_max: 4);
565 default:
566 return -EINVAL;
567 }
568}
569
570static 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 /* Make sure we compare against isldN values
625 * by clearing the LSB.
626 * This is what the silicon does.
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, v_max: 2);
636 case 3:
637 /* Only the EMU will use 40 bit addressing. Silently
638 * set the direct locality bit for everyone else.
639 * The SDK toolchain uses dest_island <= 0 to test
640 * for atypical address encodings to support access
641 * to local-island CTM with a 32-but address (high-locality
642 * is effewctively ignored and just used for
643 * routing to island #0).
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, v_max: 4);
667 default:
668 return -EINVAL;
669 }
670}
671
672static 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
701int 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(id: cpp_island_id);
706 const int target = NFP_CPP_ID_TARGET_of(id: 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 /* Already translated */
717 *cpp_target_id = cpp_island_id;
718 *cpp_target_address = cpp_island_address;
719 return 0;
720 }
721
722 /* CPP + Island only allowed on systems with IMB tables */
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(addr: cpp_target_address, dest_island: island, cpp_tgt: target,
730 mode: ((imb >> 13) & 7), addr40: ((imb >> 12) & 1),
731 isld1: ((imb >> 6) & 0x3f), isld0: ((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}
743

source code of linux/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_target.c