1 /*
2 * Copyright (C) 2015-2017 Netronome Systems, Inc.
3 *
4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree or the BSD 2-Clause License provided below. You have the
7 * option to license this software under the complete terms of either license.
8 *
9 * The BSD 2-Clause License:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34 /*
35 * nfp_target.c
36 * CPP Access Width Decoder
37 * Authors: Jakub Kicinski <jakub.kicinski@netronome.com>
38 * Jason McMullan <jason.mcmullan@netronome.com>
39 * Francois H. Theron <francois.theron@netronome.com>
40 */
41
42 #include <linux/bitops.h>
43
44 #include "nfp_cpp.h"
45
46 #include "nfp6000/nfp6000.h"
47
48 #define P32 1
49 #define P64 2
50
51 /* This structure ONLY includes items that can be done with a read or write of
52 * 32-bit or 64-bit words. All others are not listed.
53 */
54
55 #define AT(_action, _token, _pull, _push) \
56 case NFP_CPP_ID(0, (_action), (_token)): \
57 return PUSHPULL((_pull), (_push))
58
target_rw(u32 cpp_id,int pp,int start,int len)59 static int target_rw(u32 cpp_id, int pp, int start, int len)
60 {
61 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
62 AT(0, 0, 0, pp);
63 AT(1, 0, pp, 0);
64 AT(NFP_CPP_ACTION_RW, 0, pp, pp);
65 default:
66 return -EINVAL;
67 }
68 }
69
nfp6000_nbi_dma(u32 cpp_id)70 static int nfp6000_nbi_dma(u32 cpp_id)
71 {
72 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
73 AT(0, 0, 0, P64); /* ReadNbiDma */
74 AT(1, 0, P64, 0); /* WriteNbiDma */
75 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
76 default:
77 return -EINVAL;
78 }
79 }
80
nfp6000_nbi_stats(u32 cpp_id)81 static int nfp6000_nbi_stats(u32 cpp_id)
82 {
83 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
84 AT(0, 0, 0, P32); /* ReadNbiStats */
85 AT(1, 0, P32, 0); /* WriteNbiStats */
86 AT(NFP_CPP_ACTION_RW, 0, P32, P32);
87 default:
88 return -EINVAL;
89 }
90 }
91
nfp6000_nbi_tm(u32 cpp_id)92 static int nfp6000_nbi_tm(u32 cpp_id)
93 {
94 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
95 AT(0, 0, 0, P64); /* ReadNbiTM */
96 AT(1, 0, P64, 0); /* WriteNbiTM */
97 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
98 default:
99 return -EINVAL;
100 }
101 }
102
nfp6000_nbi_ppc(u32 cpp_id)103 static int nfp6000_nbi_ppc(u32 cpp_id)
104 {
105 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
106 AT(0, 0, 0, P64); /* ReadNbiPreclassifier */
107 AT(1, 0, P64, 0); /* WriteNbiPreclassifier */
108 AT(NFP_CPP_ACTION_RW, 0, P64, P64);
109 default:
110 return -EINVAL;
111 }
112 }
113
nfp6000_nbi(u32 cpp_id,u64 address)114 static int nfp6000_nbi(u32 cpp_id, u64 address)
115 {
116 u64 rel_addr = address & 0x3fFFFF;
117
118 if (rel_addr < (1 << 20))
119 return nfp6000_nbi_dma(cpp_id);
120 if (rel_addr < (2 << 20))
121 return nfp6000_nbi_stats(cpp_id);
122 if (rel_addr < (3 << 20))
123 return nfp6000_nbi_tm(cpp_id);
124 return nfp6000_nbi_ppc(cpp_id);
125 }
126
127 /* This structure ONLY includes items that can be done with a read or write of
128 * 32-bit or 64-bit words. All others are not listed.
129 */
nfp6000_mu_common(u32 cpp_id)130 static int nfp6000_mu_common(u32 cpp_id)
131 {
132 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
133 AT(NFP_CPP_ACTION_RW, 0, P64, P64); /* read_be/write_be */
134 AT(NFP_CPP_ACTION_RW, 1, P64, P64); /* read_le/write_le */
135 AT(NFP_CPP_ACTION_RW, 2, P64, P64); /* read_swap_be/write_swap_be */
136 AT(NFP_CPP_ACTION_RW, 3, P64, P64); /* read_swap_le/write_swap_le */
137 AT(0, 0, 0, P64); /* read_be */
138 AT(0, 1, 0, P64); /* read_le */
139 AT(0, 2, 0, P64); /* read_swap_be */
140 AT(0, 3, 0, P64); /* read_swap_le */
141 AT(1, 0, P64, 0); /* write_be */
142 AT(1, 1, P64, 0); /* write_le */
143 AT(1, 2, P64, 0); /* write_swap_be */
144 AT(1, 3, P64, 0); /* write_swap_le */
145 AT(3, 0, 0, P32); /* atomic_read */
146 AT(3, 2, P32, 0); /* mask_compare_write */
147 AT(4, 0, P32, 0); /* atomic_write */
148 AT(4, 2, 0, 0); /* atomic_write_imm */
149 AT(4, 3, 0, P32); /* swap_imm */
150 AT(5, 0, P32, 0); /* set */
151 AT(5, 3, 0, P32); /* test_set_imm */
152 AT(6, 0, P32, 0); /* clr */
153 AT(6, 3, 0, P32); /* test_clr_imm */
154 AT(7, 0, P32, 0); /* add */
155 AT(7, 3, 0, P32); /* test_add_imm */
156 AT(8, 0, P32, 0); /* addsat */
157 AT(8, 3, 0, P32); /* test_subsat_imm */
158 AT(9, 0, P32, 0); /* sub */
159 AT(9, 3, 0, P32); /* test_sub_imm */
160 AT(10, 0, P32, 0); /* subsat */
161 AT(10, 3, 0, P32); /* test_subsat_imm */
162 AT(13, 0, 0, P32); /* microq128_get */
163 AT(13, 1, 0, P32); /* microq128_pop */
164 AT(13, 2, P32, 0); /* microq128_put */
165 AT(15, 0, P32, 0); /* xor */
166 AT(15, 3, 0, P32); /* test_xor_imm */
167 AT(28, 0, 0, P32); /* read32_be */
168 AT(28, 1, 0, P32); /* read32_le */
169 AT(28, 2, 0, P32); /* read32_swap_be */
170 AT(28, 3, 0, P32); /* read32_swap_le */
171 AT(31, 0, P32, 0); /* write32_be */
172 AT(31, 1, P32, 0); /* write32_le */
173 AT(31, 2, P32, 0); /* write32_swap_be */
174 AT(31, 3, P32, 0); /* write32_swap_le */
175 default:
176 return -EINVAL;
177 }
178 }
179
nfp6000_mu_ctm(u32 cpp_id)180 static int nfp6000_mu_ctm(u32 cpp_id)
181 {
182 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
183 AT(16, 1, 0, P32); /* packet_read_packet_status */
184 AT(17, 1, 0, P32); /* packet_credit_get */
185 AT(17, 3, 0, P64); /* packet_add_thread */
186 AT(18, 2, 0, P64); /* packet_free_and_return_pointer */
187 AT(18, 3, 0, P64); /* packet_return_pointer */
188 AT(21, 0, 0, P64); /* pe_dma_to_memory_indirect */
189 AT(21, 1, 0, P64); /* pe_dma_to_memory_indirect_swap */
190 AT(21, 2, 0, P64); /* pe_dma_to_memory_indirect_free */
191 AT(21, 3, 0, P64); /* pe_dma_to_memory_indirect_free_swap */
192 default:
193 return nfp6000_mu_common(cpp_id);
194 }
195 }
196
nfp6000_mu_emu(u32 cpp_id)197 static int nfp6000_mu_emu(u32 cpp_id)
198 {
199 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
200 AT(18, 0, 0, P32); /* read_queue */
201 AT(18, 1, 0, P32); /* read_queue_ring */
202 AT(18, 2, P32, 0); /* write_queue */
203 AT(18, 3, P32, 0); /* write_queue_ring */
204 AT(20, 2, P32, 0); /* journal */
205 AT(21, 0, 0, P32); /* get */
206 AT(21, 1, 0, P32); /* get_eop */
207 AT(21, 2, 0, P32); /* get_freely */
208 AT(22, 0, 0, P32); /* pop */
209 AT(22, 1, 0, P32); /* pop_eop */
210 AT(22, 2, 0, P32); /* pop_freely */
211 default:
212 return nfp6000_mu_common(cpp_id);
213 }
214 }
215
nfp6000_mu_imu(u32 cpp_id)216 static int nfp6000_mu_imu(u32 cpp_id)
217 {
218 return nfp6000_mu_common(cpp_id);
219 }
220
nfp6000_mu(u32 cpp_id,u64 address)221 static int nfp6000_mu(u32 cpp_id, u64 address)
222 {
223 int pp;
224
225 if (address < 0x2000000000ULL)
226 pp = nfp6000_mu_ctm(cpp_id);
227 else if (address < 0x8000000000ULL)
228 pp = nfp6000_mu_emu(cpp_id);
229 else if (address < 0x9800000000ULL)
230 pp = nfp6000_mu_ctm(cpp_id);
231 else if (address < 0x9C00000000ULL)
232 pp = nfp6000_mu_emu(cpp_id);
233 else if (address < 0xA000000000ULL)
234 pp = nfp6000_mu_imu(cpp_id);
235 else
236 pp = nfp6000_mu_ctm(cpp_id);
237
238 return pp;
239 }
240
nfp6000_ila(u32 cpp_id)241 static int nfp6000_ila(u32 cpp_id)
242 {
243 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
244 AT(0, 1, 0, P32); /* read_check_error */
245 AT(2, 0, 0, P32); /* read_int */
246 AT(3, 0, P32, 0); /* write_int */
247 default:
248 return target_rw(cpp_id, P32, 48, 4);
249 }
250 }
251
nfp6000_pci(u32 cpp_id)252 static int nfp6000_pci(u32 cpp_id)
253 {
254 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
255 AT(2, 0, 0, P32);
256 AT(3, 0, P32, 0);
257 default:
258 return target_rw(cpp_id, P32, 4, 4);
259 }
260 }
261
nfp6000_crypto(u32 cpp_id)262 static int nfp6000_crypto(u32 cpp_id)
263 {
264 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
265 AT(2, 0, P64, 0);
266 default:
267 return target_rw(cpp_id, P64, 12, 4);
268 }
269 }
270
nfp6000_cap_xpb(u32 cpp_id)271 static int nfp6000_cap_xpb(u32 cpp_id)
272 {
273 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
274 AT(0, 1, 0, P32); /* RingGet */
275 AT(0, 2, P32, 0); /* Interthread Signal */
276 AT(1, 1, P32, 0); /* RingPut */
277 AT(1, 2, P32, 0); /* CTNNWr */
278 AT(2, 0, 0, P32); /* ReflectRd, signal none */
279 AT(2, 1, 0, P32); /* ReflectRd, signal self */
280 AT(2, 2, 0, P32); /* ReflectRd, signal remote */
281 AT(2, 3, 0, P32); /* ReflectRd, signal both */
282 AT(3, 0, P32, 0); /* ReflectWr, signal none */
283 AT(3, 1, P32, 0); /* ReflectWr, signal self */
284 AT(3, 2, P32, 0); /* ReflectWr, signal remote */
285 AT(3, 3, P32, 0); /* ReflectWr, signal both */
286 AT(NFP_CPP_ACTION_RW, 1, P32, P32);
287 default:
288 return target_rw(cpp_id, P32, 1, 63);
289 }
290 }
291
nfp6000_cls(u32 cpp_id)292 static int nfp6000_cls(u32 cpp_id)
293 {
294 switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
295 AT(0, 3, P32, 0); /* xor */
296 AT(2, 0, P32, 0); /* set */
297 AT(2, 1, P32, 0); /* clr */
298 AT(4, 0, P32, 0); /* add */
299 AT(4, 1, P32, 0); /* add64 */
300 AT(6, 0, P32, 0); /* sub */
301 AT(6, 1, P32, 0); /* sub64 */
302 AT(6, 2, P32, 0); /* subsat */
303 AT(8, 2, P32, 0); /* hash_mask */
304 AT(8, 3, P32, 0); /* hash_clear */
305 AT(9, 0, 0, P32); /* ring_get */
306 AT(9, 1, 0, P32); /* ring_pop */
307 AT(9, 2, 0, P32); /* ring_get_freely */
308 AT(9, 3, 0, P32); /* ring_pop_freely */
309 AT(10, 0, P32, 0); /* ring_put */
310 AT(10, 2, P32, 0); /* ring_journal */
311 AT(14, 0, P32, 0); /* reflect_write_sig_local */
312 AT(15, 1, 0, P32); /* reflect_read_sig_local */
313 AT(17, 2, P32, 0); /* statisic */
314 AT(24, 0, 0, P32); /* ring_read */
315 AT(24, 1, P32, 0); /* ring_write */
316 AT(25, 0, 0, P32); /* ring_workq_add_thread */
317 AT(25, 1, P32, 0); /* ring_workq_add_work */
318 default:
319 return target_rw(cpp_id, P32, 0, 64);
320 }
321 }
322
nfp_target_pushpull(u32 cpp_id,u64 address)323 int nfp_target_pushpull(u32 cpp_id, u64 address)
324 {
325 switch (NFP_CPP_ID_TARGET_of(cpp_id)) {
326 case NFP_CPP_TARGET_NBI:
327 return nfp6000_nbi(cpp_id, address);
328 case NFP_CPP_TARGET_QDR:
329 return target_rw(cpp_id, P32, 24, 4);
330 case NFP_CPP_TARGET_ILA:
331 return nfp6000_ila(cpp_id);
332 case NFP_CPP_TARGET_MU:
333 return nfp6000_mu(cpp_id, address);
334 case NFP_CPP_TARGET_PCIE:
335 return nfp6000_pci(cpp_id);
336 case NFP_CPP_TARGET_ARM:
337 if (address < 0x10000)
338 return target_rw(cpp_id, P64, 1, 1);
339 else
340 return target_rw(cpp_id, P32, 1, 1);
341 case NFP_CPP_TARGET_CRYPTO:
342 return nfp6000_crypto(cpp_id);
343 case NFP_CPP_TARGET_CT_XPB:
344 return nfp6000_cap_xpb(cpp_id);
345 case NFP_CPP_TARGET_CLS:
346 return nfp6000_cls(cpp_id);
347 case 0:
348 return target_rw(cpp_id, P32, 4, 4);
349 default:
350 return -EINVAL;
351 }
352 }
353
354 #undef AT
355 #undef P32
356 #undef P64
357
358 /* All magic NFP-6xxx IMB 'mode' numbers here are from:
359 * Databook (1 August 2013)
360 * - System Overview and Connectivity
361 * -- Internal Connectivity
362 * --- Distributed Switch Fabric - Command Push/Pull (DSF-CPP) Bus
363 * ---- CPP addressing
364 * ----- Table 3.6. CPP Address Translation Mode Commands
365 */
366
367 #define _NIC_NFP6000_MU_LOCALITY_DIRECT 2
368
nfp_decode_basic(u64 addr,int * dest_island,int cpp_tgt,int mode,bool addr40,int isld1,int isld0)369 static int nfp_decode_basic(u64 addr, int *dest_island, int cpp_tgt,
370 int mode, bool addr40, int isld1, int isld0)
371 {
372 int iid_lsb, idx_lsb;
373
374 /* This function doesn't handle MU or CTXBP */
375 if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
376 return -EINVAL;
377
378 switch (mode) {
379 case 0:
380 /* For VQDR, in this mode for 32-bit addressing
381 * it would be islands 0, 16, 32 and 48 depending on channel
382 * and upper address bits.
383 * Since those are not all valid islands, most decode
384 * cases would result in bad island IDs, but we do them
385 * anyway since this is decoding an address that is already
386 * assumed to be used as-is to get to sram.
387 */
388 iid_lsb = addr40 ? 34 : 26;
389 *dest_island = (addr >> iid_lsb) & 0x3F;
390 return 0;
391 case 1:
392 /* For VQDR 32-bit, this would decode as:
393 * Channel 0: island#0
394 * Channel 1: island#0
395 * Channel 2: island#1
396 * Channel 3: island#1
397 * That would be valid as long as both islands
398 * have VQDR. Let's allow this.
399 */
400 idx_lsb = addr40 ? 39 : 31;
401 if (addr & BIT_ULL(idx_lsb))
402 *dest_island = isld1;
403 else
404 *dest_island = isld0;
405
406 return 0;
407 case 2:
408 /* For VQDR 32-bit:
409 * Channel 0: (island#0 | 0)
410 * Channel 1: (island#0 | 1)
411 * Channel 2: (island#1 | 0)
412 * Channel 3: (island#1 | 1)
413 *
414 * Make sure we compare against isldN values
415 * by clearing the LSB.
416 * This is what the silicon does.
417 */
418 isld0 &= ~1;
419 isld1 &= ~1;
420
421 idx_lsb = addr40 ? 39 : 31;
422 iid_lsb = idx_lsb - 1;
423
424 if (addr & BIT_ULL(idx_lsb))
425 *dest_island = isld1 | (int)((addr >> iid_lsb) & 1);
426 else
427 *dest_island = isld0 | (int)((addr >> iid_lsb) & 1);
428
429 return 0;
430 case 3:
431 /* In this mode the data address starts to affect the island ID
432 * so rather not allow it. In some really specific case
433 * one could use this to send the upper half of the
434 * VQDR channel to another MU, but this is getting very
435 * specific.
436 * However, as above for mode 0, this is the decoder
437 * and the caller should validate the resulting IID.
438 * This blindly does what the silicon would do.
439 */
440 isld0 &= ~3;
441 isld1 &= ~3;
442
443 idx_lsb = addr40 ? 39 : 31;
444 iid_lsb = idx_lsb - 2;
445
446 if (addr & BIT_ULL(idx_lsb))
447 *dest_island = isld1 | (int)((addr >> iid_lsb) & 3);
448 else
449 *dest_island = isld0 | (int)((addr >> iid_lsb) & 3);
450
451 return 0;
452 default:
453 return -EINVAL;
454 }
455 }
456
nfp_encode_basic_qdr(u64 addr,int dest_island,int cpp_tgt,int mode,bool addr40,int isld1,int isld0)457 static int nfp_encode_basic_qdr(u64 addr, int dest_island, int cpp_tgt,
458 int mode, bool addr40, int isld1, int isld0)
459 {
460 int v, ret;
461
462 /* Full Island ID and channel bits overlap? */
463 ret = nfp_decode_basic(addr, &v, cpp_tgt, mode, addr40, isld1, isld0);
464 if (ret)
465 return ret;
466
467 /* The current address won't go where expected? */
468 if (dest_island != -1 && dest_island != v)
469 return -EINVAL;
470
471 /* If dest_island was -1, we don't care where it goes. */
472 return 0;
473 }
474
475 /* Try each option, take first one that fits.
476 * Not sure if we would want to do some smarter
477 * searching and prefer 0 or non-0 island IDs.
478 */
nfp_encode_basic_search(u64 * addr,int dest_island,int * isld,int iid_lsb,int idx_lsb,int v_max)479 static int nfp_encode_basic_search(u64 *addr, int dest_island, int *isld,
480 int iid_lsb, int idx_lsb, int v_max)
481 {
482 int i, v;
483
484 for (i = 0; i < 2; i++)
485 for (v = 0; v < v_max; v++) {
486 if (dest_island != (isld[i] | v))
487 continue;
488
489 *addr &= ~GENMASK_ULL(idx_lsb, iid_lsb);
490 *addr |= ((u64)i << idx_lsb);
491 *addr |= ((u64)v << iid_lsb);
492 return 0;
493 }
494
495 return -ENODEV;
496 }
497
498 /* For VQDR, we may not modify the Channel bits, which might overlap
499 * with the Index bit. When it does, we need to ensure that isld0 == isld1.
500 */
nfp_encode_basic(u64 * addr,int dest_island,int cpp_tgt,int mode,bool addr40,int isld1,int isld0)501 static int nfp_encode_basic(u64 *addr, int dest_island, int cpp_tgt,
502 int mode, bool addr40, int isld1, int isld0)
503 {
504 int iid_lsb, idx_lsb;
505 int isld[2];
506 u64 v64;
507
508 isld[0] = isld0;
509 isld[1] = isld1;
510
511 /* This function doesn't handle MU or CTXBP */
512 if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
513 return -EINVAL;
514
515 switch (mode) {
516 case 0:
517 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
518 /* In this specific mode we'd rather not modify
519 * the address but we can verify if the existing
520 * contents will point to a valid island.
521 */
522 return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
523 mode, addr40, isld1, isld0);
524
525 iid_lsb = addr40 ? 34 : 26;
526 /* <39:34> or <31:26> */
527 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
528 *addr &= ~v64;
529 *addr |= ((u64)dest_island << iid_lsb) & v64;
530 return 0;
531 case 1:
532 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
533 return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
534 mode, addr40, isld1, isld0);
535
536 idx_lsb = addr40 ? 39 : 31;
537 if (dest_island == isld0) {
538 /* Only need to clear the Index bit */
539 *addr &= ~BIT_ULL(idx_lsb);
540 return 0;
541 }
542
543 if (dest_island == isld1) {
544 /* Only need to set the Index bit */
545 *addr |= BIT_ULL(idx_lsb);
546 return 0;
547 }
548
549 return -ENODEV;
550 case 2:
551 /* iid<0> = addr<30> = channel<0>
552 * channel<1> = addr<31> = Index
553 */
554 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
555 /* Special case where we allow channel bits to
556 * be set before hand and with them select an island.
557 * So we need to confirm that it's at least plausible.
558 */
559 return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
560 mode, addr40, isld1, isld0);
561
562 /* Make sure we compare against isldN values
563 * by clearing the LSB.
564 * This is what the silicon does.
565 */
566 isld[0] &= ~1;
567 isld[1] &= ~1;
568
569 idx_lsb = addr40 ? 39 : 31;
570 iid_lsb = idx_lsb - 1;
571
572 return nfp_encode_basic_search(addr, dest_island, isld,
573 iid_lsb, idx_lsb, 2);
574 case 3:
575 if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
576 /* iid<0> = addr<29> = data
577 * iid<1> = addr<30> = channel<0>
578 * channel<1> = addr<31> = Index
579 */
580 return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
581 mode, addr40, isld1, isld0);
582
583 isld[0] &= ~3;
584 isld[1] &= ~3;
585
586 idx_lsb = addr40 ? 39 : 31;
587 iid_lsb = idx_lsb - 2;
588
589 return nfp_encode_basic_search(addr, dest_island, isld,
590 iid_lsb, idx_lsb, 4);
591 default:
592 return -EINVAL;
593 }
594 }
595
nfp_encode_mu(u64 * addr,int dest_island,int mode,bool addr40,int isld1,int isld0)596 static int nfp_encode_mu(u64 *addr, int dest_island, int mode,
597 bool addr40, int isld1, int isld0)
598 {
599 int iid_lsb, idx_lsb, locality_lsb;
600 int isld[2];
601 u64 v64;
602 int da;
603
604 isld[0] = isld0;
605 isld[1] = isld1;
606 locality_lsb = nfp_cppat_mu_locality_lsb(mode, addr40);
607
608 if (((*addr >> locality_lsb) & 3) == _NIC_NFP6000_MU_LOCALITY_DIRECT)
609 da = 1;
610 else
611 da = 0;
612
613 switch (mode) {
614 case 0:
615 iid_lsb = addr40 ? 32 : 24;
616 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
617 *addr &= ~v64;
618 *addr |= (((u64)dest_island) << iid_lsb) & v64;
619 return 0;
620 case 1:
621 if (da) {
622 iid_lsb = addr40 ? 32 : 24;
623 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
624 *addr &= ~v64;
625 *addr |= (((u64)dest_island) << iid_lsb) & v64;
626 return 0;
627 }
628
629 idx_lsb = addr40 ? 37 : 29;
630 if (dest_island == isld0) {
631 *addr &= ~BIT_ULL(idx_lsb);
632 return 0;
633 }
634
635 if (dest_island == isld1) {
636 *addr |= BIT_ULL(idx_lsb);
637 return 0;
638 }
639
640 return -ENODEV;
641 case 2:
642 if (da) {
643 iid_lsb = addr40 ? 32 : 24;
644 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
645 *addr &= ~v64;
646 *addr |= (((u64)dest_island) << iid_lsb) & v64;
647 return 0;
648 }
649
650 /* Make sure we compare against isldN values
651 * by clearing the LSB.
652 * This is what the silicon does.
653 */
654 isld[0] &= ~1;
655 isld[1] &= ~1;
656
657 idx_lsb = addr40 ? 37 : 29;
658 iid_lsb = idx_lsb - 1;
659
660 return nfp_encode_basic_search(addr, dest_island, isld,
661 iid_lsb, idx_lsb, 2);
662 case 3:
663 /* Only the EMU will use 40 bit addressing. Silently
664 * set the direct locality bit for everyone else.
665 * The SDK toolchain uses dest_island <= 0 to test
666 * for atypical address encodings to support access
667 * to local-island CTM with a 32-but address (high-locality
668 * is effewctively ignored and just used for
669 * routing to island #0).
670 */
671 if (dest_island > 0 && (dest_island < 24 || dest_island > 26)) {
672 *addr |= ((u64)_NIC_NFP6000_MU_LOCALITY_DIRECT)
673 << locality_lsb;
674 da = 1;
675 }
676
677 if (da) {
678 iid_lsb = addr40 ? 32 : 24;
679 v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
680 *addr &= ~v64;
681 *addr |= (((u64)dest_island) << iid_lsb) & v64;
682 return 0;
683 }
684
685 isld[0] &= ~3;
686 isld[1] &= ~3;
687
688 idx_lsb = addr40 ? 37 : 29;
689 iid_lsb = idx_lsb - 2;
690
691 return nfp_encode_basic_search(addr, dest_island, isld,
692 iid_lsb, idx_lsb, 4);
693 default:
694 return -EINVAL;
695 }
696 }
697
nfp_cppat_addr_encode(u64 * addr,int dest_island,int cpp_tgt,int mode,bool addr40,int isld1,int isld0)698 static int nfp_cppat_addr_encode(u64 *addr, int dest_island, int cpp_tgt,
699 int mode, bool addr40, int isld1, int isld0)
700 {
701 switch (cpp_tgt) {
702 case NFP_CPP_TARGET_NBI:
703 case NFP_CPP_TARGET_QDR:
704 case NFP_CPP_TARGET_ILA:
705 case NFP_CPP_TARGET_PCIE:
706 case NFP_CPP_TARGET_ARM:
707 case NFP_CPP_TARGET_CRYPTO:
708 case NFP_CPP_TARGET_CLS:
709 return nfp_encode_basic(addr, dest_island, cpp_tgt, mode,
710 addr40, isld1, isld0);
711
712 case NFP_CPP_TARGET_MU:
713 return nfp_encode_mu(addr, dest_island, mode,
714 addr40, isld1, isld0);
715
716 case NFP_CPP_TARGET_CT_XPB:
717 if (mode != 1 || addr40)
718 return -EINVAL;
719 *addr &= ~GENMASK_ULL(29, 24);
720 *addr |= ((u64)dest_island << 24) & GENMASK_ULL(29, 24);
721 return 0;
722 default:
723 return -EINVAL;
724 }
725 }
726
nfp_target_cpp(u32 cpp_island_id,u64 cpp_island_address,u32 * cpp_target_id,u64 * cpp_target_address,const u32 * imb_table)727 int nfp_target_cpp(u32 cpp_island_id, u64 cpp_island_address,
728 u32 *cpp_target_id, u64 *cpp_target_address,
729 const u32 *imb_table)
730 {
731 const int island = NFP_CPP_ID_ISLAND_of(cpp_island_id);
732 const int target = NFP_CPP_ID_TARGET_of(cpp_island_id);
733 u32 imb;
734 int err;
735
736 if (target < 0 || target >= 16)
737 return -EINVAL;
738
739 if (island == 0) {
740 /* Already translated */
741 *cpp_target_id = cpp_island_id;
742 *cpp_target_address = cpp_island_address;
743 return 0;
744 }
745
746 /* CPP + Island only allowed on systems with IMB tables */
747 if (!imb_table)
748 return -EINVAL;
749
750 imb = imb_table[target];
751
752 *cpp_target_address = cpp_island_address;
753 err = nfp_cppat_addr_encode(cpp_target_address, island, target,
754 ((imb >> 13) & 7), ((imb >> 12) & 1),
755 ((imb >> 6) & 0x3f), ((imb >> 0) & 0x3f));
756 if (err)
757 return err;
758
759 *cpp_target_id = NFP_CPP_ID(target,
760 NFP_CPP_ID_ACTION_of(cpp_island_id),
761 NFP_CPP_ID_TOKEN_of(cpp_island_id));
762
763 return 0;
764 }
765