LCOV - code coverage report
Current view: top level - drivers/net/nfp/nfpcore - nfp_target.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 398 0.0 %
Date: 2024-01-22 15:55:54 Functions: 0 17 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 385 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (c) 2022 Corigine, Inc.
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "nfp_target.h"
       7                 :            : 
       8                 :            : #include "nfp_cpp.h"
       9                 :            : #include "nfp6000/nfp6000.h"
      10                 :            : 
      11                 :            : #define P32 1
      12                 :            : #define P64 2
      13                 :            : 
      14                 :            : /*
      15                 :            :  * All magic NFP-6xxx IMB 'mode' numbers here are from:
      16                 :            :  * Databook (1 August 2013)
      17                 :            :  * - System Overview and Connectivity
      18                 :            :  * -- Internal Connectivity
      19                 :            :  * --- Distributed Switch Fabric - Command Push/Pull (DSF-CPP) Bus
      20                 :            :  * ---- CPP addressing
      21                 :            :  * ----- Table 3.6. CPP Address Translation Mode Commands
      22                 :            :  */
      23                 :            : #define NFP6000_MU_LOCALITY_DIRECT 2
      24                 :            : 
      25                 :            : static int
      26                 :            : target_rw(uint32_t cpp_id,
      27                 :            :                 int pp,
      28                 :            :                 int start,
      29                 :            :                 int len)
      30                 :            : {
      31                 :            :         uint8_t island;
      32                 :            : 
      33                 :            :         island = NFP_CPP_ID_ISLAND_of(cpp_id);
      34   [ #  #  #  #  :          0 :         if (island != 0 && (island < start || island > (start + len)))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
      35                 :            :                 return -EINVAL;
      36                 :            : 
      37   [ #  #  #  #  :          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
      38                 :            :         case NFP_CPP_ID(0, 0, 0):
      39                 :            :                 return PUSHPULL(0, pp);
      40                 :          0 :         case NFP_CPP_ID(0, 1, 0):
      41                 :          0 :                 return PUSHPULL(pp, 0);
      42                 :          0 :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
      43                 :          0 :                 return PUSHPULL(pp, pp);
      44                 :          0 :         default:
      45                 :          0 :                 return -EINVAL;
      46                 :            :         }
      47                 :            : }
      48                 :            : 
      49                 :            : static int
      50                 :            : nfp6000_nbi_dma(uint32_t cpp_id)
      51                 :            : {
      52   [ #  #  #  # ]:          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
      53                 :            :         case NFP_CPP_ID(0, 0, 0): /* Read NBI DMA */
      54                 :            :                 return PUSHPULL(0, P64);
      55                 :          0 :         case NFP_CPP_ID(0, 1, 0): /* Write NBI DMA */
      56                 :          0 :                 return PUSHPULL(P64, 0);
      57                 :          0 :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
      58                 :          0 :                 return PUSHPULL(P64, P64);
      59                 :          0 :         default:
      60                 :          0 :                 return -EINVAL;
      61                 :            :         }
      62                 :            : }
      63                 :            : 
      64                 :            : static int
      65                 :            : nfp6000_nbi_stats(uint32_t cpp_id)
      66                 :            : {
      67   [ #  #  #  # ]:          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
      68                 :            :         case NFP_CPP_ID(0, 0, 0): /* Read NBI Stats */
      69                 :            :                 return PUSHPULL(0, P32);
      70                 :          0 :         case NFP_CPP_ID(0, 1, 0): /* Write NBI Stats */
      71                 :          0 :                 return PUSHPULL(P32, 0);
      72                 :          0 :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
      73                 :          0 :                 return PUSHPULL(P32, P32);
      74                 :          0 :         default:
      75                 :          0 :                 return -EINVAL;
      76                 :            :         }
      77                 :            : }
      78                 :            : 
      79                 :            : static int
      80                 :            : nfp6000_nbi_tm(uint32_t cpp_id)
      81                 :            : {
      82   [ #  #  #  # ]:          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
      83                 :            :         case NFP_CPP_ID(0, 0, 0): /* Read NBI TM */
      84                 :            :                 return PUSHPULL(0, P64);
      85                 :          0 :         case NFP_CPP_ID(0, 1, 0): /* Write NBI TM */
      86                 :          0 :                 return PUSHPULL(P64, 0);
      87                 :          0 :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
      88                 :          0 :                 return PUSHPULL(P64, P64);
      89                 :          0 :         default:
      90                 :          0 :                 return -EINVAL;
      91                 :            :         }
      92                 :            : }
      93                 :            : 
      94                 :            : static int
      95                 :            : nfp6000_nbi_ppc(uint32_t cpp_id)
      96                 :            : {
      97   [ #  #  #  # ]:          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
      98                 :            :         case NFP_CPP_ID(0, 0, 0): /* Read NBI Preclassifier */
      99                 :            :                 return PUSHPULL(0, P64);
     100                 :          0 :         case NFP_CPP_ID(0, 1, 0): /* Write NBI Preclassifier */
     101                 :          0 :                 return PUSHPULL(P64, 0);
     102                 :          0 :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
     103                 :          0 :                 return PUSHPULL(P64, P64);
     104                 :          0 :         default:
     105                 :          0 :                 return -EINVAL;
     106                 :            :         }
     107                 :            : }
     108                 :            : 
     109                 :            : static int
     110         [ #  # ]:          0 : nfp6000_nbi(uint32_t cpp_id,
     111                 :            :                 uint64_t address)
     112                 :            : {
     113                 :            :         uint8_t island;
     114                 :            :         uint64_t rel_addr;
     115                 :            : 
     116                 :            :         island = NFP_CPP_ID_ISLAND_of(cpp_id);
     117         [ #  # ]:          0 :         if (island != 8 && island != 9)
     118                 :            :                 return -EINVAL;
     119                 :            : 
     120                 :          0 :         rel_addr = address & 0x3FFFFF;
     121         [ #  # ]:          0 :         if (rel_addr < (1 << 20))        /* [0x000000, 0x100000) */
     122                 :          0 :                 return nfp6000_nbi_dma(cpp_id);
     123         [ #  # ]:          0 :         else if (rel_addr < (2 << 20))   /* [0x100000, 0x200000) */
     124                 :          0 :                 return nfp6000_nbi_stats(cpp_id);
     125         [ #  # ]:          0 :         else if (rel_addr < (3 << 20))   /* [0x200000, 0x300000) */
     126                 :          0 :                 return nfp6000_nbi_tm(cpp_id);
     127                 :            :         else                             /* [0x300000, 0x400000) */
     128                 :          0 :                 return nfp6000_nbi_ppc(cpp_id);
     129                 :            : }
     130                 :            : 
     131                 :            : /*
     132                 :            :  * This structure ONLY includes items that can be done with a read or write of
     133                 :            :  * 32-bit or 64-bit words. All others are not listed.
     134                 :            :  */
     135                 :            : static int
     136                 :          0 : nfp6000_mu_common(uint32_t cpp_id)
     137                 :            : {
     138   [ #  #  #  #  :          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     139                 :            :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0): /* read_be/write_be */
     140                 :            :                 return PUSHPULL(P64, P64);
     141                 :            :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 1): /* read_le/write_le */
     142                 :            :                 return PUSHPULL(P64, P64);
     143                 :            :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 2): /* read_swap_be/write_swap_be */
     144                 :            :                 return PUSHPULL(P64, P64);
     145                 :            :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 3): /* read_swap_le/write_swap_le */
     146                 :            :                 return PUSHPULL(P64, P64);
     147                 :          0 :         case NFP_CPP_ID(0, 0, 0): /* read_be */
     148                 :          0 :                 return PUSHPULL(0, P64);
     149                 :          0 :         case NFP_CPP_ID(0, 0, 1): /* read_le */
     150                 :          0 :                 return PUSHPULL(0, P64);
     151                 :          0 :         case NFP_CPP_ID(0, 0, 2): /* read_swap_be */
     152                 :          0 :                 return PUSHPULL(0, P64);
     153                 :          0 :         case NFP_CPP_ID(0, 0, 3): /* read_swap_le */
     154                 :          0 :                 return PUSHPULL(0, P64);
     155                 :          0 :         case NFP_CPP_ID(0, 1, 0): /* write_be */
     156                 :          0 :                 return PUSHPULL(P64, 0);
     157                 :          0 :         case NFP_CPP_ID(0, 1, 1): /* write_le */
     158                 :          0 :                 return PUSHPULL(P64, 0);
     159                 :          0 :         case NFP_CPP_ID(0, 1, 2): /* write_swap_be */
     160                 :          0 :                 return PUSHPULL(P64, 0);
     161                 :          0 :         case NFP_CPP_ID(0, 1, 3): /* write_swap_le */
     162                 :          0 :                 return PUSHPULL(P64, 0);
     163                 :          0 :         case NFP_CPP_ID(0, 3, 0): /* atomic_read */
     164                 :          0 :                 return PUSHPULL(0, P32);
     165                 :          0 :         case NFP_CPP_ID(0, 3, 2): /* mask_compare_write */
     166                 :          0 :                 return PUSHPULL(P32, 0);
     167                 :          0 :         case NFP_CPP_ID(0, 4, 0): /* atomic_write */
     168                 :          0 :                 return PUSHPULL(P32, 0);
     169                 :          0 :         case NFP_CPP_ID(0, 4, 2): /* atomic_write_imm */
     170                 :          0 :                 return PUSHPULL(0, 0);
     171                 :          0 :         case NFP_CPP_ID(0, 4, 3): /* swap_imm */
     172                 :          0 :                 return PUSHPULL(0, P32);
     173                 :          0 :         case NFP_CPP_ID(0, 5, 0): /* set */
     174                 :          0 :                 return PUSHPULL(P32, 0);
     175                 :          0 :         case NFP_CPP_ID(0, 5, 3): /* test_set_imm */
     176                 :          0 :                 return PUSHPULL(0, P32);
     177                 :          0 :         case NFP_CPP_ID(0, 6, 0): /* clr */
     178                 :          0 :                 return PUSHPULL(P32, 0);
     179                 :          0 :         case NFP_CPP_ID(0, 6, 3): /* test_clr_imm */
     180                 :          0 :                 return PUSHPULL(0, P32);
     181                 :          0 :         case NFP_CPP_ID(0, 7, 0): /* add */
     182                 :          0 :                 return PUSHPULL(P32, 0);
     183                 :          0 :         case NFP_CPP_ID(0, 7, 3): /* test_add_imm */
     184                 :          0 :                 return PUSHPULL(0, P32);
     185                 :          0 :         case NFP_CPP_ID(0, 8, 0): /* addsat */
     186                 :          0 :                 return PUSHPULL(P32, 0);
     187                 :          0 :         case NFP_CPP_ID(0, 8, 3): /* test_subsat_imm */
     188                 :          0 :                 return PUSHPULL(0, P32);
     189                 :          0 :         case NFP_CPP_ID(0, 9, 0): /* sub */
     190                 :          0 :                 return PUSHPULL(P32, 0);
     191                 :          0 :         case NFP_CPP_ID(0, 9, 3): /* test_sub_imm */
     192                 :          0 :                 return PUSHPULL(0, P32);
     193                 :          0 :         case NFP_CPP_ID(0, 10, 0): /* subsat */
     194                 :          0 :                 return PUSHPULL(P32, 0);
     195                 :          0 :         case NFP_CPP_ID(0, 10, 3): /* test_subsat_imm */
     196                 :          0 :                 return PUSHPULL(0, P32);
     197                 :          0 :         case NFP_CPP_ID(0, 13, 0): /* microq128_get */
     198                 :          0 :                 return PUSHPULL(0, P32);
     199                 :          0 :         case NFP_CPP_ID(0, 13, 1): /* microq128_pop */
     200                 :          0 :                 return PUSHPULL(0, P32);
     201                 :          0 :         case NFP_CPP_ID(0, 13, 2): /* microq128_put */
     202                 :          0 :                 return PUSHPULL(P32, 0);
     203                 :          0 :         case NFP_CPP_ID(0, 15, 0): /* xor */
     204                 :          0 :                 return PUSHPULL(P32, 0);
     205                 :          0 :         case NFP_CPP_ID(0, 15, 3): /* test_xor_imm */
     206                 :          0 :                 return PUSHPULL(0, P32);
     207                 :          0 :         case NFP_CPP_ID(0, 28, 0): /* read32_be */
     208                 :          0 :                 return PUSHPULL(0, P32);
     209                 :          0 :         case NFP_CPP_ID(0, 28, 1): /* read32_le */
     210                 :          0 :                 return PUSHPULL(0, P32);
     211                 :          0 :         case NFP_CPP_ID(0, 28, 2): /* read32_swap_be */
     212                 :          0 :                 return PUSHPULL(0, P32);
     213                 :          0 :         case NFP_CPP_ID(0, 28, 3): /* read32_swap_le */
     214                 :          0 :                 return PUSHPULL(0, P32);
     215                 :          0 :         case NFP_CPP_ID(0, 31, 0): /* write32_be */
     216                 :          0 :                 return PUSHPULL(P32, 0);
     217                 :          0 :         case NFP_CPP_ID(0, 31, 1): /* write32_le */
     218                 :          0 :                 return PUSHPULL(P32, 0);
     219                 :          0 :         case NFP_CPP_ID(0, 31, 2): /* write32_swap_be */
     220                 :          0 :                 return PUSHPULL(P32, 0);
     221                 :          0 :         case NFP_CPP_ID(0, 31, 3): /* write32_swap_le */
     222                 :          0 :                 return PUSHPULL(P32, 0);
     223                 :          0 :         default:
     224                 :          0 :                 return -EINVAL;
     225                 :            :         }
     226                 :            : }
     227                 :            : 
     228                 :            : static int
     229                 :          0 : nfp6000_mu_ctm(uint32_t cpp_id)
     230                 :            : {
     231   [ #  #  #  #  :          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
             #  #  #  #  
                      # ]
     232                 :            :         case NFP_CPP_ID(0, 16, 1): /* packet_read_packet_status */
     233                 :            :                 return PUSHPULL(0, P32);
     234                 :            :         case NFP_CPP_ID(0, 17, 1): /* packet_credit_get */
     235                 :            :                 return PUSHPULL(0, P32);
     236                 :          0 :         case NFP_CPP_ID(0, 17, 3): /* packet_add_thread */
     237                 :          0 :                 return PUSHPULL(0, P64);
     238                 :          0 :         case NFP_CPP_ID(0, 18, 2): /* packet_free_and_return_pointer */
     239                 :          0 :                 return PUSHPULL(0, P64);
     240                 :          0 :         case NFP_CPP_ID(0, 18, 3): /* packet_return_pointer */
     241                 :          0 :                 return PUSHPULL(0, P64);
     242                 :          0 :         case NFP_CPP_ID(0, 21, 0): /* pe_dma_to_memory_indirect */
     243                 :          0 :                 return PUSHPULL(0, P64);
     244                 :          0 :         case NFP_CPP_ID(0, 21, 1): /* pe_dma_to_memory_indirect_swap */
     245                 :          0 :                 return PUSHPULL(0, P64);
     246                 :          0 :         case NFP_CPP_ID(0, 21, 2): /* pe_dma_to_memory_indirect_free */
     247                 :          0 :                 return PUSHPULL(0, P64);
     248                 :          0 :         case NFP_CPP_ID(0, 21, 3): /* pe_dma_to_memory_indirect_free_swap */
     249                 :          0 :                 return PUSHPULL(0, P64);
     250                 :          0 :         default:
     251                 :          0 :                 return nfp6000_mu_common(cpp_id);
     252                 :            :         }
     253                 :            : }
     254                 :            : 
     255                 :            : static int
     256                 :          0 : nfp6000_mu_emu(uint32_t cpp_id)
     257                 :            : {
     258   [ #  #  #  #  :          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
                      # ]
     259                 :            :         case NFP_CPP_ID(0, 18, 0): /* read_queue */
     260                 :            :                 return PUSHPULL(0, P32);
     261                 :            :         case NFP_CPP_ID(0, 18, 1): /* read_queue_ring */
     262                 :            :                 return PUSHPULL(0, P32);
     263                 :          0 :         case NFP_CPP_ID(0, 18, 2): /* write_queue */
     264                 :          0 :                 return PUSHPULL(P32, 0);
     265                 :          0 :         case NFP_CPP_ID(0, 18, 3): /* write_queue_ring */
     266                 :          0 :                 return PUSHPULL(P32, 0);
     267                 :          0 :         case NFP_CPP_ID(0, 20, 2): /* journal */
     268                 :          0 :                 return PUSHPULL(P32, 0);
     269                 :            :         case NFP_CPP_ID(0, 21, 0): /* get */
     270                 :            :                 return PUSHPULL(0, P32);
     271                 :            :         case NFP_CPP_ID(0, 21, 1): /* get_eop */
     272                 :            :                 return PUSHPULL(0, P32);
     273                 :            :         case NFP_CPP_ID(0, 21, 2): /* get_freely */
     274                 :            :                 return PUSHPULL(0, P32);
     275                 :            :         case NFP_CPP_ID(0, 22, 0): /* pop */
     276                 :            :                 return PUSHPULL(0, P32);
     277                 :            :         case NFP_CPP_ID(0, 22, 1): /* pop_eop */
     278                 :            :                 return PUSHPULL(0, P32);
     279                 :            :         case NFP_CPP_ID(0, 22, 2): /* pop_freely */
     280                 :            :                 return PUSHPULL(0, P32);
     281                 :          0 :         default:
     282                 :          0 :                 return nfp6000_mu_common(cpp_id);
     283                 :            :         }
     284                 :            : }
     285                 :            : 
     286                 :            : static int
     287                 :            : nfp6000_mu_imu(uint32_t cpp_id)
     288                 :            : {
     289                 :          0 :         return nfp6000_mu_common(cpp_id);
     290                 :            : }
     291                 :            : 
     292                 :            : static int
     293         [ #  # ]:          0 : nfp6000_mu(uint32_t cpp_id,
     294                 :            :                 uint64_t address)
     295                 :            : {
     296                 :            :         int pp;
     297                 :            :         uint8_t island;
     298                 :            : 
     299                 :            :         island = NFP_CPP_ID_ISLAND_of(cpp_id);
     300         [ #  # ]:          0 :         if (island == 0) {
     301         [ #  # ]:          0 :                 if (address < 0x2000000000ULL)
     302                 :          0 :                         pp = nfp6000_mu_ctm(cpp_id);
     303         [ #  # ]:          0 :                 else if (address < 0x8000000000ULL)
     304                 :          0 :                         pp = nfp6000_mu_emu(cpp_id);
     305         [ #  # ]:          0 :                 else if (address < 0x9800000000ULL)
     306                 :          0 :                         pp = nfp6000_mu_ctm(cpp_id);
     307         [ #  # ]:          0 :                 else if (address < 0x9C00000000ULL)
     308                 :          0 :                         pp = nfp6000_mu_emu(cpp_id);
     309         [ #  # ]:          0 :                 else if (address < 0xA000000000ULL)
     310                 :            :                         pp = nfp6000_mu_imu(cpp_id);
     311                 :            :                 else
     312                 :          0 :                         pp = nfp6000_mu_ctm(cpp_id);
     313   [ #  #  #  # ]:          0 :         } else if (island >= 24 && island <= 27) {
     314                 :          0 :                 pp = nfp6000_mu_emu(cpp_id);
     315                 :            :         } else if (island >= 28 && island <= 31) {
     316                 :            :                 pp = nfp6000_mu_imu(cpp_id);
     317                 :            :         } else if (island == 1 ||
     318                 :            :                         (island >= 4 && island <= 7) ||
     319                 :            :                         (island >= 12 && island <= 13) ||
     320                 :            :                         (island >= 32 && island <= 51)) {
     321                 :          0 :                 pp = nfp6000_mu_ctm(cpp_id);
     322                 :            :         } else {
     323                 :            :                 pp = -EINVAL;
     324                 :            :         }
     325                 :            : 
     326                 :          0 :         return pp;
     327                 :            : }
     328                 :            : 
     329                 :            : static int
     330         [ #  # ]:          0 : nfp6000_ila(uint32_t cpp_id)
     331                 :            : {
     332                 :            :         uint8_t island;
     333                 :            : 
     334                 :            :         island = NFP_CPP_ID_ISLAND_of(cpp_id);
     335         [ #  # ]:          0 :         if (island != 0 && (island < 48 || island > 51))
     336                 :            :                 return -EINVAL;
     337                 :            : 
     338      [ #  #  # ]:          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
     339                 :            :         case NFP_CPP_ID(0, 0, 1): /* read_check_error */
     340                 :            :                 return PUSHPULL(0, P32);
     341                 :            :         case NFP_CPP_ID(0, 2, 0): /* read_int */
     342                 :            :                 return PUSHPULL(0, P32);
     343                 :          0 :         case NFP_CPP_ID(0, 3, 0): /* write_int */
     344                 :          0 :                 return PUSHPULL(P32, 0);
     345                 :            :         default:
     346                 :            :                 return target_rw(cpp_id, P32, 48, 4);
     347                 :            :         }
     348                 :            : }
     349                 :            : 
     350                 :            : static int
     351         [ #  # ]:          0 : nfp6000_pci(uint32_t cpp_id)
     352                 :            : {
     353                 :            :         uint8_t island;
     354                 :            : 
     355                 :            :         island = NFP_CPP_ID_ISLAND_of(cpp_id);
     356         [ #  # ]:          0 :         if (island != 0 && (island < 4 || island > 7))
     357                 :            :                 return -EINVAL;
     358                 :            : 
     359      [ #  #  # ]:          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
     360                 :            :         case NFP_CPP_ID(0, 2, 0):
     361                 :            :                 return PUSHPULL(0, P32);
     362                 :          0 :         case NFP_CPP_ID(0, 3, 0):
     363                 :          0 :                 return PUSHPULL(P32, 0);
     364                 :            :         default:
     365                 :            :                 return target_rw(cpp_id, P32, 4, 4);
     366                 :            :         }
     367                 :            : }
     368                 :            : 
     369                 :            : static int
     370         [ #  # ]:          0 : nfp6000_crypto(uint32_t cpp_id)
     371                 :            : {
     372                 :            :         uint8_t island;
     373                 :            : 
     374                 :            :         island = NFP_CPP_ID_ISLAND_of(cpp_id);
     375         [ #  # ]:          0 :         if (island != 0 && (island < 12 || island > 15))
     376                 :            :                 return -EINVAL;
     377                 :            : 
     378         [ #  # ]:          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
     379                 :            :         case NFP_CPP_ID(0, 2, 0):
     380                 :            :                 return PUSHPULL(P64, 0);
     381                 :            :         default:
     382                 :            :                 return target_rw(cpp_id, P64, 12, 4);
     383                 :            :         }
     384                 :            : }
     385                 :            : 
     386                 :            : static int
     387         [ #  # ]:          0 : nfp6000_cap_xpb(uint32_t cpp_id)
     388                 :            : {
     389                 :            :         uint8_t island;
     390                 :            : 
     391                 :            :         island = NFP_CPP_ID_ISLAND_of(cpp_id);
     392         [ #  # ]:          0 :         if (island > 63)
     393                 :            :                 return -EINVAL;
     394                 :            : 
     395   [ #  #  #  #  :          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
          #  #  #  #  #  
                      # ]
     396                 :            :         case NFP_CPP_ID(0, 0, 1): /* RingGet */
     397                 :            :                 return PUSHPULL(0, P32);
     398                 :          0 :         case NFP_CPP_ID(0, 0, 2): /* Interthread Signal */
     399                 :          0 :                 return PUSHPULL(P32, 0);
     400                 :          0 :         case NFP_CPP_ID(0, 1, 1): /* RingPut */
     401                 :          0 :                 return PUSHPULL(P32, 0);
     402                 :          0 :         case NFP_CPP_ID(0, 1, 2): /* CTNNWr */
     403                 :          0 :                 return PUSHPULL(P32, 0);
     404                 :            :         case NFP_CPP_ID(0, 2, 0): /* ReflectRd, signal none */
     405                 :            :                 return PUSHPULL(0, P32);
     406                 :            :         case NFP_CPP_ID(0, 2, 1): /* ReflectRd, signal self */
     407                 :            :                 return PUSHPULL(0, P32);
     408                 :            :         case NFP_CPP_ID(0, 2, 2): /* ReflectRd, signal remote */
     409                 :            :                 return PUSHPULL(0, P32);
     410                 :            :         case NFP_CPP_ID(0, 2, 3): /* ReflectRd, signal both */
     411                 :            :                 return PUSHPULL(0, P32);
     412                 :          0 :         case NFP_CPP_ID(0, 3, 0): /* ReflectWr, signal none */
     413                 :          0 :                 return PUSHPULL(P32, 0);
     414                 :          0 :         case NFP_CPP_ID(0, 3, 1): /* ReflectWr, signal self */
     415                 :          0 :                 return PUSHPULL(P32, 0);
     416                 :          0 :         case NFP_CPP_ID(0, 3, 2): /* ReflectWr, signal remote */
     417                 :          0 :                 return PUSHPULL(P32, 0);
     418                 :          0 :         case NFP_CPP_ID(0, 3, 3): /* ReflectWr, signal both */
     419                 :          0 :                 return PUSHPULL(P32, 0);
     420                 :          0 :         case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 1):
     421                 :          0 :                 return PUSHPULL(P32, P32);
     422                 :            :         default:
     423                 :            :                 return target_rw(cpp_id, P32, 1, 63);
     424                 :            :         }
     425                 :            : }
     426                 :            : 
     427                 :            : static int
     428         [ #  # ]:          0 : nfp6000_cls(uint32_t cpp_id)
     429                 :            : {
     430                 :            :         uint8_t island;
     431                 :            : 
     432                 :            :         island = NFP_CPP_ID_ISLAND_of(cpp_id);
     433         [ #  # ]:          0 :         if (island > 63)
     434                 :            :                 return -EINVAL;
     435                 :            : 
     436   [ #  #  #  #  :          0 :         switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
             #  #  #  #  
                      # ]
     437                 :            :         case NFP_CPP_ID(0, 0, 3): /* xor */
     438                 :            :                 return PUSHPULL(P32, 0);
     439                 :            :         case NFP_CPP_ID(0, 2, 0): /* set */
     440                 :            :                 return PUSHPULL(P32, 0);
     441                 :            :         case NFP_CPP_ID(0, 2, 1): /* clr */
     442                 :            :                 return PUSHPULL(P32, 0);
     443                 :            :         case NFP_CPP_ID(0, 4, 0): /* add */
     444                 :            :                 return PUSHPULL(P32, 0);
     445                 :            :         case NFP_CPP_ID(0, 4, 1): /* add64 */
     446                 :            :                 return PUSHPULL(P32, 0);
     447                 :            :         case NFP_CPP_ID(0, 6, 0): /* sub */
     448                 :            :                 return PUSHPULL(P32, 0);
     449                 :            :         case NFP_CPP_ID(0, 6, 1): /* sub64 */
     450                 :            :                 return PUSHPULL(P32, 0);
     451                 :            :         case NFP_CPP_ID(0, 6, 2): /* subsat */
     452                 :            :                 return PUSHPULL(P32, 0);
     453                 :            :         case NFP_CPP_ID(0, 8, 2): /* hash_mask */
     454                 :            :                 return PUSHPULL(P32, 0);
     455                 :            :         case NFP_CPP_ID(0, 8, 3): /* hash_clear */
     456                 :            :                 return PUSHPULL(P32, 0);
     457                 :          0 :         case NFP_CPP_ID(0, 9, 0): /* ring_get */
     458                 :          0 :                 return PUSHPULL(0, P32);
     459                 :          0 :         case NFP_CPP_ID(0, 9, 1): /* ring_pop */
     460                 :          0 :                 return PUSHPULL(0, P32);
     461                 :          0 :         case NFP_CPP_ID(0, 9, 2): /* ring_get_freely */
     462                 :          0 :                 return PUSHPULL(0, P32);
     463                 :          0 :         case NFP_CPP_ID(0, 9, 3): /* ring_pop_freely */
     464                 :          0 :                 return PUSHPULL(0, P32);
     465                 :            :         case NFP_CPP_ID(0, 10, 0): /* ring_put */
     466                 :            :                 return PUSHPULL(P32, 0);
     467                 :            :         case NFP_CPP_ID(0, 10, 2): /* ring_journal */
     468                 :            :                 return PUSHPULL(P32, 0);
     469                 :            :         case NFP_CPP_ID(0, 14, 0): /* reflect_write_sig_local */
     470                 :            :                 return PUSHPULL(P32, 0);
     471                 :          0 :         case NFP_CPP_ID(0, 15, 1):  /* reflect_read_sig_local */
     472                 :          0 :                 return PUSHPULL(0, P32);
     473                 :            :         case NFP_CPP_ID(0, 17, 2): /* statistic */
     474                 :            :                 return PUSHPULL(P32, 0);
     475                 :          0 :         case NFP_CPP_ID(0, 24, 0): /* ring_read */
     476                 :          0 :                 return PUSHPULL(0, P32);
     477                 :            :         case NFP_CPP_ID(0, 24, 1): /* ring_write */
     478                 :            :                 return PUSHPULL(P32, 0);
     479                 :          0 :         case NFP_CPP_ID(0, 25, 0): /* ring_workq_add_thread */
     480                 :          0 :                 return PUSHPULL(0, P32);
     481                 :            :         case NFP_CPP_ID(0, 25, 1): /* ring_workq_add_work */
     482                 :            :                 return PUSHPULL(P32, 0);
     483                 :            :         default:
     484                 :            :                 return target_rw(cpp_id, P32, 0, 64);
     485                 :            :         }
     486                 :            : }
     487                 :            : 
     488                 :            : int
     489   [ #  #  #  #  :          0 : nfp_target_pushpull(uint32_t cpp_id,
          #  #  #  #  #  
                   #  # ]
     490                 :            :                 uint64_t address)
     491                 :            : {
     492   [ #  #  #  #  :          0 :         switch (NFP_CPP_ID_TARGET_of(cpp_id)) {
          #  #  #  #  #  
                   #  # ]
     493                 :          0 :         case NFP_CPP_TARGET_NBI:
     494                 :          0 :                 return nfp6000_nbi(cpp_id, address);
     495                 :            :         case NFP_CPP_TARGET_QDR:
     496                 :            :                 return target_rw(cpp_id, P32, 24, 4);
     497                 :          0 :         case NFP_CPP_TARGET_ILA:
     498                 :          0 :                 return nfp6000_ila(cpp_id);
     499                 :          0 :         case NFP_CPP_TARGET_MU:
     500                 :          0 :                 return nfp6000_mu(cpp_id, address);
     501                 :          0 :         case NFP_CPP_TARGET_PCIE:
     502                 :          0 :                 return nfp6000_pci(cpp_id);
     503                 :          0 :         case NFP_CPP_TARGET_ARM:
     504         [ #  # ]:          0 :                 if (address < 0x10000)
     505                 :          0 :                         return target_rw(cpp_id, P64, 1, 1);
     506                 :            :                 else
     507                 :          0 :                         return target_rw(cpp_id, P32, 1, 1);
     508                 :          0 :         case NFP_CPP_TARGET_CRYPTO:
     509                 :          0 :                 return nfp6000_crypto(cpp_id);
     510                 :          0 :         case NFP_CPP_TARGET_CT_XPB:
     511                 :          0 :                 return nfp6000_cap_xpb(cpp_id);
     512                 :          0 :         case NFP_CPP_TARGET_CLS:
     513                 :          0 :                 return nfp6000_cls(cpp_id);
     514                 :            :         case NFP_CPP_TARGET_INVALID:
     515                 :            :                 return target_rw(cpp_id, P32, 4, 4);
     516                 :            :         default:
     517                 :            :                 return -EINVAL;
     518                 :            :         }
     519                 :            : }
     520                 :            : 
     521                 :            : static uint64_t
     522                 :            : nfp_mask64(int msb,
     523                 :            :                 int lsb)
     524                 :            : {
     525                 :            :         int width;
     526                 :            : 
     527         [ #  # ]:          0 :         if (msb < 0 || lsb < 0)
     528                 :            :                 return 0;
     529                 :            : 
     530                 :          0 :         width = msb - lsb + 1;
     531         [ #  # ]:          0 :         if (width <= 0)
     532                 :            :                 return 0;
     533                 :            : 
     534         [ #  # ]:          0 :         if (width == 64)
     535                 :            :                 return ~(uint64_t)0;
     536                 :            : 
     537         [ #  # ]:          0 :         if ((lsb + width) > 64)
     538                 :            :                 return 0;
     539                 :            : 
     540                 :          0 :         return (RTE_BIT64(width) - 1) << lsb;
     541                 :            : }
     542                 :            : 
     543                 :            : static int
     544                 :          0 : nfp_decode_basic(uint64_t addr,
     545                 :            :                 int *dest_island,
     546                 :            :                 int cpp_tgt,
     547                 :            :                 int mode,
     548                 :            :                 int addr40,
     549                 :            :                 int isld1,
     550                 :            :                 int isld0)
     551                 :            : {
     552                 :            :         int iid_lsb;
     553                 :            :         int idx_lsb;
     554                 :            : 
     555                 :            :         /* This function doesn't handle MU or CTXBP */
     556         [ #  # ]:          0 :         if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
     557                 :            :                 return -EINVAL;
     558                 :            : 
     559   [ #  #  #  #  :          0 :         switch (mode) {
                      # ]
     560                 :          0 :         case 0:
     561                 :            :                 /*
     562                 :            :                  * For VQDR, in this mode for 32-bit addressing it would be
     563                 :            :                  * islands 0, 16, 32 and 48 depending on channel and upper
     564                 :            :                  * address bits. Since those are not all valid islands, most
     565                 :            :                  * decode cases would result in bad island IDs, but we do them
     566                 :            :                  * anyway since this is decoding an address that is already
     567                 :            :                  * assumed to be used as-is to get to sram.
     568                 :            :                  */
     569         [ #  # ]:          0 :                 iid_lsb = (addr40) ? 34 : 26;
     570                 :          0 :                 *dest_island = (int)(addr >> iid_lsb) & 0x3F;
     571                 :            : 
     572                 :          0 :                 return 0;
     573                 :          0 :         case 1:
     574                 :            :                 /*
     575                 :            :                  * For VQDR 32-bit, this would decode as:
     576                 :            :                  *      Channel 0: island#0
     577                 :            :                  *      Channel 1: island#0
     578                 :            :                  *      Channel 2: island#1
     579                 :            :                  *      Channel 3: island#1
     580                 :            :                  *
     581                 :            :                  * That would be valid as long as both islands have VQDR.
     582                 :            :                  * Let's allow this.
     583                 :            :                  */
     584         [ #  # ]:          0 :                 idx_lsb = (addr40) ? 39 : 31;
     585         [ #  # ]:          0 :                 if ((addr & nfp_mask64(idx_lsb, idx_lsb)) != 0)
     586                 :          0 :                         *dest_island = isld1;
     587                 :            :                 else
     588                 :          0 :                         *dest_island = isld0;
     589                 :            : 
     590                 :            :                 return 0;
     591                 :          0 :         case 2:
     592                 :            :                 /*
     593                 :            :                  * For VQDR 32-bit:
     594                 :            :                  *      Channel 0: (island#0 | 0)
     595                 :            :                  *      Channel 1: (island#0 | 1)
     596                 :            :                  *      Channel 2: (island#1 | 0)
     597                 :            :                  *      Channel 3: (island#1 | 1)
     598                 :            :                  *
     599                 :            :                  * Make sure we compare against isldN values by clearing the
     600                 :            :                  * LSB. This is what the silicon does.
     601                 :            :                  */
     602                 :          0 :                 isld0 &= ~1;
     603                 :          0 :                 isld1 &= ~1;
     604                 :            : 
     605         [ #  # ]:          0 :                 idx_lsb = (addr40) ? 39 : 31;
     606                 :          0 :                 iid_lsb = idx_lsb - 1;
     607                 :            : 
     608         [ #  # ]:          0 :                 if ((addr & nfp_mask64(idx_lsb, idx_lsb)) != 0)
     609                 :          0 :                         *dest_island = isld1 | (int)((addr >> iid_lsb) & 1);
     610                 :            :                 else
     611                 :          0 :                         *dest_island = isld0 | (int)((addr >> iid_lsb) & 1);
     612                 :            : 
     613                 :            :                 return 0;
     614                 :          0 :         case 3:
     615                 :            :                 /*
     616                 :            :                  * In this mode the data address starts to affect the island ID
     617                 :            :                  * so rather not allow it. In some really specific case one
     618                 :            :                  * could use this to send the upper half of the VQDR channel to
     619                 :            :                  * another MU, but this is getting very specific. However, as
     620                 :            :                  * above for mode 0, this is the decoder and the caller should
     621                 :            :                  * validate the resulting IID. This blindly does what the
     622                 :            :                  * silicon would do.
     623                 :            :                  */
     624                 :          0 :                 isld0 &= ~3;
     625                 :          0 :                 isld1 &= ~3;
     626                 :            : 
     627         [ #  # ]:          0 :                 idx_lsb = (addr40) ? 39 : 31;
     628                 :          0 :                 iid_lsb = idx_lsb - 2;
     629                 :            : 
     630         [ #  # ]:          0 :                 if ((addr & nfp_mask64(idx_lsb, idx_lsb)) != 0)
     631                 :          0 :                         *dest_island = isld1 | (int)((addr >> iid_lsb) & 3);
     632                 :            :                 else
     633                 :          0 :                         *dest_island = isld0 | (int)((addr >> iid_lsb) & 3);
     634                 :            : 
     635                 :            :                 return 0;
     636                 :            :         default:
     637                 :            :                 return -EINVAL;
     638                 :            :         }
     639                 :            : }
     640                 :            : 
     641                 :            : static int
     642                 :            : nfp_encode_basic_qdr(uint64_t addr,
     643                 :            :                 int dest_island,
     644                 :            :                 int cpp_tgt,
     645                 :            :                 int mode,
     646                 :            :                 int addr40,
     647                 :            :                 int isld1,
     648                 :            :                 int isld0)
     649                 :            : {
     650                 :            :         int v;
     651                 :            :         int ret;
     652                 :            : 
     653                 :            :         /* Full Island ID and channel bits overlap? */
     654                 :          0 :         ret = nfp_decode_basic(addr, &v, cpp_tgt, mode, addr40, isld1, isld0);
     655   [ #  #  #  #  :          0 :         if (ret != 0)
             #  #  #  # ]
     656                 :            :                 return ret;
     657                 :            : 
     658                 :            :         /* The current address won't go where expected? */
     659   [ #  #  #  #  :          0 :         if (dest_island != -1 && dest_island != v)
             #  #  #  # ]
     660                 :          0 :                 return -EINVAL;
     661                 :            : 
     662                 :            :         /* If dest_island was -1, we don't care where it goes. */
     663                 :            :         return 0;
     664                 :            : }
     665                 :            : 
     666                 :            : /*
     667                 :            :  * Try each option, take first one that fits.
     668                 :            :  * Not sure if we would want to do some smarter
     669                 :            :  * searching and prefer 0 or non-0 island IDs.
     670                 :            :  */
     671                 :            : static int
     672                 :          0 : nfp_encode_basic_search(uint64_t *addr,
     673                 :            :                 int dest_island,
     674                 :            :                 int *isld,
     675                 :            :                 int iid_lsb,
     676                 :            :                 int idx_lsb,
     677                 :            :                 int v_max)
     678                 :            : {
     679                 :            :         int i;
     680                 :            :         int v;
     681                 :            : 
     682         [ #  # ]:          0 :         for (i = 0; i < 2; i++)
     683         [ #  # ]:          0 :                 for (v = 0; v < v_max; v++) {
     684         [ #  # ]:          0 :                         if (dest_island != (isld[i] | v))
     685                 :            :                                 continue;
     686                 :            : 
     687                 :          0 :                         *addr &= ~nfp_mask64(idx_lsb, iid_lsb);
     688                 :          0 :                         *addr |= ((uint64_t)i << idx_lsb);
     689                 :          0 :                         *addr |= ((uint64_t)v << iid_lsb);
     690                 :          0 :                         return 0;
     691                 :            :                 }
     692                 :            : 
     693                 :            :         return -ENODEV;
     694                 :            : }
     695                 :            : 
     696                 :            : /*
     697                 :            :  * For VQDR, we may not modify the Channel bits, which might overlap
     698                 :            :  * with the Index bit. When it does, we need to ensure that isld0 == isld1.
     699                 :            :  */
     700                 :            : static int
     701                 :          0 : nfp_encode_basic(uint64_t *addr,
     702                 :            :                 int dest_island,
     703                 :            :                 int cpp_tgt,
     704                 :            :                 int mode,
     705                 :            :                 int addr40,
     706                 :            :                 int isld1,
     707                 :            :                 int isld0)
     708                 :            : {
     709                 :            :         int iid_lsb;
     710                 :            :         int idx_lsb;
     711                 :            :         int isld[2];
     712                 :            :         uint64_t value;
     713                 :            : 
     714                 :          0 :         isld[0] = isld0;
     715                 :          0 :         isld[1] = isld1;
     716                 :            : 
     717                 :            :         /* This function doesn't handle MU or CTXBP */
     718         [ #  # ]:          0 :         if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
     719                 :            :                 return -EINVAL;
     720                 :            : 
     721   [ #  #  #  #  :          0 :         switch (mode) {
                      # ]
     722                 :          0 :         case 0:
     723         [ #  # ]:          0 :                 if (cpp_tgt == NFP_CPP_TARGET_QDR && addr40 == 0) {
     724                 :            :                         /*
     725                 :            :                          * In this specific mode we'd rather not modify the
     726                 :            :                          * address but we can verify if the existing contents
     727                 :            :                          * will point to a valid island.
     728                 :            :                          */
     729                 :          0 :                         return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
     730                 :            :                                         mode, addr40, isld1, isld0);
     731                 :            :                 }
     732                 :            : 
     733         [ #  # ]:          0 :                 iid_lsb = (addr40) ? 34 : 26;
     734                 :            : 
     735                 :            :                 /* <39:34> or <31:26> */
     736                 :            :                 value = nfp_mask64((iid_lsb + 5), iid_lsb);
     737                 :          0 :                 *addr &= ~value;
     738                 :          0 :                 *addr |= (((uint64_t)dest_island) << iid_lsb) & value;
     739                 :          0 :                 return 0;
     740                 :          0 :         case 1:
     741         [ #  # ]:          0 :                 if (cpp_tgt == NFP_CPP_TARGET_QDR && addr40 == 0) {
     742                 :          0 :                         return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
     743                 :            :                                         mode, addr40, isld1, isld0);
     744                 :            :                 }
     745                 :            : 
     746         [ #  # ]:          0 :                 idx_lsb = (addr40) ? 39 : 31;
     747         [ #  # ]:          0 :                 if (dest_island == isld0) {
     748                 :            :                         /* Only need to clear the Index bit */
     749                 :          0 :                         *addr &= ~nfp_mask64(idx_lsb, idx_lsb);
     750                 :          0 :                         return 0;
     751                 :            :                 }
     752                 :            : 
     753         [ #  # ]:          0 :                 if (dest_island == isld1) {
     754                 :            :                         /* Only need to set the Index bit */
     755                 :          0 :                         *addr |= (UINT64_C(1) << idx_lsb);
     756                 :          0 :                         return 0;
     757                 :            :                 }
     758                 :            : 
     759                 :            :                 return -ENODEV;
     760                 :          0 :         case 2:
     761         [ #  # ]:          0 :                 if (cpp_tgt == NFP_CPP_TARGET_QDR && addr40 == 0) {
     762                 :            :                         /* iid<0> = addr<30> = channel<0> */
     763                 :            :                         /* channel<1> = addr<31> = Index */
     764                 :          0 :                         return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
     765                 :            :                                         mode, addr40, isld1, isld0);
     766                 :            :                 }
     767                 :            : 
     768                 :            :                 /*
     769                 :            :                  * Make sure we compare against isldN values by clearing the
     770                 :            :                  * LSB. This is what the silicon does.
     771                 :            :                  */
     772                 :          0 :                 isld[0] &= ~1;
     773                 :          0 :                 isld[1] &= ~1;
     774                 :            : 
     775         [ #  # ]:          0 :                 idx_lsb = (addr40) ? 39 : 31;
     776                 :          0 :                 iid_lsb = idx_lsb - 1;
     777                 :            : 
     778                 :          0 :                 return nfp_encode_basic_search(addr, dest_island, isld,
     779                 :            :                                 iid_lsb, idx_lsb, 2);
     780                 :          0 :         case 3:
     781         [ #  # ]:          0 :                 if (cpp_tgt == NFP_CPP_TARGET_QDR && addr40 == 0) {
     782                 :            :                         /*
     783                 :            :                          * iid<0> = addr<29> = data
     784                 :            :                          * iid<1> = addr<30> = channel<0>
     785                 :            :                          * channel<1> = addr<31> = Index
     786                 :            :                          */
     787                 :          0 :                         return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
     788                 :            :                                         mode, addr40, isld1, isld0);
     789                 :            :                 }
     790                 :            : 
     791                 :          0 :                 isld[0] &= ~3;
     792                 :          0 :                 isld[1] &= ~3;
     793                 :            : 
     794         [ #  # ]:          0 :                 idx_lsb = (addr40) ? 39 : 31;
     795                 :          0 :                 iid_lsb = idx_lsb - 2;
     796                 :            : 
     797                 :          0 :                 return nfp_encode_basic_search(addr, dest_island, isld,
     798                 :            :                                 iid_lsb, idx_lsb, 4);
     799                 :            :         default:
     800                 :            :                 return -EINVAL;
     801                 :            :         }
     802                 :            : }
     803                 :            : 
     804                 :            : static int
     805                 :          0 : nfp_encode_mu(uint64_t *addr,
     806                 :            :                 int dest_island,
     807                 :            :                 int mode,
     808                 :            :                 int addr40,
     809                 :            :                 int isld1,
     810                 :            :                 int isld0)
     811                 :            : {
     812                 :            :         int da;
     813                 :            :         int iid_lsb;
     814                 :            :         int idx_lsb;
     815                 :            :         int isld[2];
     816                 :            :         uint64_t value;
     817                 :            :         int locality_lsb;
     818                 :            : 
     819                 :          0 :         isld[0] = isld0;
     820         [ #  # ]:          0 :         isld[1] = isld1;
     821                 :            : 
     822                 :            :         locality_lsb = nfp_cppat_mu_locality_lsb(mode, addr40);
     823                 :            :         if (locality_lsb < 0)
     824                 :            :                 return -EINVAL;
     825                 :            : 
     826         [ #  # ]:          0 :         if (((*addr >> locality_lsb) & 3) == NFP6000_MU_LOCALITY_DIRECT)
     827                 :            :                 da = 1;
     828                 :            :         else
     829                 :            :                 da = 0;
     830                 :            : 
     831   [ #  #  #  # ]:          0 :         switch (mode) {
     832                 :          0 :         case 0:
     833         [ #  # ]:          0 :                 iid_lsb = (addr40 != 0) ? 32 : 24;
     834                 :            :                 value = nfp_mask64((iid_lsb + 5), iid_lsb);
     835                 :          0 :                 *addr &= ~value;
     836                 :          0 :                 *addr |= (((uint64_t)dest_island) << iid_lsb) & value;
     837                 :          0 :                 return 0;
     838                 :          0 :         case 1:
     839         [ #  # ]:          0 :                 if (da == 1) {
     840         [ #  # ]:          0 :                         iid_lsb = (addr40 != 0) ? 32 : 24;
     841                 :            :                         value = nfp_mask64((iid_lsb + 5), iid_lsb);
     842                 :          0 :                         *addr &= ~value;
     843                 :          0 :                         *addr |= (((uint64_t)dest_island) << iid_lsb) & value;
     844                 :          0 :                         return 0;
     845                 :            :                 }
     846                 :            : 
     847         [ #  # ]:          0 :                 idx_lsb = (addr40 != 0) ? 37 : 29;
     848         [ #  # ]:          0 :                 if (dest_island == isld0) {
     849                 :          0 :                         *addr &= ~nfp_mask64(idx_lsb, idx_lsb);
     850                 :          0 :                         return 0;
     851                 :            :                 }
     852                 :            : 
     853         [ #  # ]:          0 :                 if (dest_island == isld1) {
     854                 :          0 :                         *addr |= (UINT64_C(1) << idx_lsb);
     855                 :          0 :                         return 0;
     856                 :            :                 }
     857                 :            : 
     858                 :            :                 return -ENODEV;
     859                 :          0 :         case 2:
     860         [ #  # ]:          0 :                 if (da == 1) {
     861         [ #  # ]:          0 :                         iid_lsb = (addr40 != 0) ? 32 : 24;
     862                 :            :                         value = nfp_mask64((iid_lsb + 5), iid_lsb);
     863                 :          0 :                         *addr &= ~value;
     864                 :          0 :                         *addr |= (((uint64_t)dest_island) << iid_lsb) & value;
     865                 :          0 :                         return 0;
     866                 :            :                 }
     867                 :            : 
     868                 :            :                 /*
     869                 :            :                  * Make sure we compare against isldN values by clearing the
     870                 :            :                  * LSB. This is what the silicon does.
     871                 :            :                  */
     872                 :          0 :                 isld[0] &= ~1;
     873                 :          0 :                 isld[1] &= ~1;
     874                 :            : 
     875         [ #  # ]:          0 :                 idx_lsb = (addr40 != 0) ? 37 : 29;
     876                 :          0 :                 iid_lsb = idx_lsb - 1;
     877                 :            : 
     878                 :          0 :                 return nfp_encode_basic_search(addr, dest_island, isld,
     879                 :            :                                 iid_lsb, idx_lsb, 2);
     880                 :          0 :         case 3:
     881                 :            :                 /*
     882                 :            :                  * Only the EMU will use 40 bit addressing. Silently set the
     883                 :            :                  * direct locality bit for everyone else. The SDK toolchain
     884                 :            :                  * uses dest_island <= 0 to test for atypical address encodings
     885                 :            :                  * to support access to local-island CTM with a 32-but address
     886                 :            :                  * (high-locality is effectively ignored and just used for
     887                 :            :                  * routing to island #0).
     888                 :            :                  */
     889         [ #  # ]:          0 :                 if (dest_island > 0 && (dest_island < 24 || dest_island > 26)) {
     890                 :          0 :                         *addr |= ((uint64_t)NFP6000_MU_LOCALITY_DIRECT)
     891                 :          0 :                                         << locality_lsb;
     892                 :            :                         da = 1;
     893                 :            :                 }
     894                 :            : 
     895         [ #  # ]:          0 :                 if (da == 1) {
     896         [ #  # ]:          0 :                         iid_lsb = (addr40 != 0) ? 32 : 24;
     897                 :            :                         value = nfp_mask64((iid_lsb + 5), iid_lsb);
     898                 :          0 :                         *addr &= ~value;
     899                 :          0 :                         *addr |= (((uint64_t)dest_island) << iid_lsb) & value;
     900                 :          0 :                         return 0;
     901                 :            :                 }
     902                 :            : 
     903                 :          0 :                 isld[0] &= ~3;
     904                 :          0 :                 isld[1] &= ~3;
     905                 :            : 
     906         [ #  # ]:          0 :                 idx_lsb = (addr40 != 0) ? 37 : 29;
     907                 :          0 :                 iid_lsb = idx_lsb - 2;
     908                 :            : 
     909                 :          0 :                 return nfp_encode_basic_search(addr, dest_island, isld,
     910                 :            :                                 iid_lsb, idx_lsb, 4);
     911                 :            :         default:
     912                 :            :                 return -EINVAL;
     913                 :            :         }
     914                 :            : }
     915                 :            : 
     916                 :            : static int
     917                 :          0 : nfp_cppat_addr_encode(uint64_t *addr,
     918                 :            :                 int dest_island,
     919                 :            :                 int cpp_tgt,
     920                 :            :                 int mode,
     921                 :            :                 int addr40,
     922                 :            :                 int isld1,
     923                 :            :                 int isld0)
     924                 :            : {
     925                 :            :         uint64_t value;
     926                 :            : 
     927   [ #  #  #  # ]:          0 :         switch (cpp_tgt) {
     928                 :          0 :         case NFP_CPP_TARGET_NBI:
     929                 :            :         case NFP_CPP_TARGET_QDR:
     930                 :            :         case NFP_CPP_TARGET_ILA:
     931                 :            :         case NFP_CPP_TARGET_PCIE:
     932                 :            :         case NFP_CPP_TARGET_ARM:
     933                 :            :         case NFP_CPP_TARGET_CRYPTO:
     934                 :            :         case NFP_CPP_TARGET_CLS:
     935                 :          0 :                 return nfp_encode_basic(addr, dest_island, cpp_tgt, mode,
     936                 :            :                                 addr40, isld1, isld0);
     937                 :          0 :         case NFP_CPP_TARGET_MU:
     938                 :          0 :                 return nfp_encode_mu(addr, dest_island, mode, addr40,
     939                 :            :                                 isld1, isld0);
     940                 :          0 :         case NFP_CPP_TARGET_CT_XPB:
     941         [ #  # ]:          0 :                 if (mode != 1 || addr40 != 0)
     942                 :            :                         return -EINVAL;
     943                 :            : 
     944                 :            :                 value = nfp_mask64(29, 24);
     945                 :          0 :                 *addr &= ~value;
     946                 :          0 :                 *addr |= (((uint64_t)dest_island) << 24) & value;
     947                 :          0 :                 return 0;
     948                 :            :         default:
     949                 :            :                 return -EINVAL;
     950                 :            :         }
     951                 :            : }
     952                 :            : 
     953                 :            : int
     954         [ #  # ]:          0 : nfp_target_cpp(uint32_t cpp_island_id,
     955                 :            :                 uint64_t cpp_island_address,
     956                 :            :                 uint32_t *cpp_target_id,
     957                 :            :                 uint64_t *cpp_target_address,
     958                 :            :                 const uint32_t *imb_table)
     959                 :            : {
     960                 :            :         int err;
     961                 :            :         uint32_t imb;
     962                 :            :         uint8_t island;
     963                 :            :         uint8_t target;
     964                 :            : 
     965                 :            :         target = NFP_CPP_ID_TARGET_of(cpp_island_id);
     966         [ #  # ]:          0 :         if (target >= 16)
     967                 :            :                 return -EINVAL;
     968                 :            : 
     969                 :            :         island = NFP_CPP_ID_ISLAND_of(cpp_island_id);
     970         [ #  # ]:          0 :         if (island == 0) {
     971                 :            :                 /* Already translated */
     972                 :          0 :                 *cpp_target_id = cpp_island_id;
     973                 :          0 :                 *cpp_target_address = cpp_island_address;
     974                 :          0 :                 return 0;
     975                 :            :         }
     976                 :            : 
     977                 :            :         /* CPP + Island only allowed on systems with IMB tables */
     978         [ #  # ]:          0 :         if (imb_table == NULL)
     979                 :            :                 return -EINVAL;
     980                 :            : 
     981                 :          0 :         imb = imb_table[target];
     982                 :            : 
     983                 :          0 :         *cpp_target_address = cpp_island_address;
     984                 :          0 :         err = nfp_cppat_addr_encode(cpp_target_address, island, target,
     985                 :          0 :                         ((imb >> 13) & 7), ((imb >> 12) & 1),
     986                 :          0 :                         ((imb >> 6) & 0x3f), ((imb >> 0) & 0x3f));
     987         [ #  # ]:          0 :         if (err != 0)
     988                 :            :                 return err;
     989                 :            : 
     990                 :          0 :         *cpp_target_id = NFP_CPP_ID(target,
     991                 :            :                         NFP_CPP_ID_ACTION_of(cpp_island_id),
     992                 :            :                         NFP_CPP_ID_TOKEN_of(cpp_island_id));
     993                 :            : 
     994                 :          0 :         return 0;
     995                 :            : }

Generated by: LCOV version 1.14