cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nfp_target.c (19637B)


      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, 48, 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, 4, 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, 12, 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, 1, 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, 0, 64);
    294	}
    295}
    296
    297int 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/* 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, &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, 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, 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, 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, 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, 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
    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, 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, 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(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		/* 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(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}