LCOV - code coverage report
Current view: top level - drivers/net/ntnic/nthw - nthw_rac.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 387 0.0 %
Date: 2025-04-03 19:37:06 Functions: 0 18 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 140 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * SPDX-License-Identifier: BSD-3-Clause
       3                 :            :  * Copyright(c) 2023 Napatech A/S
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "rte_spinlock.h"
       7                 :            : #include "nt_util.h"
       8                 :            : #include "ntlog.h"
       9                 :            : 
      10                 :            : #include "nthw_drv.h"
      11                 :            : #include "nthw_register.h"
      12                 :            : #include "nthw_rac.h"
      13                 :            : 
      14                 :            : #define RAB_DMA_WAIT (1000000)
      15                 :            : 
      16                 :            : #define RAB_READ (0x01)
      17                 :            : #define RAB_WRITE (0x02)
      18                 :            : #define RAB_ECHO (0x08)
      19                 :            : #define RAB_COMPLETION (0x0F)
      20                 :            : 
      21                 :            : #define RAB_OPR_LO (28)
      22                 :            : 
      23                 :            : #define RAB_CNT_LO (20)
      24                 :            : #define RAB_CNT_BW (8)
      25                 :            : 
      26                 :            : #define RAB_BUSID_LO (16)
      27                 :            : #define RAB_BUSID_BW (4)
      28                 :            : 
      29                 :            : #define RAB_ADDR_BW (16)
      30                 :            : 
      31                 :          0 : nthw_rac_t *nthw_rac_new(void)
      32                 :            : {
      33                 :          0 :         nthw_rac_t *p = malloc(sizeof(nthw_rac_t));
      34                 :            : 
      35         [ #  # ]:          0 :         if (p)
      36                 :            :                 memset(p, 0, sizeof(nthw_rac_t));
      37                 :            : 
      38                 :          0 :         return p;
      39                 :            : }
      40                 :            : 
      41                 :          0 : int nthw_rac_init(nthw_rac_t *p, nthw_fpga_t *p_fpga, struct fpga_info_s *p_fpga_info)
      42                 :            : {
      43                 :            :         RTE_ASSERT(p_fpga_info);
      44                 :            : 
      45                 :          0 :         const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
      46                 :          0 :         nthw_module_t *p_mod = nthw_fpga_query_module(p_fpga, MOD_RAC, 0);
      47                 :            : 
      48         [ #  # ]:          0 :         if (p == NULL)
      49         [ #  # ]:          0 :                 return p_mod == NULL ? -1 : 0;
      50                 :            : 
      51         [ #  # ]:          0 :         if (p_mod == NULL) {
      52                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAC %d: no such instance", p_adapter_id_str, 0);
      53                 :          0 :                 return -1;
      54                 :            :         }
      55                 :            : 
      56                 :          0 :         p->mp_fpga = p_fpga;
      57                 :          0 :         p->mp_mod_rac = p_mod;
      58                 :            : 
      59                 :          0 :         p->mn_param_rac_rab_interfaces =
      60                 :          0 :                 nthw_fpga_get_product_param(p->mp_fpga, NT_RAC_RAB_INTERFACES, 3);
      61                 :          0 :         NT_LOG(DBG, NTHW, "%s: NT_RAC_RAB_INTERFACES=%d", p_adapter_id_str,
      62                 :            :                 p->mn_param_rac_rab_interfaces);
      63                 :            : 
      64                 :          0 :         p->mn_param_rac_rab_ob_update =
      65                 :          0 :                 nthw_fpga_get_product_param(p->mp_fpga, NT_RAC_RAB_OB_UPDATE, 0);
      66                 :          0 :         NT_LOG(DBG, NTHW, "%s: NT_RAC_RAB_OB_UPDATE=%d", p_adapter_id_str,
      67                 :            :                 p->mn_param_rac_rab_ob_update);
      68                 :            : 
      69                 :            :         /* Optional dummy test registers */
      70                 :          0 :         p->mp_reg_dummy0 = nthw_module_query_register(p->mp_mod_rac, RAC_DUMMY0);
      71                 :          0 :         p->mp_reg_dummy1 = nthw_module_query_register(p->mp_mod_rac, RAC_DUMMY1);
      72                 :          0 :         p->mp_reg_dummy2 = nthw_module_query_register(p->mp_mod_rac, RAC_DUMMY2);
      73                 :            : 
      74                 :          0 :         p->mp_reg_rab_init = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_INIT);
      75                 :          0 :         p->mp_fld_rab_init = nthw_register_get_field(p->mp_reg_rab_init, RAC_RAB_INIT_RAB);
      76                 :          0 :         p->mn_fld_rab_init_bw = nthw_field_get_bit_width(p->mp_fld_rab_init);
      77                 :          0 :         p->mn_fld_rab_init_mask = nthw_field_get_mask(p->mp_fld_rab_init);
      78                 :            : 
      79                 :            :         /* RAC_RAB_INIT_RAB reg/field sanity checks: */
      80                 :            :         RTE_ASSERT(p->mn_fld_rab_init_mask == ((1UL << p->mn_fld_rab_init_bw) - 1));
      81                 :            :         RTE_ASSERT(p->mn_fld_rab_init_bw == p->mn_param_rac_rab_interfaces);
      82                 :            : 
      83                 :          0 :         p->mp_reg_dbg_ctrl = nthw_module_query_register(p->mp_mod_rac, RAC_DBG_CTRL);
      84                 :            : 
      85         [ #  # ]:          0 :         if (p->mp_reg_dbg_ctrl)
      86                 :          0 :                 p->mp_fld_dbg_ctrl = nthw_register_query_field(p->mp_reg_dbg_ctrl, RAC_DBG_CTRL_C);
      87                 :            : 
      88                 :            :         else
      89                 :          0 :                 p->mp_fld_dbg_ctrl = NULL;
      90                 :            : 
      91                 :          0 :         p->mp_reg_dbg_data = nthw_module_query_register(p->mp_mod_rac, RAC_DBG_DATA);
      92                 :            : 
      93         [ #  # ]:          0 :         if (p->mp_reg_dbg_data)
      94                 :          0 :                 p->mp_fld_dbg_data = nthw_register_query_field(p->mp_reg_dbg_data, RAC_DBG_DATA_D);
      95                 :            : 
      96                 :            :         else
      97                 :          0 :                 p->mp_reg_dbg_data = NULL;
      98                 :            : 
      99                 :          0 :         p->mp_reg_rab_ib_data = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_IB_DATA);
     100                 :          0 :         p->mp_fld_rab_ib_data = nthw_register_get_field(p->mp_reg_rab_ib_data, RAC_RAB_IB_DATA_D);
     101                 :            : 
     102                 :          0 :         p->mp_reg_rab_ob_data = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_OB_DATA);
     103                 :          0 :         p->mp_fld_rab_ob_data = nthw_register_get_field(p->mp_reg_rab_ob_data, RAC_RAB_OB_DATA_D);
     104                 :            : 
     105                 :          0 :         p->mp_reg_rab_buf_free = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_BUF_FREE);
     106                 :          0 :         p->mp_fld_rab_buf_free_ib_free =
     107                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_buf_free, RAC_RAB_BUF_FREE_IB_FREE);
     108                 :          0 :         p->mp_fld_rab_buf_free_ib_ovf =
     109                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_buf_free, RAC_RAB_BUF_FREE_IB_OVF);
     110                 :          0 :         p->mp_fld_rab_buf_free_ob_free =
     111                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_buf_free, RAC_RAB_BUF_FREE_OB_FREE);
     112                 :          0 :         p->mp_fld_rab_buf_free_ob_ovf =
     113                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_buf_free, RAC_RAB_BUF_FREE_OB_OVF);
     114                 :          0 :         p->mp_fld_rab_buf_free_timeout =
     115                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_buf_free, RAC_RAB_BUF_FREE_TIMEOUT);
     116                 :            : 
     117                 :          0 :         p->mp_reg_rab_buf_used = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_BUF_USED);
     118                 :          0 :         p->mp_fld_rab_buf_used_ib_used =
     119                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_buf_used, RAC_RAB_BUF_USED_IB_USED);
     120                 :          0 :         p->mp_fld_rab_buf_used_ob_used =
     121                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_buf_used, RAC_RAB_BUF_USED_OB_USED);
     122                 :          0 :         p->mp_fld_rab_buf_used_flush =
     123                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_buf_used, RAC_RAB_BUF_USED_FLUSH);
     124                 :            : 
     125                 :            :         /*
     126                 :            :          * RAC_RAB_DMA regs are optional - only found in real
     127                 :            :          * NT4GA - not found in 9231/9232 and earlier
     128                 :            :          */
     129                 :          0 :         p->mp_reg_rab_dma_ib_lo = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_DMA_IB_LO);
     130                 :          0 :         p->mp_fld_rab_dma_ib_lo_phy_addr =
     131                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_dma_ib_lo, RAC_RAB_DMA_IB_LO_PHYADDR);
     132                 :            : 
     133                 :          0 :         p->mp_reg_rab_dma_ib_hi = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_DMA_IB_HI);
     134                 :          0 :         p->mp_fld_rab_dma_ib_hi_phy_addr =
     135                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_dma_ib_hi, RAC_RAB_DMA_IB_HI_PHYADDR);
     136                 :            : 
     137                 :          0 :         p->mp_reg_rab_dma_ob_lo = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_DMA_OB_LO);
     138                 :          0 :         p->mp_fld_rab_dma_ob_lo_phy_addr =
     139                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_dma_ob_lo, RAC_RAB_DMA_OB_LO_PHYADDR);
     140                 :            : 
     141                 :          0 :         p->mp_reg_rab_dma_ob_hi = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_DMA_OB_HI);
     142                 :          0 :         p->mp_fld_rab_dma_ob_hi_phy_addr =
     143                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_dma_ob_hi, RAC_RAB_DMA_OB_HI_PHYADDR);
     144                 :            : 
     145                 :          0 :         p->mp_reg_rab_dma_ib_wr = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_DMA_IB_WR);
     146                 :          0 :         p->mp_fld_rab_dma_ib_wr_ptr =
     147                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_dma_ib_wr, RAC_RAB_DMA_IB_WR_PTR);
     148                 :            : 
     149                 :          0 :         p->mp_reg_rab_dma_ib_rd = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_DMA_IB_RD);
     150                 :          0 :         p->mp_fld_rab_dma_ib_rd_ptr =
     151                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_dma_ib_rd, RAC_RAB_DMA_IB_RD_PTR);
     152                 :            : 
     153                 :          0 :         p->mp_reg_rab_dma_ob_wr = nthw_module_get_register(p->mp_mod_rac, RAC_RAB_DMA_OB_WR);
     154                 :          0 :         p->mp_fld_rab_dma_ob_wr_ptr =
     155                 :          0 :                 nthw_register_get_field(p->mp_reg_rab_dma_ob_wr, RAC_RAB_DMA_OB_WR_PTR);
     156                 :            : 
     157                 :          0 :         p->RAC_RAB_INIT_ADDR = nthw_register_get_address(p->mp_reg_rab_init);
     158                 :          0 :         p->RAC_RAB_IB_DATA_ADDR = nthw_register_get_address(p->mp_reg_rab_ib_data);
     159                 :          0 :         p->RAC_RAB_OB_DATA_ADDR = nthw_register_get_address(p->mp_reg_rab_ob_data);
     160                 :          0 :         p->RAC_RAB_BUF_FREE_ADDR = nthw_register_get_address(p->mp_reg_rab_buf_free);
     161                 :          0 :         p->RAC_RAB_BUF_USED_ADDR = nthw_register_get_address(p->mp_reg_rab_buf_used);
     162                 :            : 
     163                 :            :         /*
     164                 :            :          * RAC_RAB_DMA regs are optional - only found in real NT4GA - not found in 9231/9232 and
     165                 :            :          * earlier
     166                 :            :          */
     167                 :            : 
     168                 :          0 :         p->RAC_RAB_DMA_IB_LO_ADDR = nthw_register_get_address(p->mp_reg_rab_dma_ib_lo);
     169                 :          0 :         p->RAC_RAB_DMA_IB_HI_ADDR = nthw_register_get_address(p->mp_reg_rab_dma_ib_hi);
     170                 :          0 :         p->RAC_RAB_DMA_OB_LO_ADDR = nthw_register_get_address(p->mp_reg_rab_dma_ob_lo);
     171                 :          0 :         p->RAC_RAB_DMA_OB_HI_ADDR = nthw_register_get_address(p->mp_reg_rab_dma_ob_hi);
     172                 :          0 :         p->RAC_RAB_DMA_IB_RD_ADDR = nthw_register_get_address(p->mp_reg_rab_dma_ib_rd);
     173                 :          0 :         p->RAC_RAB_DMA_OB_WR_ADDR = nthw_register_get_address(p->mp_reg_rab_dma_ob_wr);
     174                 :          0 :         p->RAC_RAB_DMA_IB_WR_ADDR = nthw_register_get_address(p->mp_reg_rab_dma_ib_wr);
     175                 :            : 
     176                 :          0 :         p->RAC_RAB_BUF_FREE_IB_FREE_MASK = nthw_field_get_mask(p->mp_fld_rab_buf_free_ib_free);
     177                 :          0 :         p->RAC_RAB_BUF_FREE_OB_FREE_MASK = nthw_field_get_mask(p->mp_fld_rab_buf_free_ob_free);
     178                 :          0 :         p->RAC_RAB_BUF_USED_IB_USED_MASK = nthw_field_get_mask(p->mp_fld_rab_buf_used_ib_used);
     179                 :          0 :         p->RAC_RAB_BUF_USED_OB_USED_MASK = nthw_field_get_mask(p->mp_fld_rab_buf_used_ob_used);
     180                 :            : 
     181                 :          0 :         p->RAC_RAB_BUF_USED_FLUSH_MASK = nthw_field_get_mask(p->mp_fld_rab_buf_used_flush);
     182                 :            : 
     183                 :          0 :         p->RAC_RAB_BUF_USED_OB_USED_LOW =
     184                 :          0 :                 nthw_field_get_bit_pos_low(p->mp_fld_rab_buf_used_ob_used);
     185                 :            : 
     186                 :          0 :         p->mp_reg_rab_nmb_rd = nthw_module_query_register(p->mp_mod_rac, RAC_NMB_RD_ADR);
     187                 :            : 
     188         [ #  # ]:          0 :         if (p->mp_reg_rab_nmb_rd)
     189                 :          0 :                 p->RAC_NMB_RD_ADR_ADDR = nthw_register_get_address(p->mp_reg_rab_nmb_rd);
     190                 :            : 
     191                 :          0 :         p->mp_reg_rab_nmb_data = nthw_module_query_register(p->mp_mod_rac, RAC_NMB_DATA);
     192                 :            : 
     193         [ #  # ]:          0 :         if (p->mp_reg_rab_nmb_data)
     194                 :          0 :                 p->RAC_NMB_DATA_ADDR = nthw_register_get_address(p->mp_reg_rab_nmb_data);
     195                 :            : 
     196                 :          0 :         p->mp_reg_rab_nmb_wr = nthw_module_query_register(p->mp_mod_rac, RAC_NMB_WR_ADR);
     197                 :            : 
     198         [ #  # ]:          0 :         if (p->mp_reg_rab_nmb_wr)
     199                 :          0 :                 p->RAC_NMB_WR_ADR_ADDR = nthw_register_get_address(p->mp_reg_rab_nmb_wr);
     200                 :            : 
     201                 :          0 :         p->mp_reg_rab_nmb_status = nthw_module_query_register(p->mp_mod_rac, RAC_NMB_STATUS);
     202                 :            : 
     203         [ #  # ]:          0 :         if (p->mp_reg_rab_nmb_status)
     204                 :          0 :                 p->RAC_NMB_STATUS_ADDR = nthw_register_get_address(p->mp_reg_rab_nmb_status);
     205                 :            : 
     206                 :          0 :         p->m_dma = NULL;
     207                 :            : 
     208                 :            :         {
     209                 :            :                 /*
     210                 :            :                  * RAC is a primary communication channel - debug will be messy
     211                 :            :                  * turn off debug by default - except for rac_rab_init
     212                 :            :                  * NOTE: currently debug will not work - due to optimizations
     213                 :            :                  */
     214                 :          0 :                 const int n_debug_mode = nthw_module_get_debug_mode(p->mp_mod_rac);
     215                 :            : 
     216         [ #  # ]:          0 :                 if (n_debug_mode && n_debug_mode <= 0xff) {
     217                 :          0 :                         nthw_module_set_debug_mode(p->mp_mod_rac, 0);
     218                 :          0 :                         nthw_register_set_debug_mode(p->mp_reg_rab_init, n_debug_mode);
     219                 :            :                 }
     220                 :            :         }
     221                 :            : 
     222                 :            :         rte_spinlock_init(&p->m_mutex);
     223                 :            : 
     224                 :          0 :         return 0;
     225                 :            : }
     226                 :            : 
     227                 :            : static int nthw_rac_get_rab_interface_count(const nthw_rac_t *p)
     228                 :            : {
     229                 :          0 :         return p->mn_param_rac_rab_interfaces;
     230                 :            : }
     231                 :            : 
     232                 :            : /* private function for internal RAC operations -
     233                 :            :  * improves log flexibility and prevents log flooding
     234                 :            :  */
     235                 :            : static void nthw_rac_reg_read32(const struct fpga_info_s *p_fpga_info, uint32_t reg_addr,
     236                 :            :         uint32_t *p_data)
     237                 :            : {
     238                 :          0 :         *p_data = *(volatile uint32_t *)((uint8_t *)p_fpga_info->bar0_addr + reg_addr);
     239                 :            : }
     240                 :            : 
     241                 :            : /* private function for internal RAC operations -
     242                 :            :  * improves log flexibility and prevents log flooding
     243                 :            :  */
     244                 :            : static void nthw_rac_reg_write32(const struct fpga_info_s *p_fpga_info, uint32_t reg_addr,
     245                 :            :         uint32_t n_data)
     246                 :            : {
     247                 :          0 :         *(volatile uint32_t *)((uint8_t *)p_fpga_info->bar0_addr + reg_addr) = n_data;
     248                 :          0 : }
     249                 :            : 
     250                 :          0 : static inline int _nthw_rac_wait_for_rab_done(const nthw_rac_t *p, uint32_t address,
     251                 :            :         uint32_t word_cnt)
     252                 :            : {
     253                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     254                 :          0 :         const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
     255                 :            :         uint32_t used = 0;
     256                 :            :         uint32_t retry;
     257                 :            : 
     258         [ #  # ]:          0 :         for (retry = 0; retry < 100000; retry++) {
     259                 :          0 :                 nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_BUF_USED_ADDR, &used);
     260                 :          0 :                 used = (used & p->RAC_RAB_BUF_USED_OB_USED_MASK) >>
     261                 :          0 :                         p->RAC_RAB_BUF_USED_OB_USED_LOW;
     262                 :            : 
     263         [ #  # ]:          0 :                 if (used >= word_cnt)
     264                 :            :                         break;
     265                 :            :         }
     266                 :            : 
     267         [ #  # ]:          0 :         if (used < word_cnt) {
     268                 :          0 :                 NT_LOG(ERR, NTHW, "%s: Fail rab bus r/w addr=0x%08X used=%x wordcount=%d",
     269                 :            :                         p_adapter_id_str, address, used, word_cnt);
     270                 :          0 :                 return -1;
     271                 :            :         }
     272                 :            : 
     273                 :            :         return 0;
     274                 :            : }
     275                 :            : 
     276                 :            : /*
     277                 :            :  * NT_PCI_REG_P9xyz_RAC_RAB_INIT
     278                 :            :  *
     279                 :            :  * Initializes (resets) the programmable registers on the Register Access Buses (RAB).
     280                 :            :  * This initialization must be performed by software as part of the driver load procedure.
     281                 :            :  *
     282                 :            :  * Bit n of this field initializes the programmable registers on RAB interface n.
     283                 :            :  * Software must write one to the bit and then clear the bit again.
     284                 :            :  *
     285                 :            :  * All RAB module registers will be reset to their defaults.
     286                 :            :  * This includes the product specific RESET module (eg RST9xyz)
     287                 :            :  * As a consequence of this behavior the official reset sequence
     288                 :            :  * must be excersised - as all RAB modules will be held in reset.
     289                 :            :  */
     290                 :          0 : int nthw_rac_rab_init(nthw_rac_t *p, uint32_t n_rab_intf_mask)
     291                 :            : {
     292                 :            :         /*
     293                 :            :          * Write rac_rab_init
     294                 :            :          * Perform operation twice - first to get trace of operation -
     295                 :            :          * second to get things done...
     296                 :            :          */
     297                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     298                 :          0 :         nthw_field_set_val_flush32(p->mp_fld_rab_init, n_rab_intf_mask);
     299                 :          0 :         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_INIT_ADDR, n_rab_intf_mask);
     300                 :          0 :         return 0;
     301                 :            : }
     302                 :            : 
     303                 :          0 : int nthw_rac_rab_reset(nthw_rac_t *p)
     304                 :            : {
     305                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     306                 :          0 :         const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
     307                 :            :         (void)p_adapter_id_str;
     308                 :            : 
     309                 :            :         /* RAC RAB bus "flip/flip" reset */
     310                 :            :         const int n_rac_rab_bus_count = nthw_rac_get_rab_interface_count(p);
     311                 :          0 :         const int n_rac_rab_bus_mask = (1 << n_rac_rab_bus_count) - 1;
     312                 :            : 
     313                 :          0 :         NT_LOG(DBG, NTHW, "%s: NT_RAC_RAB_INTERFACES=%d (0x%02X)", p_adapter_id_str,
     314                 :            :                 n_rac_rab_bus_count, n_rac_rab_bus_mask);
     315                 :            :         RTE_ASSERT(n_rac_rab_bus_count);
     316                 :            :         RTE_ASSERT(n_rac_rab_bus_mask);
     317                 :            : 
     318                 :            :         /* RAC RAB bus "flip/flip" reset first stage - new impl (ref RMT#37020) */
     319                 :          0 :         nthw_rac_rab_init(p, 0);
     320                 :          0 :         nthw_rac_rab_init(p, n_rac_rab_bus_mask);
     321                 :          0 :         nthw_rac_rab_init(p, n_rac_rab_bus_mask & ~0x01);
     322                 :            : 
     323                 :          0 :         return 0;
     324                 :            : }
     325                 :            : 
     326                 :          0 : int nthw_rac_rab_setup(nthw_rac_t *p)
     327                 :            : {
     328                 :            :         int rc = 0;
     329                 :            : 
     330                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     331                 :            :         uint32_t n_dma_buf_size = 2L * RAB_DMA_BUF_CNT * sizeof(uint32_t);
     332                 :          0 :         const size_t align_size = nt_util_align_size(n_dma_buf_size);
     333                 :          0 :         int numa_node = p_fpga_info->numa_node;
     334                 :            :         uint64_t dma_addr;
     335                 :            :         uint32_t buf;
     336                 :            : 
     337         [ #  # ]:          0 :         if (!p->m_dma) {
     338                 :            :                 struct nt_dma_s *vfio_dma;
     339                 :            :                 /* FPGA needs Page alignment (4K) */
     340                 :          0 :                 vfio_dma = nt_dma_alloc(align_size, 0x1000, numa_node);
     341                 :            : 
     342         [ #  # ]:          0 :                 if (vfio_dma == NULL) {
     343                 :          0 :                         NT_LOG(ERR, NTNIC, "nt_dma_alloc failed");
     344                 :          0 :                         return -1;
     345                 :            :                 }
     346                 :            : 
     347                 :          0 :                 p->m_dma_in_buf = (uint32_t *)vfio_dma->addr;
     348                 :          0 :                 p->m_dma_out_buf = p->m_dma_in_buf + RAB_DMA_BUF_CNT;
     349                 :          0 :                 p->m_dma = vfio_dma;
     350                 :            :         }
     351                 :            : 
     352                 :            :         /* Setup DMA on the adapter */
     353                 :          0 :         dma_addr = p->m_dma->iova;
     354                 :          0 :         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_DMA_IB_LO_ADDR, dma_addr & 0xffffffff);
     355                 :          0 :         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_DMA_IB_HI_ADDR,
     356                 :          0 :                 (uint32_t)(dma_addr >> 32) & 0xffffffff);
     357                 :          0 :         dma_addr += RAB_DMA_BUF_CNT * sizeof(uint32_t);
     358                 :          0 :         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_DMA_OB_LO_ADDR, dma_addr & 0xffffffff);
     359                 :          0 :         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_DMA_OB_HI_ADDR,
     360                 :          0 :                 (uint32_t)(dma_addr >> 32) & 0xffffffff);
     361                 :            : 
     362                 :            :         /* Set initial value of internal pointers */
     363                 :          0 :         nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_DMA_IB_RD_ADDR, &buf);
     364                 :          0 :         p->m_dma_in_ptr_wr = (uint16_t)(buf / sizeof(uint32_t));
     365                 :          0 :         nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_DMA_OB_WR_ADDR, &buf);
     366                 :          0 :         p->m_dma_out_ptr_rd = (uint16_t)(buf / sizeof(uint32_t));
     367                 :          0 :         p->m_in_free = RAB_DMA_BUF_CNT;
     368                 :            : 
     369                 :          0 :         return rc;
     370                 :            : }
     371                 :            : 
     372                 :          0 : void nthw_rac_bar0_read32(const struct fpga_info_s *p_fpga_info, uint32_t reg_addr,
     373                 :            :         uint32_t word_cnt, uint32_t *p_data)
     374                 :            : {
     375                 :            :         volatile const uint32_t *const src_addr =
     376                 :          0 :                 (uint32_t *)((uint8_t *)p_fpga_info->bar0_addr + reg_addr);
     377                 :            : 
     378         [ #  # ]:          0 :         for (uint32_t i = 0; i < word_cnt; i++)
     379                 :          0 :                 p_data[i] = src_addr[i];
     380                 :          0 : }
     381                 :            : 
     382                 :          0 : void nthw_rac_bar0_write32(const struct fpga_info_s *p_fpga_info, uint32_t reg_addr,
     383                 :            :         uint32_t word_cnt, const uint32_t *p_data)
     384                 :            : {
     385                 :            :         volatile uint32_t *const dst_addr =
     386                 :          0 :                 (uint32_t *)((uint8_t *)p_fpga_info->bar0_addr + reg_addr);
     387                 :            : 
     388         [ #  # ]:          0 :         for (uint32_t i = 0; i < word_cnt; i++)
     389                 :          0 :                 dst_addr[i] = p_data[i];
     390                 :          0 : }
     391                 :            : 
     392                 :          0 : int nthw_rac_rab_dma_begin(nthw_rac_t *p)
     393                 :            : {
     394                 :          0 :         p->m_dma_active = true;
     395                 :            : 
     396                 :          0 :         return 0;
     397                 :            : }
     398                 :            : 
     399                 :          0 : static void nthw_rac_rab_dma_activate(nthw_rac_t *p)
     400                 :            : {
     401                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     402                 :            :         const uint32_t completion = RAB_COMPLETION << RAB_OPR_LO;
     403                 :            : 
     404                 :            :         /* Write completion word */
     405                 :          0 :         p->m_dma_in_buf[p->m_dma_in_ptr_wr] = completion;
     406                 :          0 :         p->m_dma_in_ptr_wr = (uint16_t)((p->m_dma_in_ptr_wr + 1) & (RAB_DMA_BUF_CNT - 1));
     407                 :            : 
     408                 :            :         /* Clear output completion word */
     409                 :          0 :         p->m_dma_out_buf[p->m_dma_out_ptr_rd] = 0;
     410                 :            : 
     411                 :            :         /* Update DMA pointer and start transfer */
     412                 :          0 :         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_DMA_IB_WR_ADDR,
     413                 :          0 :                 (uint32_t)(p->m_dma_in_ptr_wr * sizeof(uint32_t)));
     414                 :          0 : }
     415                 :            : 
     416                 :          0 : static int nthw_rac_rab_dma_wait(nthw_rac_t *p)
     417                 :            : {
     418                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     419                 :          0 :         const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
     420                 :            :         const uint32_t completion = RAB_COMPLETION << RAB_OPR_LO;
     421                 :            :         uint32_t i;
     422                 :            : 
     423         [ #  # ]:          0 :         for (i = 0; i < RAB_DMA_WAIT; i++) {
     424                 :          0 :                 nt_os_wait_usec_poll(1);
     425                 :            : 
     426         [ #  # ]:          0 :                 if ((p->m_dma_out_buf[p->m_dma_out_ptr_rd] & completion) == completion)
     427                 :            :                         break;
     428                 :            :         }
     429                 :            : 
     430         [ #  # ]:          0 :         if (i == RAB_DMA_WAIT) {
     431                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Unexpected value of completion (0x%08X)",
     432                 :            :                         p_adapter_id_str, p->m_dma_out_buf[p->m_dma_out_ptr_rd]);
     433                 :          0 :                 return -1;
     434                 :            :         }
     435                 :            : 
     436                 :          0 :         p->m_dma_out_ptr_rd = (uint16_t)((p->m_dma_out_ptr_rd + 1) & (RAB_DMA_BUF_CNT - 1));
     437                 :          0 :         p->m_in_free = RAB_DMA_BUF_CNT;
     438                 :            : 
     439                 :          0 :         return 0;
     440                 :            : }
     441                 :            : 
     442                 :          0 : int nthw_rac_rab_dma_commit(nthw_rac_t *p)
     443                 :            : {
     444                 :            :         int ret;
     445                 :            : 
     446                 :          0 :         nthw_rac_rab_dma_activate(p);
     447                 :          0 :         ret = nthw_rac_rab_dma_wait(p);
     448                 :            : 
     449                 :          0 :         p->m_dma_active = false;
     450                 :            : 
     451                 :          0 :         return ret;
     452                 :            : }
     453                 :            : 
     454                 :          0 : uint32_t nthw_rac_rab_get_free(nthw_rac_t *p)
     455                 :            : {
     456         [ #  # ]:          0 :         if (!p->m_dma_active) {
     457                 :            :                 /* Expecting mutex not to be locked! */
     458                 :            :                 RTE_ASSERT(0);      /* alert developer that something is wrong */
     459                 :            :                 return -1;
     460                 :            :         }
     461                 :            : 
     462                 :          0 :         return p->m_in_free;
     463                 :            : }
     464                 :            : 
     465                 :          0 : int nthw_rac_rab_write32_dma(nthw_rac_t *p, nthw_rab_bus_id_t bus_id, uint32_t address,
     466                 :            :         uint32_t word_cnt, const uint32_t *p_data)
     467                 :            : {
     468                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     469                 :          0 :         const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
     470                 :            : 
     471         [ #  # ]:          0 :         if (word_cnt == 0 || word_cnt > 256) {
     472                 :          0 :                 NT_LOG(ERR, NTHW,
     473                 :            :                         "%s: Failed rab dma write length check - bus: %d addr: 0x%08X wordcount: %d - inBufFree: 0x%08X",
     474                 :            :                         p_adapter_id_str, bus_id, address, word_cnt, p->m_in_free);
     475                 :            :                 RTE_ASSERT(0);      /* alert developer that something is wrong */
     476                 :          0 :                 return -1;
     477                 :            :         }
     478                 :            : 
     479         [ #  # ]:          0 :         if (p->m_in_free < (word_cnt + 3)) {
     480                 :            :                 /*
     481                 :            :                  * No more memory available.
     482                 :            :                  * nthw_rac_rab_dma_commit() needs to be called to start and finish pending
     483                 :            :                  * transfers.
     484                 :            :                  */
     485                 :            :                 return -1;
     486                 :            :         }
     487                 :            : 
     488                 :          0 :         p->m_in_free -= (word_cnt + 1);
     489                 :            : 
     490                 :            :         /* Write the command word */
     491                 :          0 :         p->m_dma_in_buf[p->m_dma_in_ptr_wr] = (RAB_WRITE << RAB_OPR_LO) |
     492                 :          0 :                 ((word_cnt & ((1 << RAB_CNT_BW) - 1)) << RAB_CNT_LO) | (bus_id << RAB_BUSID_LO) |
     493                 :            :                 address;
     494                 :          0 :         p->m_dma_in_ptr_wr = (uint16_t)((p->m_dma_in_ptr_wr + 1) & (RAB_DMA_BUF_CNT - 1));
     495                 :            : 
     496         [ #  # ]:          0 :         for (uint32_t i = 0; i < word_cnt; i++) {
     497                 :          0 :                 p->m_dma_in_buf[p->m_dma_in_ptr_wr] = p_data[i];
     498                 :          0 :                 p->m_dma_in_ptr_wr = (uint16_t)((p->m_dma_in_ptr_wr + 1) & (RAB_DMA_BUF_CNT - 1));
     499                 :            :         }
     500                 :            : 
     501                 :            :         return 0;
     502                 :            : }
     503                 :            : 
     504                 :          0 : int nthw_rac_rab_read32_dma(nthw_rac_t *p, nthw_rab_bus_id_t bus_id, uint32_t address,
     505                 :            :         uint32_t word_cnt, struct dma_buf_ptr *buf_ptr)
     506                 :            : {
     507                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     508                 :          0 :         const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
     509                 :            : 
     510         [ #  # ]:          0 :         if (word_cnt == 0 || word_cnt > 256) {
     511                 :          0 :                 NT_LOG(ERR, NTHW,
     512                 :            :                         "%s: Failed rab dma read length check - bus: %d addr: 0x%08X wordcount: %d - inBufFree: 0x%08X",
     513                 :            :                         p_adapter_id_str, bus_id, address, word_cnt, p->m_in_free);
     514                 :            :                 RTE_ASSERT(0);      /* alert developer that something is wrong */
     515                 :          0 :                 return -1;
     516                 :            :         }
     517                 :            : 
     518                 :            :         if ((word_cnt + 3) > RAB_DMA_BUF_CNT) {
     519                 :            :                 NT_LOG(ERR, NTHW,
     520                 :            :                         "%s: Failed rab dma read length check - bus: %d addr: 0x%08X wordcount: %d",
     521                 :            :                         p_adapter_id_str, bus_id, address, word_cnt);
     522                 :            :                 return -1;
     523                 :            :         }
     524                 :            : 
     525         [ #  # ]:          0 :         if (p->m_in_free < 3) {
     526                 :            :                 /*
     527                 :            :                  * No more memory available.
     528                 :            :                  * nthw_rac_rab_dma_commit() needs to be called to start and finish pending
     529                 :            :                  * transfers.
     530                 :            :                  */
     531                 :            :                 return -1;
     532                 :            :         }
     533                 :            : 
     534                 :          0 :         p->m_in_free -= 1;
     535                 :            : 
     536                 :            :         /* Write the command word */
     537                 :          0 :         p->m_dma_in_buf[p->m_dma_in_ptr_wr] = (RAB_READ << RAB_OPR_LO) |
     538                 :          0 :                 ((word_cnt & ((1 << RAB_CNT_BW) - 1)) << RAB_CNT_LO) | (bus_id << RAB_BUSID_LO) |
     539                 :            :                 address;
     540                 :          0 :         p->m_dma_in_ptr_wr = (uint16_t)((p->m_dma_in_ptr_wr + 1) & (RAB_DMA_BUF_CNT - 1));
     541                 :            : 
     542                 :          0 :         buf_ptr->index = p->m_dma_out_ptr_rd;
     543                 :          0 :         buf_ptr->size = RAB_DMA_BUF_CNT;
     544                 :          0 :         buf_ptr->base = p->m_dma_out_buf;
     545                 :          0 :         p->m_dma_out_ptr_rd =
     546                 :          0 :                 (uint16_t)((p->m_dma_out_ptr_rd + word_cnt) & (RAB_DMA_BUF_CNT - 1U));
     547                 :            : 
     548                 :          0 :         return 0;
     549                 :            : }
     550                 :            : 
     551                 :          0 : int nthw_rac_rab_write32(nthw_rac_t *p, bool trc, nthw_rab_bus_id_t bus_id, uint32_t address,
     552                 :            :         uint32_t word_cnt, const uint32_t *p_data)
     553                 :            : {
     554                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     555                 :          0 :         const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
     556                 :            :         uint32_t buf_used;
     557                 :            :         uint32_t buf_free;
     558                 :            :         uint32_t in_buf_free;
     559                 :            :         uint32_t out_buf_free;
     560                 :            :         int res = 0;
     561                 :            : 
     562         [ #  # ]:          0 :         if (address > (1 << RAB_ADDR_BW)) {
     563                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Illegal address: value too large %d - max %d",
     564                 :            :                         p_adapter_id_str, address, (1 << RAB_ADDR_BW));
     565                 :          0 :                 return -1;
     566                 :            :         }
     567                 :            : 
     568         [ #  # ]:          0 :         if (bus_id > (1 << RAB_BUSID_BW)) {
     569                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Illegal bus id: value too large %d - max %d",
     570                 :            :                         p_adapter_id_str, bus_id, (1 << RAB_BUSID_BW));
     571                 :          0 :                 return -1;
     572                 :            :         }
     573                 :            : 
     574         [ #  # ]:          0 :         if (word_cnt == 0) {
     575                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Illegal word count: value is zero (%d)",
     576                 :            :                         p_adapter_id_str, word_cnt);
     577                 :          0 :                 return -1;
     578                 :            :         }
     579                 :            : 
     580         [ #  # ]:          0 :         if (word_cnt > (1 << RAB_CNT_BW)) {
     581                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Illegal word count: value too large %d - max %d",
     582                 :            :                         p_adapter_id_str, word_cnt, (1 << RAB_CNT_BW));
     583                 :          0 :                 return -1;
     584                 :            :         }
     585                 :            : 
     586                 :          0 :         rte_spinlock_lock(&p->m_mutex);
     587                 :            : 
     588         [ #  # ]:          0 :         if (p->m_dma_active) {
     589                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Illegal operation: DMA enabled", p_adapter_id_str);
     590                 :            :                 res = -1;
     591                 :          0 :                 goto exit_unlock_res;
     592                 :            :         }
     593                 :            : 
     594                 :            :         /* Read buffer free register */
     595                 :          0 :         nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_BUF_FREE_ADDR, &buf_free);
     596                 :            : 
     597                 :          0 :         in_buf_free = buf_free & p->RAC_RAB_BUF_FREE_IB_FREE_MASK;
     598                 :          0 :         out_buf_free = (buf_free & p->RAC_RAB_BUF_FREE_OB_FREE_MASK) >> 16;
     599                 :            : 
     600                 :            :         /* Read buffer used register */
     601                 :          0 :         nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_BUF_USED_ADDR, &buf_used);
     602                 :            : 
     603                 :            :         buf_used =
     604                 :          0 :                 buf_used & (p->RAC_RAB_BUF_USED_IB_USED_MASK | p->RAC_RAB_BUF_USED_OB_USED_MASK);
     605                 :            : 
     606                 :            :         /*
     607                 :            :          * Verify that output buffer can hold one completion word,
     608                 :            :          * input buffer can hold the number of words to be written +
     609                 :            :          * one write and one completion command
     610                 :            :          * and that the input and output "used" buffer is 0
     611                 :            :          */
     612   [ #  #  #  #  :          0 :         if (out_buf_free >= 1 && in_buf_free >= word_cnt + 2 && buf_used == 0) {
                   #  # ]
     613                 :            :                 const uint32_t rab_oper_cmpl = (RAB_COMPLETION << RAB_OPR_LO);
     614                 :            :                 uint32_t rab_echo_oper_cmpl;
     615                 :            :                 uint32_t word_cnt_expected = 1;
     616                 :            :                 uint32_t rab_oper_wr;
     617                 :            :                 uint32_t i;
     618                 :            : 
     619                 :          0 :                 rab_oper_wr = (RAB_WRITE << RAB_OPR_LO) |
     620                 :          0 :                         ((word_cnt & ((1 << RAB_CNT_BW) - 1)) << RAB_CNT_LO) |
     621                 :          0 :                         (bus_id << RAB_BUSID_LO) | address;
     622                 :            : 
     623         [ #  # ]:          0 :                 if (trc) {
     624                 :          0 :                         rab_oper_wr |= (RAB_ECHO << RAB_OPR_LO);
     625                 :            :                         word_cnt_expected += word_cnt + 1;
     626                 :            :                 }
     627                 :            : 
     628                 :            :                 /* Write command */
     629                 :          0 :                 nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_IB_DATA_ADDR, rab_oper_wr);
     630                 :            : 
     631                 :            :                 /* Write data to input buffer */
     632         [ #  # ]:          0 :                 for (i = 0; i < word_cnt; i++)
     633                 :          0 :                         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_IB_DATA_ADDR, p_data[i]);
     634                 :            : 
     635                 :            :                 /* Write completion command */
     636                 :          0 :                 nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_IB_DATA_ADDR, rab_oper_cmpl);
     637                 :            : 
     638                 :            :                 /* Wait until done */
     639         [ #  # ]:          0 :                 if (_nthw_rac_wait_for_rab_done(p, address, word_cnt_expected)) {
     640                 :            :                         res = -1;
     641                 :          0 :                         goto exit_unlock_res;
     642                 :            :                 }
     643                 :            : 
     644         [ #  # ]:          0 :                 if (trc) {
     645                 :            :                         uint32_t rab_echo_oper_wr;
     646                 :          0 :                         nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR,
     647                 :            :                                 &rab_echo_oper_wr);
     648                 :            : 
     649         [ #  # ]:          0 :                         if (p->mn_param_rac_rab_ob_update)
     650                 :            :                                 nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR, 0);
     651                 :            : 
     652         [ #  # ]:          0 :                         if (rab_oper_wr != rab_echo_oper_wr) {
     653                 :          0 :                                 NT_LOG(ERR, NTHW,
     654                 :            :                                         "%s: expected rab read echo oper (0x%08X) - read (0x%08X)",
     655                 :            :                                         p_adapter_id_str, rab_oper_wr, rab_echo_oper_wr);
     656                 :            :                         }
     657                 :            :                 }
     658                 :            : 
     659                 :            :                 {
     660                 :            :                         /* Read data from output buffer */
     661                 :            :                         uint32_t data;
     662                 :            :                         char *tmp_string;
     663                 :            : 
     664         [ #  # ]:          0 :                         if (trc) {
     665                 :          0 :                                 tmp_string = ntlog_helper_str_alloc("Register::write");
     666                 :          0 :                                 ntlog_helper_str_add(tmp_string,
     667                 :            :                                         "(Dev: NA, Bus: RAB%u, Addr: 0x%08X, Cnt: %d, Data:",
     668                 :            :                                         bus_id, address, word_cnt);
     669                 :            :                         }
     670                 :            : 
     671         [ #  # ]:          0 :                         for (i = 0; i < word_cnt; i++) {
     672                 :          0 :                                 nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR, &data);
     673                 :            : 
     674         [ #  # ]:          0 :                                 if (p->mn_param_rac_rab_ob_update) {
     675                 :            :                                         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR,
     676                 :            :                                                 0);
     677                 :            :                                 }
     678                 :            : 
     679         [ #  # ]:          0 :                                 if (trc)
     680                 :          0 :                                         ntlog_helper_str_add(tmp_string, " 0x%08X", data);
     681                 :            :                         }
     682                 :            : 
     683         [ #  # ]:          0 :                         if (trc) {
     684                 :          0 :                                 ntlog_helper_str_add(tmp_string, ")");
     685                 :          0 :                                 NT_LOG(DBG, NTHW, "%s", tmp_string);
     686                 :          0 :                                 ntlog_helper_str_free(tmp_string);
     687                 :            :                         }
     688                 :            :                 }
     689                 :            : 
     690                 :            :                 /* Read completion from out buffer */
     691                 :          0 :                 nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR, &rab_echo_oper_cmpl);
     692                 :            : 
     693         [ #  # ]:          0 :                 if (p->mn_param_rac_rab_ob_update)
     694                 :            :                         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR, 0);
     695                 :            : 
     696         [ #  # ]:          0 :                 if (rab_echo_oper_cmpl != rab_oper_cmpl) {
     697                 :          0 :                         NT_LOG(ERR, NTHW,
     698                 :            :                                 "%s: RAB: Unexpected value of completion (0x%08X)- inBufFree: 0x%08X, outBufFree: 0x%08X, bufUsed: 0x%08X",
     699                 :            :                                 p_adapter_id_str, rab_echo_oper_cmpl, in_buf_free, out_buf_free,
     700                 :            :                                 buf_used);
     701                 :            :                         res = -1;
     702                 :          0 :                         goto exit_unlock_res;
     703                 :            :                 }
     704                 :            : 
     705                 :            :                 /* Read buffer free register */
     706                 :          0 :                 nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_BUF_FREE_ADDR, &buf_free);
     707                 :            : 
     708         [ #  # ]:          0 :                 if (buf_free & 0x80000000) {
     709                 :            :                         /* Clear Timeout and overflow bits */
     710                 :            :                         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_BUF_FREE_ADDR, 0x0);
     711                 :          0 :                         NT_LOG(ERR, NTHW,
     712                 :            :                                 "%s: RAB: timeout - Access outside register - bus: %d addr: 0x%08X - inBufFree: 0x%08X, outBufFree: 0x%08X, bufUsed: 0x%08X",
     713                 :            :                                 p_adapter_id_str, bus_id, address, in_buf_free, out_buf_free,
     714                 :            :                                 buf_used);
     715                 :            :                         res = -1;
     716                 :          0 :                         goto exit_unlock_res;
     717                 :            :                 }
     718                 :            : 
     719                 :            :                 res = 0;
     720                 :          0 :                 goto exit_unlock_res;
     721                 :            : 
     722                 :            :         } else {
     723                 :          0 :                 NT_LOG(ERR, NTHW,
     724                 :            :                         "%s: RAB: Fail rab bus buffer check - bus: %d addr: 0x%08X wordcount: %d - inBufFree: 0x%08X, outBufFree: 0x%08X, bufUsed: 0x%08X",
     725                 :            :                         p_adapter_id_str, bus_id, address, word_cnt, in_buf_free, out_buf_free,
     726                 :            :                         buf_used);
     727                 :            :                 res = -1;
     728                 :          0 :                 goto exit_unlock_res;
     729                 :            :         }
     730                 :            : 
     731                 :          0 : exit_unlock_res:
     732                 :            :         rte_spinlock_unlock(&p->m_mutex);
     733                 :          0 :         return res;
     734                 :            : }
     735                 :            : 
     736                 :          0 : int nthw_rac_rab_read32(nthw_rac_t *p, bool trc, nthw_rab_bus_id_t bus_id, uint32_t address,
     737                 :            :         uint32_t word_cnt, uint32_t *p_data)
     738                 :            : {
     739                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     740                 :          0 :         const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
     741                 :            :         uint32_t buf_used;
     742                 :            :         uint32_t buf_free;
     743                 :            :         uint32_t in_buf_free;
     744                 :            :         uint32_t out_buf_free;
     745                 :            :         int res = 0;
     746                 :            : 
     747                 :          0 :         rte_spinlock_lock(&p->m_mutex);
     748                 :            : 
     749         [ #  # ]:          0 :         if (address > (1 << RAB_ADDR_BW)) {
     750                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Illegal address: value too large %d - max %d",
     751                 :            :                         p_adapter_id_str, address, (1 << RAB_ADDR_BW));
     752                 :            :                 res = -1;
     753                 :          0 :                 goto exit_unlock_res;
     754                 :            :         }
     755                 :            : 
     756         [ #  # ]:          0 :         if (bus_id > (1 << RAB_BUSID_BW)) {
     757                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Illegal bus id: value too large %d - max %d",
     758                 :            :                         p_adapter_id_str, bus_id, (1 << RAB_BUSID_BW));
     759                 :            :                 res = -1;
     760                 :          0 :                 goto exit_unlock_res;
     761                 :            :         }
     762                 :            : 
     763         [ #  # ]:          0 :         if (word_cnt == 0) {
     764                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Illegal word count: value is zero (%d)",
     765                 :            :                         p_adapter_id_str, word_cnt);
     766                 :            :                 res = -1;
     767                 :          0 :                 goto exit_unlock_res;
     768                 :            :         }
     769                 :            : 
     770         [ #  # ]:          0 :         if (word_cnt > (1 << RAB_CNT_BW)) {
     771                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Illegal word count: value too large %d - max %d",
     772                 :            :                         p_adapter_id_str, word_cnt, (1 << RAB_CNT_BW));
     773                 :            :                 res = -1;
     774                 :          0 :                 goto exit_unlock_res;
     775                 :            :         }
     776                 :            : 
     777                 :            :         /* Read buffer free register */
     778                 :          0 :         nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_BUF_FREE_ADDR, &buf_free);
     779                 :            : 
     780                 :          0 :         in_buf_free = buf_free & p->RAC_RAB_BUF_FREE_IB_FREE_MASK;
     781                 :          0 :         out_buf_free = (buf_free & p->RAC_RAB_BUF_FREE_OB_FREE_MASK) >> 16;
     782                 :            : 
     783                 :            :         /* Read buffer used register */
     784                 :          0 :         nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_BUF_USED_ADDR, &buf_used);
     785                 :            : 
     786                 :            :         buf_used =
     787                 :          0 :                 buf_used & (p->RAC_RAB_BUF_USED_IB_USED_MASK | p->RAC_RAB_BUF_USED_OB_USED_MASK);
     788                 :            : 
     789                 :            :         /*
     790                 :            :          * Verify that output buffer can hold the number of words to be read,
     791                 :            :          * input buffer can hold one read command
     792                 :            :          * and that the input and output "used" buffer is 0
     793                 :            :          */
     794   [ #  #  #  # ]:          0 :         if (out_buf_free >= word_cnt && in_buf_free >= 1 && buf_used == 0) {
     795                 :            :                 const uint32_t rab_oper_cmpl = (RAB_COMPLETION << RAB_OPR_LO);
     796                 :            :                 uint32_t rab_read_oper_cmpl;
     797                 :          0 :                 uint32_t word_cnt_expected = word_cnt + 1;
     798                 :            :                 uint32_t rab_oper_rd;
     799                 :            : 
     800                 :          0 :                 rab_oper_rd = (RAB_READ << RAB_OPR_LO) |
     801                 :          0 :                         ((word_cnt & ((1 << RAB_CNT_BW) - 1)) << RAB_CNT_LO) |
     802                 :          0 :                         (bus_id << RAB_BUSID_LO) | address;
     803                 :            : 
     804         [ #  # ]:          0 :                 if (trc) {
     805                 :          0 :                         rab_oper_rd |= (RAB_ECHO << RAB_OPR_LO);
     806                 :          0 :                         word_cnt_expected++;
     807                 :            :                 }
     808                 :            : 
     809                 :            :                 /* Write command */
     810                 :          0 :                 nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_IB_DATA_ADDR, rab_oper_rd);
     811                 :            : 
     812                 :            :                 /* Write completion command */
     813                 :          0 :                 nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_IB_DATA_ADDR, rab_oper_cmpl);
     814                 :            : 
     815                 :            :                 /* Wait until done */
     816         [ #  # ]:          0 :                 if (_nthw_rac_wait_for_rab_done(p, address, word_cnt_expected)) {
     817                 :            :                         res = -1;
     818                 :          0 :                         goto exit_unlock_res;
     819                 :            :                 }
     820                 :            : 
     821         [ #  # ]:          0 :                 if (trc) {
     822                 :            :                         uint32_t rab_echo_oper_rd;
     823                 :          0 :                         nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR,
     824                 :            :                                 &rab_echo_oper_rd);
     825                 :            : 
     826         [ #  # ]:          0 :                         if (p->mn_param_rac_rab_ob_update)
     827                 :            :                                 nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR, 0);
     828                 :            : 
     829         [ #  # ]:          0 :                         if (rab_oper_rd != rab_echo_oper_rd) {
     830                 :          0 :                                 NT_LOG(ERR, NTHW,
     831                 :            :                                         "%s: RAB: expected rab read echo oper (0x%08X) - read (0x%08X)",
     832                 :            :                                         p_adapter_id_str, rab_oper_rd, rab_echo_oper_rd);
     833                 :            :                         }
     834                 :            :                 }
     835                 :            : 
     836                 :            :                 {
     837                 :            :                         /* Read data from output buffer */
     838                 :            :                         uint32_t i;
     839                 :            : 
     840         [ #  # ]:          0 :                         for (i = 0; i < word_cnt; i++) {
     841                 :          0 :                                 nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR,
     842                 :          0 :                                         &p_data[i]);
     843                 :            : 
     844         [ #  # ]:          0 :                                 if (p->mn_param_rac_rab_ob_update) {
     845                 :          0 :                                         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR,
     846                 :            :                                                 0);
     847                 :            :                                 }
     848                 :            :                         }
     849                 :            : 
     850         [ #  # ]:          0 :                         if (trc) {
     851                 :          0 :                                 char *tmp_string = ntlog_helper_str_alloc("Register::read");
     852                 :          0 :                                 ntlog_helper_str_add(tmp_string,
     853                 :            :                                         "(Dev: NA, Bus: RAB%u, Addr: 0x%08X, Cnt: %d, Data:",
     854                 :            :                                         bus_id, address, word_cnt);
     855                 :            : 
     856         [ #  # ]:          0 :                                 for (i = 0; i < word_cnt; i++)
     857                 :          0 :                                         ntlog_helper_str_add(tmp_string, " 0x%08X", p_data[i]);
     858                 :            : 
     859                 :          0 :                                 ntlog_helper_str_add(tmp_string, ")");
     860                 :          0 :                                 NT_LOG(DBG, NTHW, "%s", tmp_string);
     861                 :          0 :                                 ntlog_helper_str_free(tmp_string);
     862                 :            :                         }
     863                 :            :                 }
     864                 :            : 
     865                 :            :                 /* Read completion from out buffer */
     866                 :          0 :                 nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR, &rab_read_oper_cmpl);
     867                 :            : 
     868         [ #  # ]:          0 :                 if (p->mn_param_rac_rab_ob_update)
     869                 :            :                         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_OB_DATA_ADDR, 0);
     870                 :            : 
     871         [ #  # ]:          0 :                 if (rab_read_oper_cmpl != rab_oper_cmpl) {
     872                 :          0 :                         NT_LOG(ERR, NTHW,
     873                 :            :                                 "%s: RAB: Unexpected value of completion (0x%08X)- inBufFree: 0x%08X, outBufFree: 0x%08X, bufUsed: 0x%08X",
     874                 :            :                                 p_adapter_id_str, rab_read_oper_cmpl, in_buf_free, out_buf_free,
     875                 :            :                                 buf_used);
     876                 :            :                         res = -1;
     877                 :          0 :                         goto exit_unlock_res;
     878                 :            :                 }
     879                 :            : 
     880                 :            :                 /* Read buffer free register */
     881                 :          0 :                 nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_BUF_FREE_ADDR, &buf_free);
     882                 :            : 
     883         [ #  # ]:          0 :                 if (buf_free & 0x80000000) {
     884                 :            :                         /* Clear Timeout and overflow bits */
     885                 :            :                         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_BUF_FREE_ADDR, 0x0);
     886                 :          0 :                         NT_LOG(ERR, NTHW,
     887                 :            :                                 "%s: RAB: timeout - Access outside register - bus: %d addr: 0x%08X - inBufFree: 0x%08X, outBufFree: 0x%08X, bufUsed: 0x%08X",
     888                 :            :                                 p_adapter_id_str, bus_id, address, in_buf_free, out_buf_free,
     889                 :            :                                 buf_used);
     890                 :            :                         res = -1;
     891                 :          0 :                         goto exit_unlock_res;
     892                 :            :                 }
     893                 :            : 
     894                 :            :                 res = 0;
     895                 :          0 :                 goto exit_unlock_res;
     896                 :            : 
     897                 :            :         } else {
     898                 :          0 :                 NT_LOG(ERR, NTHW,
     899                 :            :                         "%s: RAB: Fail rab bus buffer check - bus: %d addr: 0x%08X wordcount: %d - inBufFree: 0x%08X, outBufFree: 0x%08X, bufUsed: 0x%08X",
     900                 :            :                         p_adapter_id_str, bus_id, address, word_cnt, in_buf_free, out_buf_free,
     901                 :            :                         buf_used);
     902                 :            :                 res = -1;
     903                 :          0 :                 goto exit_unlock_res;
     904                 :            :         }
     905                 :            : 
     906                 :          0 : exit_unlock_res:
     907                 :            :         rte_spinlock_unlock(&p->m_mutex);
     908                 :          0 :         return res;
     909                 :            : }
     910                 :            : 
     911                 :          0 : int nthw_rac_rab_flush(nthw_rac_t *p)
     912                 :            : {
     913                 :          0 :         const struct fpga_info_s *const p_fpga_info = p->mp_fpga->p_fpga_info;
     914                 :          0 :         const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
     915                 :            :         uint32_t data = 0;
     916                 :            :         uint32_t retry;
     917                 :            :         int res = 0;
     918                 :            : 
     919                 :          0 :         rte_spinlock_lock(&p->m_mutex);
     920                 :            : 
     921                 :            :         /* Set the flush bit */
     922                 :          0 :         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_BUF_USED_ADDR,
     923                 :            :                 p->RAC_RAB_BUF_USED_FLUSH_MASK);
     924                 :            : 
     925                 :            :         /* Reset BUF FREE register */
     926                 :          0 :         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_BUF_FREE_ADDR, 0x0);
     927                 :            : 
     928                 :            :         /* Wait until OB_USED and IB_USED are 0 */
     929         [ #  # ]:          0 :         for (retry = 0; retry < 100000; retry++) {
     930                 :          0 :                 nthw_rac_reg_read32(p_fpga_info, p->RAC_RAB_BUF_USED_ADDR, &data);
     931                 :            : 
     932         [ #  # ]:          0 :                 if ((data & 0xFFFFFFFF) == p->RAC_RAB_BUF_USED_FLUSH_MASK)
     933                 :            :                         break;
     934                 :            :         }
     935                 :            : 
     936         [ #  # ]:          0 :         if (data != p->RAC_RAB_BUF_USED_FLUSH_MASK) {
     937                 :          0 :                 NT_LOG(ERR, NTHW, "%s: RAB: Rab bus flush error.", p_adapter_id_str);
     938                 :            :                 res = -1;
     939                 :            :         }
     940                 :            : 
     941                 :            :         /* Clear flush bit when done */
     942                 :          0 :         nthw_rac_reg_write32(p_fpga_info, p->RAC_RAB_BUF_USED_ADDR, 0x0);
     943                 :            : 
     944                 :            :         rte_spinlock_unlock(&p->m_mutex);
     945                 :          0 :         return res;
     946                 :            : }

Generated by: LCOV version 1.14