Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
0002 /* Copyright (C) 2015-2018 Netronome Systems, Inc. */
0003 
0004 /*
0005  * nfp_target.c
0006  * CPP Access Width Decoder
0007  * Authors: Jakub Kicinski <jakub.kicinski@netronome.com>
0008  *          Jason McMullan <jason.mcmullan@netronome.com>
0009  *          Francois H. Theron <francois.theron@netronome.com>
0010  */
0011 
0012 #define pr_fmt(fmt)       "NFP target: " fmt
0013 
0014 #include <linux/bitops.h>
0015 #include <linux/kernel.h>
0016 #include <linux/printk.h>
0017 
0018 #include "nfp_cpp.h"
0019 
0020 #include "nfp6000/nfp6000.h"
0021 
0022 #define P32 1
0023 #define P64 2
0024 
0025 /* This structure ONLY includes items that can be done with a read or write of
0026  * 32-bit or 64-bit words. All others are not listed.
0027  */
0028 
0029 #define AT(_action, _token, _pull, _push)               \
0030     case NFP_CPP_ID(0, (_action), (_token)):            \
0031         return PUSHPULL((_pull), (_push))
0032 
0033 static int target_rw(u32 cpp_id, int pp, int start, int len)
0034 {
0035     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0036     AT(0, 0,  0, pp);
0037     AT(1, 0, pp,  0);
0038     AT(NFP_CPP_ACTION_RW, 0, pp, pp);
0039     default:
0040         return -EINVAL;
0041     }
0042 }
0043 
0044 static int nfp6000_nbi_dma(u32 cpp_id)
0045 {
0046     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0047     AT(0, 0,   0, P64); /* ReadNbiDma */
0048     AT(1, 0,   P64, 0); /* WriteNbiDma */
0049     AT(NFP_CPP_ACTION_RW, 0, P64, P64);
0050     default:
0051         return -EINVAL;
0052     }
0053 }
0054 
0055 static int nfp6000_nbi_stats(u32 cpp_id)
0056 {
0057     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0058     AT(0, 0,   0, P32); /* ReadNbiStats */
0059     AT(1, 0,   P32, 0); /* WriteNbiStats */
0060     AT(NFP_CPP_ACTION_RW, 0, P32, P32);
0061     default:
0062         return -EINVAL;
0063     }
0064 }
0065 
0066 static int nfp6000_nbi_tm(u32 cpp_id)
0067 {
0068     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0069     AT(0, 0,   0, P64); /* ReadNbiTM */
0070     AT(1, 0,   P64, 0); /* WriteNbiTM */
0071     AT(NFP_CPP_ACTION_RW, 0, P64, P64);
0072     default:
0073         return -EINVAL;
0074     }
0075 }
0076 
0077 static int nfp6000_nbi_ppc(u32 cpp_id)
0078 {
0079     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0080     AT(0, 0,   0, P64); /* ReadNbiPreclassifier */
0081     AT(1, 0,   P64, 0); /* WriteNbiPreclassifier */
0082     AT(NFP_CPP_ACTION_RW, 0, P64, P64);
0083     default:
0084         return -EINVAL;
0085     }
0086 }
0087 
0088 static int nfp6000_nbi(u32 cpp_id, u64 address)
0089 {
0090     u64 rel_addr = address & 0x3fFFFF;
0091 
0092     if (rel_addr < (1 << 20))
0093         return nfp6000_nbi_dma(cpp_id);
0094     if (rel_addr < (2 << 20))
0095         return nfp6000_nbi_stats(cpp_id);
0096     if (rel_addr < (3 << 20))
0097         return nfp6000_nbi_tm(cpp_id);
0098     return nfp6000_nbi_ppc(cpp_id);
0099 }
0100 
0101 /* This structure ONLY includes items that can be done with a read or write of
0102  * 32-bit or 64-bit words. All others are not listed.
0103  */
0104 static int nfp6000_mu_common(u32 cpp_id)
0105 {
0106     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0107     AT(NFP_CPP_ACTION_RW, 0, P64, P64); /* read_be/write_be */
0108     AT(NFP_CPP_ACTION_RW, 1, P64, P64); /* read_le/write_le */
0109     AT(NFP_CPP_ACTION_RW, 2, P64, P64); /* read_swap_be/write_swap_be */
0110     AT(NFP_CPP_ACTION_RW, 3, P64, P64); /* read_swap_le/write_swap_le */
0111     AT(0, 0,   0, P64); /* read_be */
0112     AT(0, 1,   0, P64); /* read_le */
0113     AT(0, 2,   0, P64); /* read_swap_be */
0114     AT(0, 3,   0, P64); /* read_swap_le */
0115     AT(1, 0, P64,   0); /* write_be */
0116     AT(1, 1, P64,   0); /* write_le */
0117     AT(1, 2, P64,   0); /* write_swap_be */
0118     AT(1, 3, P64,   0); /* write_swap_le */
0119     AT(3, 0,   0, P32); /* atomic_read */
0120     AT(3, 2, P32,   0); /* mask_compare_write */
0121     AT(4, 0, P32,   0); /* atomic_write */
0122     AT(4, 2,   0,   0); /* atomic_write_imm */
0123     AT(4, 3,   0, P32); /* swap_imm */
0124     AT(5, 0, P32,   0); /* set */
0125     AT(5, 3,   0, P32); /* test_set_imm */
0126     AT(6, 0, P32,   0); /* clr */
0127     AT(6, 3,   0, P32); /* test_clr_imm */
0128     AT(7, 0, P32,   0); /* add */
0129     AT(7, 3,   0, P32); /* test_add_imm */
0130     AT(8, 0, P32,   0); /* addsat */
0131     AT(8, 3,   0, P32); /* test_subsat_imm */
0132     AT(9, 0, P32,   0); /* sub */
0133     AT(9, 3,   0, P32); /* test_sub_imm */
0134     AT(10, 0, P32,   0);    /* subsat */
0135     AT(10, 3,   0, P32);    /* test_subsat_imm */
0136     AT(13, 0,   0, P32);    /* microq128_get */
0137     AT(13, 1,   0, P32);    /* microq128_pop */
0138     AT(13, 2, P32,   0);    /* microq128_put */
0139     AT(15, 0, P32,   0);    /* xor */
0140     AT(15, 3,   0, P32);    /* test_xor_imm */
0141     AT(28, 0,   0, P32);    /* read32_be */
0142     AT(28, 1,   0, P32);    /* read32_le */
0143     AT(28, 2,   0, P32);    /* read32_swap_be */
0144     AT(28, 3,   0, P32);    /* read32_swap_le */
0145     AT(31, 0, P32,   0);    /* write32_be */
0146     AT(31, 1, P32,   0);    /* write32_le */
0147     AT(31, 2, P32,   0);    /* write32_swap_be */
0148     AT(31, 3, P32,   0);    /* write32_swap_le */
0149     default:
0150         return -EINVAL;
0151     }
0152 }
0153 
0154 static int nfp6000_mu_ctm(u32 cpp_id)
0155 {
0156     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0157     AT(16, 1,   0, P32);    /* packet_read_packet_status */
0158     AT(17, 1,   0, P32);    /* packet_credit_get */
0159     AT(17, 3,   0, P64);    /* packet_add_thread */
0160     AT(18, 2,   0, P64);    /* packet_free_and_return_pointer */
0161     AT(18, 3,   0, P64);    /* packet_return_pointer */
0162     AT(21, 0,   0, P64);    /* pe_dma_to_memory_indirect */
0163     AT(21, 1,   0, P64);    /* pe_dma_to_memory_indirect_swap */
0164     AT(21, 2,   0, P64);    /* pe_dma_to_memory_indirect_free */
0165     AT(21, 3,   0, P64);    /* pe_dma_to_memory_indirect_free_swap */
0166     default:
0167         return nfp6000_mu_common(cpp_id);
0168     }
0169 }
0170 
0171 static int nfp6000_mu_emu(u32 cpp_id)
0172 {
0173     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0174     AT(18, 0,   0, P32);    /* read_queue */
0175     AT(18, 1,   0, P32);    /* read_queue_ring */
0176     AT(18, 2, P32,   0);    /* write_queue */
0177     AT(18, 3, P32,   0);    /* write_queue_ring */
0178     AT(20, 2, P32,   0);    /* journal */
0179     AT(21, 0,   0, P32);    /* get */
0180     AT(21, 1,   0, P32);    /* get_eop */
0181     AT(21, 2,   0, P32);    /* get_freely */
0182     AT(22, 0,   0, P32);    /* pop */
0183     AT(22, 1,   0, P32);    /* pop_eop */
0184     AT(22, 2,   0, P32);    /* pop_freely */
0185     default:
0186         return nfp6000_mu_common(cpp_id);
0187     }
0188 }
0189 
0190 static int nfp6000_mu_imu(u32 cpp_id)
0191 {
0192     return nfp6000_mu_common(cpp_id);
0193 }
0194 
0195 static int nfp6000_mu(u32 cpp_id, u64 address)
0196 {
0197     int pp;
0198 
0199     if (address < 0x2000000000ULL)
0200         pp = nfp6000_mu_ctm(cpp_id);
0201     else if (address < 0x8000000000ULL)
0202         pp = nfp6000_mu_emu(cpp_id);
0203     else if (address < 0x9800000000ULL)
0204         pp = nfp6000_mu_ctm(cpp_id);
0205     else if (address < 0x9C00000000ULL)
0206         pp = nfp6000_mu_emu(cpp_id);
0207     else if (address < 0xA000000000ULL)
0208         pp = nfp6000_mu_imu(cpp_id);
0209     else
0210         pp = nfp6000_mu_ctm(cpp_id);
0211 
0212     return pp;
0213 }
0214 
0215 static int nfp6000_ila(u32 cpp_id)
0216 {
0217     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0218     AT(0, 1,   0, P32); /* read_check_error */
0219     AT(2, 0,   0, P32); /* read_int */
0220     AT(3, 0, P32,   0); /* write_int */
0221     default:
0222         return target_rw(cpp_id, P32, 48, 4);
0223     }
0224 }
0225 
0226 static int nfp6000_pci(u32 cpp_id)
0227 {
0228     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0229     AT(2, 0,   0, P32);
0230     AT(3, 0, P32,   0);
0231     default:
0232         return target_rw(cpp_id, P32, 4, 4);
0233     }
0234 }
0235 
0236 static int nfp6000_crypto(u32 cpp_id)
0237 {
0238     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0239     AT(2, 0, P64,   0);
0240     default:
0241         return target_rw(cpp_id, P64, 12, 4);
0242     }
0243 }
0244 
0245 static int nfp6000_cap_xpb(u32 cpp_id)
0246 {
0247     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0248     AT(0, 1,   0, P32); /* RingGet */
0249     AT(0, 2, P32,   0); /* Interthread Signal */
0250     AT(1, 1, P32,   0); /* RingPut */
0251     AT(1, 2, P32,   0); /* CTNNWr */
0252     AT(2, 0,   0, P32); /* ReflectRd, signal none */
0253     AT(2, 1,   0, P32); /* ReflectRd, signal self */
0254     AT(2, 2,   0, P32); /* ReflectRd, signal remote */
0255     AT(2, 3,   0, P32); /* ReflectRd, signal both */
0256     AT(3, 0, P32,   0); /* ReflectWr, signal none */
0257     AT(3, 1, P32,   0); /* ReflectWr, signal self */
0258     AT(3, 2, P32,   0); /* ReflectWr, signal remote */
0259     AT(3, 3, P32,   0); /* ReflectWr, signal both */
0260     AT(NFP_CPP_ACTION_RW, 1, P32, P32);
0261     default:
0262         return target_rw(cpp_id, P32, 1, 63);
0263     }
0264 }
0265 
0266 static int nfp6000_cls(u32 cpp_id)
0267 {
0268     switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
0269     AT(0, 3, P32,  0); /* xor */
0270     AT(2, 0, P32,  0); /* set */
0271     AT(2, 1, P32,  0); /* clr */
0272     AT(4, 0, P32,  0); /* add */
0273     AT(4, 1, P32,  0); /* add64 */
0274     AT(6, 0, P32,  0); /* sub */
0275     AT(6, 1, P32,  0); /* sub64 */
0276     AT(6, 2, P32,  0); /* subsat */
0277     AT(8, 2, P32,  0); /* hash_mask */
0278     AT(8, 3, P32,  0); /* hash_clear */
0279     AT(9, 0,  0, P32); /* ring_get */
0280     AT(9, 1,  0, P32); /* ring_pop */
0281     AT(9, 2,  0, P32); /* ring_get_freely */
0282     AT(9, 3,  0, P32); /* ring_pop_freely */
0283     AT(10, 0, P32,  0); /* ring_put */
0284     AT(10, 2, P32,  0); /* ring_journal */
0285     AT(14, 0,  P32, 0); /* reflect_write_sig_local */
0286     AT(15, 1,  0, P32); /* reflect_read_sig_local */
0287     AT(17, 2, P32,  0); /* statisic */
0288     AT(24, 0,  0, P32); /* ring_read */
0289     AT(24, 1, P32,  0); /* ring_write */
0290     AT(25, 0,  0, P32); /* ring_workq_add_thread */
0291     AT(25, 1, P32,  0); /* ring_workq_add_work */
0292     default:
0293         return target_rw(cpp_id, P32, 0, 64);
0294     }
0295 }
0296 
0297 int nfp_target_pushpull(u32 cpp_id, u64 address)
0298 {
0299     switch (NFP_CPP_ID_TARGET_of(cpp_id)) {
0300     case NFP_CPP_TARGET_NBI:
0301         return nfp6000_nbi(cpp_id, address);
0302     case NFP_CPP_TARGET_QDR:
0303         return target_rw(cpp_id, P32, 24, 4);
0304     case NFP_CPP_TARGET_ILA:
0305         return nfp6000_ila(cpp_id);
0306     case NFP_CPP_TARGET_MU:
0307         return nfp6000_mu(cpp_id, address);
0308     case NFP_CPP_TARGET_PCIE:
0309         return nfp6000_pci(cpp_id);
0310     case NFP_CPP_TARGET_ARM:
0311         if (address < 0x10000)
0312             return target_rw(cpp_id, P64, 1, 1);
0313         else
0314             return target_rw(cpp_id, P32, 1, 1);
0315     case NFP_CPP_TARGET_CRYPTO:
0316         return nfp6000_crypto(cpp_id);
0317     case NFP_CPP_TARGET_CT_XPB:
0318         return nfp6000_cap_xpb(cpp_id);
0319     case NFP_CPP_TARGET_CLS:
0320         return nfp6000_cls(cpp_id);
0321     case 0:
0322         return target_rw(cpp_id, P32, 4, 4);
0323     default:
0324         return -EINVAL;
0325     }
0326 }
0327 
0328 #undef AT
0329 #undef P32
0330 #undef P64
0331 
0332 /* All magic NFP-6xxx IMB 'mode' numbers here are from:
0333  * Databook (1 August 2013)
0334  * - System Overview and Connectivity
0335  * -- Internal Connectivity
0336  * --- Distributed Switch Fabric - Command Push/Pull (DSF-CPP) Bus
0337  * ---- CPP addressing
0338  * ----- Table 3.6. CPP Address Translation Mode Commands
0339  */
0340 
0341 #define _NIC_NFP6000_MU_LOCALITY_DIRECT     2
0342 
0343 static int nfp_decode_basic(u64 addr, int *dest_island, int cpp_tgt,
0344                 int mode, bool addr40, int isld1, int isld0)
0345 {
0346     int iid_lsb, idx_lsb;
0347 
0348     /* This function doesn't handle MU or CTXBP */
0349     if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
0350         return -EINVAL;
0351 
0352     switch (mode) {
0353     case 0:
0354         /* For VQDR, in this mode for 32-bit addressing
0355          * it would be islands 0, 16, 32 and 48 depending on channel
0356          * and upper address bits.
0357          * Since those are not all valid islands, most decode
0358          * cases would result in bad island IDs, but we do them
0359          * anyway since this is decoding an address that is already
0360          * assumed to be used as-is to get to sram.
0361          */
0362         iid_lsb = addr40 ? 34 : 26;
0363         *dest_island = (addr >> iid_lsb) & 0x3F;
0364         return 0;
0365     case 1:
0366         /* For VQDR 32-bit, this would decode as:
0367          * Channel 0: island#0
0368          * Channel 1: island#0
0369          * Channel 2: island#1
0370          * Channel 3: island#1
0371          * That would be valid as long as both islands
0372          * have VQDR. Let's allow this.
0373          */
0374         idx_lsb = addr40 ? 39 : 31;
0375         if (addr & BIT_ULL(idx_lsb))
0376             *dest_island = isld1;
0377         else
0378             *dest_island = isld0;
0379 
0380         return 0;
0381     case 2:
0382         /* For VQDR 32-bit:
0383          * Channel 0: (island#0 | 0)
0384          * Channel 1: (island#0 | 1)
0385          * Channel 2: (island#1 | 0)
0386          * Channel 3: (island#1 | 1)
0387          *
0388          * Make sure we compare against isldN values
0389          * by clearing the LSB.
0390          * This is what the silicon does.
0391          */
0392         isld0 &= ~1;
0393         isld1 &= ~1;
0394 
0395         idx_lsb = addr40 ? 39 : 31;
0396         iid_lsb = idx_lsb - 1;
0397 
0398         if (addr & BIT_ULL(idx_lsb))
0399             *dest_island = isld1 | (int)((addr >> iid_lsb) & 1);
0400         else
0401             *dest_island = isld0 | (int)((addr >> iid_lsb) & 1);
0402 
0403         return 0;
0404     case 3:
0405         /* In this mode the data address starts to affect the island ID
0406          * so rather not allow it. In some really specific case
0407          * one could use this to send the upper half of the
0408          * VQDR channel to another MU, but this is getting very
0409          * specific.
0410          * However, as above for mode 0, this is the decoder
0411          * and the caller should validate the resulting IID.
0412          * This blindly does what the silicon would do.
0413          */
0414         isld0 &= ~3;
0415         isld1 &= ~3;
0416 
0417         idx_lsb = addr40 ? 39 : 31;
0418         iid_lsb = idx_lsb - 2;
0419 
0420         if (addr & BIT_ULL(idx_lsb))
0421             *dest_island = isld1 | (int)((addr >> iid_lsb) & 3);
0422         else
0423             *dest_island = isld0 | (int)((addr >> iid_lsb) & 3);
0424 
0425         return 0;
0426     default:
0427         return -EINVAL;
0428     }
0429 }
0430 
0431 static int nfp_encode_basic_qdr(u64 addr, int dest_island, int cpp_tgt,
0432                 int mode, bool addr40, int isld1, int isld0)
0433 {
0434     int v, ret;
0435 
0436     /* Full Island ID and channel bits overlap? */
0437     ret = nfp_decode_basic(addr, &v, cpp_tgt, mode, addr40, isld1, isld0);
0438     if (ret)
0439         return ret;
0440 
0441     /* The current address won't go where expected? */
0442     if (dest_island != -1 && dest_island != v)
0443         return -EINVAL;
0444 
0445     /* If dest_island was -1, we don't care where it goes. */
0446     return 0;
0447 }
0448 
0449 /* Try each option, take first one that fits.
0450  * Not sure if we would want to do some smarter
0451  * searching and prefer 0 or non-0 island IDs.
0452  */
0453 static int nfp_encode_basic_search(u64 *addr, int dest_island, int *isld,
0454                    int iid_lsb, int idx_lsb, int v_max)
0455 {
0456     int i, v;
0457 
0458     for (i = 0; i < 2; i++)
0459         for (v = 0; v < v_max; v++) {
0460             if (dest_island != (isld[i] | v))
0461                 continue;
0462 
0463             *addr &= ~GENMASK_ULL(idx_lsb, iid_lsb);
0464             *addr |= ((u64)i << idx_lsb);
0465             *addr |= ((u64)v << iid_lsb);
0466             return 0;
0467         }
0468 
0469     return -ENODEV;
0470 }
0471 
0472 /* For VQDR, we may not modify the Channel bits, which might overlap
0473  *  with the Index bit. When it does, we need to ensure that isld0 == isld1.
0474  */
0475 static int nfp_encode_basic(u64 *addr, int dest_island, int cpp_tgt,
0476                 int mode, bool addr40, int isld1, int isld0)
0477 {
0478     int iid_lsb, idx_lsb;
0479     int isld[2];
0480     u64 v64;
0481 
0482     isld[0] = isld0;
0483     isld[1] = isld1;
0484 
0485     /* This function doesn't handle MU or CTXBP */
0486     if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
0487         return -EINVAL;
0488 
0489     switch (mode) {
0490     case 0:
0491         if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
0492             /* In this specific mode we'd rather not modify
0493              * the address but we can verify if the existing
0494              * contents will point to a valid island.
0495              */
0496             return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
0497                             mode, addr40, isld1, isld0);
0498 
0499         iid_lsb = addr40 ? 34 : 26;
0500         /* <39:34> or <31:26> */
0501         v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
0502         *addr &= ~v64;
0503         *addr |= ((u64)dest_island << iid_lsb) & v64;
0504         return 0;
0505     case 1:
0506         if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
0507             return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
0508                             mode, addr40, isld1, isld0);
0509 
0510         idx_lsb = addr40 ? 39 : 31;
0511         if (dest_island == isld0) {
0512             /* Only need to clear the Index bit */
0513             *addr &= ~BIT_ULL(idx_lsb);
0514             return 0;
0515         }
0516 
0517         if (dest_island == isld1) {
0518             /* Only need to set the Index bit */
0519             *addr |= BIT_ULL(idx_lsb);
0520             return 0;
0521         }
0522 
0523         return -ENODEV;
0524     case 2:
0525         /* iid<0> = addr<30> = channel<0>
0526          * channel<1> = addr<31> = Index
0527          */
0528         if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
0529             /* Special case where we allow channel bits to
0530              * be set before hand and with them select an island.
0531              * So we need to confirm that it's at least plausible.
0532              */
0533             return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
0534                             mode, addr40, isld1, isld0);
0535 
0536         /* Make sure we compare against isldN values
0537          * by clearing the LSB.
0538          * This is what the silicon does.
0539          */
0540         isld[0] &= ~1;
0541         isld[1] &= ~1;
0542 
0543         idx_lsb = addr40 ? 39 : 31;
0544         iid_lsb = idx_lsb - 1;
0545 
0546         return nfp_encode_basic_search(addr, dest_island, isld,
0547                            iid_lsb, idx_lsb, 2);
0548     case 3:
0549         if (cpp_tgt == NFP_CPP_TARGET_QDR && !addr40)
0550             /* iid<0> = addr<29> = data
0551              * iid<1> = addr<30> = channel<0>
0552              * channel<1> = addr<31> = Index
0553              */
0554             return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
0555                             mode, addr40, isld1, isld0);
0556 
0557         isld[0] &= ~3;
0558         isld[1] &= ~3;
0559 
0560         idx_lsb = addr40 ? 39 : 31;
0561         iid_lsb = idx_lsb - 2;
0562 
0563         return nfp_encode_basic_search(addr, dest_island, isld,
0564                            iid_lsb, idx_lsb, 4);
0565     default:
0566         return -EINVAL;
0567     }
0568 }
0569 
0570 static int nfp_encode_mu(u64 *addr, int dest_island, int mode,
0571              bool addr40, int isld1, int isld0)
0572 {
0573     int iid_lsb, idx_lsb, locality_lsb;
0574     int isld[2];
0575     u64 v64;
0576     int da;
0577 
0578     isld[0] = isld0;
0579     isld[1] = isld1;
0580     locality_lsb = nfp_cppat_mu_locality_lsb(mode, addr40);
0581 
0582     if (((*addr >> locality_lsb) & 3) == _NIC_NFP6000_MU_LOCALITY_DIRECT)
0583         da = 1;
0584     else
0585         da = 0;
0586 
0587     switch (mode) {
0588     case 0:
0589         iid_lsb = addr40 ? 32 : 24;
0590         v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
0591         *addr &= ~v64;
0592         *addr |= (((u64)dest_island) << iid_lsb) & v64;
0593         return 0;
0594     case 1:
0595         if (da) {
0596             iid_lsb = addr40 ? 32 : 24;
0597             v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
0598             *addr &= ~v64;
0599             *addr |= (((u64)dest_island) << iid_lsb) & v64;
0600             return 0;
0601         }
0602 
0603         idx_lsb = addr40 ? 37 : 29;
0604         if (dest_island == isld0) {
0605             *addr &= ~BIT_ULL(idx_lsb);
0606             return 0;
0607         }
0608 
0609         if (dest_island == isld1) {
0610             *addr |= BIT_ULL(idx_lsb);
0611             return 0;
0612         }
0613 
0614         return -ENODEV;
0615     case 2:
0616         if (da) {
0617             iid_lsb = addr40 ? 32 : 24;
0618             v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
0619             *addr &= ~v64;
0620             *addr |= (((u64)dest_island) << iid_lsb) & v64;
0621             return 0;
0622         }
0623 
0624         /* Make sure we compare against isldN values
0625          * by clearing the LSB.
0626          * This is what the silicon does.
0627          */
0628         isld[0] &= ~1;
0629         isld[1] &= ~1;
0630 
0631         idx_lsb = addr40 ? 37 : 29;
0632         iid_lsb = idx_lsb - 1;
0633 
0634         return nfp_encode_basic_search(addr, dest_island, isld,
0635                            iid_lsb, idx_lsb, 2);
0636     case 3:
0637         /* Only the EMU will use 40 bit addressing. Silently
0638          * set the direct locality bit for everyone else.
0639          * The SDK toolchain uses dest_island <= 0 to test
0640          * for atypical address encodings to support access
0641          * to local-island CTM with a 32-but address (high-locality
0642          * is effewctively ignored and just used for
0643          * routing to island #0).
0644          */
0645         if (dest_island > 0 && (dest_island < 24 || dest_island > 26)) {
0646             *addr |= ((u64)_NIC_NFP6000_MU_LOCALITY_DIRECT)
0647                             << locality_lsb;
0648             da = 1;
0649         }
0650 
0651         if (da) {
0652             iid_lsb = addr40 ? 32 : 24;
0653             v64 = GENMASK_ULL(iid_lsb + 5, iid_lsb);
0654             *addr &= ~v64;
0655             *addr |= (((u64)dest_island) << iid_lsb) & v64;
0656             return 0;
0657         }
0658 
0659         isld[0] &= ~3;
0660         isld[1] &= ~3;
0661 
0662         idx_lsb = addr40 ? 37 : 29;
0663         iid_lsb = idx_lsb - 2;
0664 
0665         return nfp_encode_basic_search(addr, dest_island, isld,
0666                            iid_lsb, idx_lsb, 4);
0667     default:
0668         return -EINVAL;
0669     }
0670 }
0671 
0672 static int nfp_cppat_addr_encode(u64 *addr, int dest_island, int cpp_tgt,
0673                  int mode, bool addr40, int isld1, int isld0)
0674 {
0675     switch (cpp_tgt) {
0676     case NFP_CPP_TARGET_NBI:
0677     case NFP_CPP_TARGET_QDR:
0678     case NFP_CPP_TARGET_ILA:
0679     case NFP_CPP_TARGET_PCIE:
0680     case NFP_CPP_TARGET_ARM:
0681     case NFP_CPP_TARGET_CRYPTO:
0682     case NFP_CPP_TARGET_CLS:
0683         return nfp_encode_basic(addr, dest_island, cpp_tgt, mode,
0684                     addr40, isld1, isld0);
0685 
0686     case NFP_CPP_TARGET_MU:
0687         return nfp_encode_mu(addr, dest_island, mode,
0688                      addr40, isld1, isld0);
0689 
0690     case NFP_CPP_TARGET_CT_XPB:
0691         if (mode != 1 || addr40)
0692             return -EINVAL;
0693         *addr &= ~GENMASK_ULL(29, 24);
0694         *addr |= ((u64)dest_island << 24) & GENMASK_ULL(29, 24);
0695         return 0;
0696     default:
0697         return -EINVAL;
0698     }
0699 }
0700 
0701 int nfp_target_cpp(u32 cpp_island_id, u64 cpp_island_address,
0702            u32 *cpp_target_id, u64 *cpp_target_address,
0703            const u32 *imb_table)
0704 {
0705     const int island = NFP_CPP_ID_ISLAND_of(cpp_island_id);
0706     const int target = NFP_CPP_ID_TARGET_of(cpp_island_id);
0707     u32 imb;
0708     int err;
0709 
0710     if (target < 0 || target >= 16) {
0711         pr_err("Invalid CPP target: %d\n", target);
0712         return -EINVAL;
0713     }
0714 
0715     if (island == 0) {
0716         /* Already translated */
0717         *cpp_target_id = cpp_island_id;
0718         *cpp_target_address = cpp_island_address;
0719         return 0;
0720     }
0721 
0722     /* CPP + Island only allowed on systems with IMB tables */
0723     if (!imb_table)
0724         return -EINVAL;
0725 
0726     imb = imb_table[target];
0727 
0728     *cpp_target_address = cpp_island_address;
0729     err = nfp_cppat_addr_encode(cpp_target_address, island, target,
0730                     ((imb >> 13) & 7), ((imb >> 12) & 1),
0731                     ((imb >> 6)  & 0x3f), ((imb >> 0)  & 0x3f));
0732     if (err) {
0733         pr_err("Can't encode CPP address: %d\n", err);
0734         return err;
0735     }
0736 
0737     *cpp_target_id = NFP_CPP_ID(target,
0738                     NFP_CPP_ID_ACTION_of(cpp_island_id),
0739                     NFP_CPP_ID_TOKEN_of(cpp_island_id));
0740 
0741     return 0;
0742 }