LCOV - code coverage report
Current view: top level - drivers/crypto/octeontx - otx_cryptodev_hw_access.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 201 0.0 %
Date: 2024-01-22 15:55:54 Functions: 0 11 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 60 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018 Cavium, Inc
       3                 :            :  */
       4                 :            : #include <assert.h>
       5                 :            : #include <string.h>
       6                 :            : #include <unistd.h>
       7                 :            : 
       8                 :            : #include <rte_branch_prediction.h>
       9                 :            : #include <rte_common.h>
      10                 :            : #include <cryptodev_pmd.h>
      11                 :            : #include <rte_errno.h>
      12                 :            : #include <rte_mempool.h>
      13                 :            : #include <rte_memzone.h>
      14                 :            : #include <rte_string_fns.h>
      15                 :            : 
      16                 :            : #include "otx_cryptodev_hw_access.h"
      17                 :            : #include "otx_cryptodev_mbox.h"
      18                 :            : 
      19                 :            : #include "cpt_pmd_logs.h"
      20                 :            : #include "cpt_pmd_ops_helper.h"
      21                 :            : #include "cpt_hw_types.h"
      22                 :            : 
      23                 :            : #define METABUF_POOL_CACHE_SIZE 512
      24                 :            : 
      25                 :            : /*
      26                 :            :  * VF HAL functions
      27                 :            :  * Access its own BAR0/4 registers by passing VF number as 0.
      28                 :            :  * OS/PCI maps them accordingly.
      29                 :            :  */
      30                 :            : 
      31                 :            : static int
      32                 :          0 : otx_cpt_vf_init(struct cpt_vf *cptvf)
      33                 :            : {
      34                 :            :         int ret = 0;
      35                 :            : 
      36                 :            :         /* Check ready with PF */
      37                 :            :         /* Gets chip ID / device Id from PF if ready */
      38                 :          0 :         ret = otx_cpt_check_pf_ready(cptvf);
      39         [ #  # ]:          0 :         if (ret) {
      40                 :          0 :                 CPT_LOG_ERR("%s: PF not responding to READY msg",
      41                 :            :                                 cptvf->dev_name);
      42                 :            :                 ret = -EBUSY;
      43                 :          0 :                 goto exit;
      44                 :            :         }
      45                 :            : 
      46                 :            :         CPT_LOG_DP_DEBUG("%s: %s done", cptvf->dev_name, __func__);
      47                 :            : 
      48                 :          0 : exit:
      49                 :          0 :         return ret;
      50                 :            : }
      51                 :            : 
      52                 :            : /*
      53                 :            :  * Read Interrupt status of the VF
      54                 :            :  *
      55                 :            :  * @param   cptvf       cptvf structure
      56                 :            :  */
      57                 :            : static uint64_t
      58                 :            : otx_cpt_read_vf_misc_intr_status(struct cpt_vf *cptvf)
      59                 :            : {
      60                 :          0 :         return CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), CPTX_VQX_MISC_INT(0, 0));
      61                 :            : }
      62                 :            : 
      63                 :            : /*
      64                 :            :  * Clear mailbox interrupt of the VF
      65                 :            :  *
      66                 :            :  * @param   cptvf       cptvf structure
      67                 :            :  */
      68                 :            : static void
      69                 :            : otx_cpt_clear_mbox_intr(struct cpt_vf *cptvf)
      70                 :            : {
      71                 :            :         cptx_vqx_misc_int_t vqx_misc_int;
      72                 :            : 
      73                 :          0 :         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
      74                 :            :                                       CPTX_VQX_MISC_INT(0, 0));
      75                 :            :         /* W1C for the VF */
      76                 :          0 :         vqx_misc_int.s.mbox = 1;
      77                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
      78                 :            :                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
      79                 :          0 : }
      80                 :            : 
      81                 :            : /*
      82                 :            :  * Clear instruction NCB read error interrupt of the VF
      83                 :            :  *
      84                 :            :  * @param   cptvf       cptvf structure
      85                 :            :  */
      86                 :            : static void
      87                 :            : otx_cpt_clear_irde_intr(struct cpt_vf *cptvf)
      88                 :            : {
      89                 :            :         cptx_vqx_misc_int_t vqx_misc_int;
      90                 :            : 
      91                 :          0 :         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
      92                 :            :                                       CPTX_VQX_MISC_INT(0, 0));
      93                 :            :         /* W1C for the VF */
      94                 :          0 :         vqx_misc_int.s.irde = 1;
      95                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
      96                 :            :                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
      97                 :          0 : }
      98                 :            : 
      99                 :            : /*
     100                 :            :  * Clear NCB result write response error interrupt of the VF
     101                 :            :  *
     102                 :            :  * @param   cptvf       cptvf structure
     103                 :            :  */
     104                 :            : static void
     105                 :            : otx_cpt_clear_nwrp_intr(struct cpt_vf *cptvf)
     106                 :            : {
     107                 :            :         cptx_vqx_misc_int_t vqx_misc_int;
     108                 :            : 
     109                 :          0 :         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     110                 :            :                                       CPTX_VQX_MISC_INT(0, 0));
     111                 :            :         /* W1C for the VF */
     112                 :          0 :         vqx_misc_int.s.nwrp = 1;
     113                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     114                 :            :                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
     115                 :          0 : }
     116                 :            : 
     117                 :            : /*
     118                 :            :  * Clear swerr interrupt of the VF
     119                 :            :  *
     120                 :            :  * @param   cptvf       cptvf structure
     121                 :            :  */
     122                 :            : static void
     123                 :            : otx_cpt_clear_swerr_intr(struct cpt_vf *cptvf)
     124                 :            : {
     125                 :            :         cptx_vqx_misc_int_t vqx_misc_int;
     126                 :            : 
     127                 :          0 :         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     128                 :            :                                       CPTX_VQX_MISC_INT(0, 0));
     129                 :            :         /* W1C for the VF */
     130                 :          0 :         vqx_misc_int.s.swerr = 1;
     131                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     132                 :            :                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
     133                 :          0 : }
     134                 :            : 
     135                 :            : /*
     136                 :            :  * Clear hwerr interrupt of the VF
     137                 :            :  *
     138                 :            :  * @param   cptvf       cptvf structure
     139                 :            :  */
     140                 :            : static void
     141                 :            : otx_cpt_clear_hwerr_intr(struct cpt_vf *cptvf)
     142                 :            : {
     143                 :            :         cptx_vqx_misc_int_t vqx_misc_int;
     144                 :            : 
     145                 :          0 :         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     146                 :            :                                       CPTX_VQX_MISC_INT(0, 0));
     147                 :            :         /* W1C for the VF */
     148                 :          0 :         vqx_misc_int.s.hwerr = 1;
     149                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     150                 :            :                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
     151                 :          0 : }
     152                 :            : 
     153                 :            : /*
     154                 :            :  * Clear translation fault interrupt of the VF
     155                 :            :  *
     156                 :            :  * @param   cptvf       cptvf structure
     157                 :            :  */
     158                 :            : static void
     159                 :            : otx_cpt_clear_fault_intr(struct cpt_vf *cptvf)
     160                 :            : {
     161                 :            :         cptx_vqx_misc_int_t vqx_misc_int;
     162                 :            : 
     163                 :          0 :         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     164                 :            :                                 CPTX_VQX_MISC_INT(0, 0));
     165                 :            :         /* W1C for the VF */
     166                 :          0 :         vqx_misc_int.s.fault = 1;
     167                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     168                 :            :                 CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
     169                 :          0 : }
     170                 :            : 
     171                 :            : /*
     172                 :            :  * Clear doorbell overflow interrupt of the VF
     173                 :            :  *
     174                 :            :  * @param   cptvf       cptvf structure
     175                 :            :  */
     176                 :            : static void
     177                 :            : otx_cpt_clear_dovf_intr(struct cpt_vf *cptvf)
     178                 :            : {
     179                 :            :         cptx_vqx_misc_int_t vqx_misc_int;
     180                 :            : 
     181                 :          0 :         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     182                 :            :                                       CPTX_VQX_MISC_INT(0, 0));
     183                 :            :         /* W1C for the VF */
     184                 :          0 :         vqx_misc_int.s.dovf = 1;
     185                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     186                 :            :                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
     187                 :          0 : }
     188                 :            : 
     189                 :            : /* Write to VQX_CTL register
     190                 :            :  */
     191                 :            : static void
     192                 :            : otx_cpt_write_vq_ctl(struct cpt_vf *cptvf, bool val)
     193                 :            : {
     194                 :            :         cptx_vqx_ctl_t vqx_ctl;
     195                 :            : 
     196                 :          0 :         vqx_ctl.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     197                 :            :                                  CPTX_VQX_CTL(0, 0));
     198                 :          0 :         vqx_ctl.s.ena = val;
     199                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     200                 :            :                       CPTX_VQX_CTL(0, 0), vqx_ctl.u);
     201                 :            : }
     202                 :            : 
     203                 :            : /* Write to VQX_INPROG register
     204                 :            :  */
     205                 :            : static void
     206                 :            : otx_cpt_write_vq_inprog(struct cpt_vf *cptvf, uint8_t val)
     207                 :            : {
     208                 :            :         cptx_vqx_inprog_t vqx_inprg;
     209                 :            : 
     210                 :          0 :         vqx_inprg.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     211                 :            :                                    CPTX_VQX_INPROG(0, 0));
     212                 :          0 :         vqx_inprg.s.inflight = val;
     213                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     214                 :            :                       CPTX_VQX_INPROG(0, 0), vqx_inprg.u);
     215                 :            : }
     216                 :            : 
     217                 :            : /* Write to VQX_DONE_WAIT NUMWAIT register
     218                 :            :  */
     219                 :            : static void
     220                 :            : otx_cpt_write_vq_done_numwait(struct cpt_vf *cptvf, uint32_t val)
     221                 :            : {
     222                 :            :         cptx_vqx_done_wait_t vqx_dwait;
     223                 :            : 
     224                 :          0 :         vqx_dwait.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     225                 :            :                                    CPTX_VQX_DONE_WAIT(0, 0));
     226                 :          0 :         vqx_dwait.s.num_wait = val;
     227                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     228                 :            :                       CPTX_VQX_DONE_WAIT(0, 0), vqx_dwait.u);
     229                 :            : }
     230                 :            : 
     231                 :            : /* Write to VQX_DONE_WAIT NUM_WAIT register
     232                 :            :  */
     233                 :            : static void
     234                 :            : otx_cpt_write_vq_done_timewait(struct cpt_vf *cptvf, uint16_t val)
     235                 :            : {
     236                 :            :         cptx_vqx_done_wait_t vqx_dwait;
     237                 :            : 
     238                 :          0 :         vqx_dwait.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     239                 :            :                                    CPTX_VQX_DONE_WAIT(0, 0));
     240                 :          0 :         vqx_dwait.s.time_wait = val;
     241                 :          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     242                 :            :                       CPTX_VQX_DONE_WAIT(0, 0), vqx_dwait.u);
     243                 :            : }
     244                 :            : 
     245                 :            : /* Write to VQX_SADDR register
     246                 :            :  */
     247                 :            : static void
     248                 :            : otx_cpt_write_vq_saddr(struct cpt_vf *cptvf, uint64_t val)
     249                 :            : {
     250                 :            :         cptx_vqx_saddr_t vqx_saddr;
     251                 :            : 
     252                 :            :         vqx_saddr.u = val;
     253                 :            :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     254                 :            :                       CPTX_VQX_SADDR(0, 0), vqx_saddr.u);
     255                 :            : }
     256                 :            : 
     257                 :            : static void
     258                 :          0 : otx_cpt_vfvq_init(struct cpt_vf *cptvf)
     259                 :            : {
     260                 :            :         uint64_t base_addr = 0;
     261                 :            : 
     262                 :            :         /* Disable the VQ */
     263                 :            :         otx_cpt_write_vq_ctl(cptvf, 0);
     264                 :            : 
     265                 :            :         /* Reset the doorbell */
     266                 :            :         otx_cpt_write_vq_doorbell(cptvf, 0);
     267                 :            :         /* Clear inflight */
     268                 :            :         otx_cpt_write_vq_inprog(cptvf, 0);
     269                 :            : 
     270                 :            :         /* Write VQ SADDR */
     271                 :          0 :         base_addr = (uint64_t)(cptvf->cqueue.chead[0].dma_addr);
     272                 :            :         otx_cpt_write_vq_saddr(cptvf, base_addr);
     273                 :            : 
     274                 :            :         /* Configure timerhold / coalescence */
     275                 :            :         otx_cpt_write_vq_done_timewait(cptvf, CPT_TIMER_THOLD);
     276                 :            :         otx_cpt_write_vq_done_numwait(cptvf, CPT_COUNT_THOLD);
     277                 :            : 
     278                 :            :         /* Enable the VQ */
     279                 :            :         otx_cpt_write_vq_ctl(cptvf, 1);
     280                 :          0 : }
     281                 :            : 
     282                 :            : static int
     283                 :          0 : cpt_vq_init(struct cpt_vf *cptvf, uint8_t group)
     284                 :            : {
     285                 :            :         int err;
     286                 :            : 
     287                 :            :         /* Convey VQ LEN to PF */
     288                 :          0 :         err = otx_cpt_send_vq_size_msg(cptvf);
     289         [ #  # ]:          0 :         if (err) {
     290                 :          0 :                 CPT_LOG_ERR("%s: PF not responding to QLEN msg",
     291                 :            :                             cptvf->dev_name);
     292                 :            :                 err = -EBUSY;
     293                 :          0 :                 goto cleanup;
     294                 :            :         }
     295                 :            : 
     296                 :            :         /* CPT VF device initialization */
     297                 :          0 :         otx_cpt_vfvq_init(cptvf);
     298                 :            : 
     299                 :            :         /* Send msg to PF to assign current Q to required group */
     300                 :          0 :         cptvf->vfgrp = group;
     301                 :          0 :         err = otx_cpt_send_vf_grp_msg(cptvf, group);
     302         [ #  # ]:          0 :         if (err) {
     303                 :          0 :                 CPT_LOG_ERR("%s: PF not responding to VF_GRP msg",
     304                 :            :                             cptvf->dev_name);
     305                 :            :                 err = -EBUSY;
     306                 :          0 :                 goto cleanup;
     307                 :            :         }
     308                 :            : 
     309                 :            :         CPT_LOG_DP_DEBUG("%s: %s done", cptvf->dev_name, __func__);
     310                 :            :         return 0;
     311                 :            : 
     312                 :            : cleanup:
     313                 :            :         return err;
     314                 :            : }
     315                 :            : 
     316                 :            : void
     317         [ #  # ]:          0 : otx_cpt_poll_misc(struct cpt_vf *cptvf)
     318                 :            : {
     319                 :            :         uint64_t intr;
     320                 :            : 
     321                 :            :         intr = otx_cpt_read_vf_misc_intr_status(cptvf);
     322                 :            : 
     323         [ #  # ]:          0 :         if (!intr)
     324                 :            :                 return;
     325                 :            : 
     326                 :            :         /* Check for MISC interrupt types */
     327         [ #  # ]:          0 :         if (likely(intr & CPT_VF_INTR_MBOX_MASK)) {
     328                 :            :                 CPT_LOG_DP_DEBUG("%s: Mailbox interrupt 0x%lx on CPT VF %d",
     329                 :            :                         cptvf->dev_name, (unsigned int long)intr, cptvf->vfid);
     330                 :          0 :                 otx_cpt_handle_mbox_intr(cptvf);
     331                 :            :                 otx_cpt_clear_mbox_intr(cptvf);
     332         [ #  # ]:          0 :         } else if (unlikely(intr & CPT_VF_INTR_IRDE_MASK)) {
     333                 :            :                 otx_cpt_clear_irde_intr(cptvf);
     334                 :            :                 CPT_LOG_DP_DEBUG("%s: Instruction NCB read error interrupt "
     335                 :            :                                 "0x%lx on CPT VF %d", cptvf->dev_name,
     336                 :            :                                 (unsigned int long)intr, cptvf->vfid);
     337         [ #  # ]:          0 :         } else if (unlikely(intr & CPT_VF_INTR_NWRP_MASK)) {
     338                 :            :                 otx_cpt_clear_nwrp_intr(cptvf);
     339                 :            :                 CPT_LOG_DP_DEBUG("%s: NCB response write error interrupt 0x%lx"
     340                 :            :                                 " on CPT VF %d", cptvf->dev_name,
     341                 :            :                                 (unsigned int long)intr, cptvf->vfid);
     342         [ #  # ]:          0 :         } else if (unlikely(intr & CPT_VF_INTR_SWERR_MASK)) {
     343                 :            :                 otx_cpt_clear_swerr_intr(cptvf);
     344                 :            :                 CPT_LOG_DP_DEBUG("%s: Software error interrupt 0x%lx on CPT VF "
     345                 :            :                                 "%d", cptvf->dev_name, (unsigned int long)intr,
     346                 :            :                                 cptvf->vfid);
     347         [ #  # ]:          0 :         } else if (unlikely(intr & CPT_VF_INTR_HWERR_MASK)) {
     348                 :            :                 otx_cpt_clear_hwerr_intr(cptvf);
     349                 :            :                 CPT_LOG_DP_DEBUG("%s: Hardware error interrupt 0x%lx on CPT VF "
     350                 :            :                                 "%d", cptvf->dev_name, (unsigned int long)intr,
     351                 :            :                                 cptvf->vfid);
     352         [ #  # ]:          0 :         } else if (unlikely(intr & CPT_VF_INTR_FAULT_MASK)) {
     353                 :            :                 otx_cpt_clear_fault_intr(cptvf);
     354                 :            :                 CPT_LOG_DP_DEBUG("%s: Translation fault interrupt 0x%lx on CPT VF "
     355                 :            :                                 "%d", cptvf->dev_name, (unsigned int long)intr,
     356                 :            :                                 cptvf->vfid);
     357         [ #  # ]:          0 :         } else if (unlikely(intr & CPT_VF_INTR_DOVF_MASK)) {
     358                 :            :                 otx_cpt_clear_dovf_intr(cptvf);
     359                 :            :                 CPT_LOG_DP_DEBUG("%s: Doorbell overflow interrupt 0x%lx on CPT VF "
     360                 :            :                                 "%d", cptvf->dev_name, (unsigned int long)intr,
     361                 :            :                                 cptvf->vfid);
     362                 :            :         } else
     363                 :          0 :                 CPT_LOG_DP_ERR("%s: Unhandled interrupt 0x%lx in CPT VF %d",
     364                 :            :                                 cptvf->dev_name, (unsigned int long)intr,
     365                 :            :                                 cptvf->vfid);
     366                 :            : }
     367                 :            : 
     368                 :            : int
     369                 :          0 : otx_cpt_hw_init(struct cpt_vf *cptvf, void *pdev, void *reg_base, char *name)
     370                 :            : {
     371                 :            :         memset(cptvf, 0, sizeof(struct cpt_vf));
     372                 :            : 
     373                 :            :         /* Bar0 base address */
     374                 :          0 :         cptvf->reg_base = reg_base;
     375                 :            : 
     376                 :            :         /* Save device name */
     377                 :          0 :         strlcpy(cptvf->dev_name, name, (sizeof(cptvf->dev_name)));
     378                 :            : 
     379                 :          0 :         cptvf->pdev = pdev;
     380                 :            : 
     381                 :            :         /* To clear if there are any pending mbox msgs */
     382                 :          0 :         otx_cpt_poll_misc(cptvf);
     383                 :            : 
     384         [ #  # ]:          0 :         if (otx_cpt_vf_init(cptvf)) {
     385                 :          0 :                 CPT_LOG_ERR("Failed to initialize CPT VF device");
     386                 :          0 :                 return -1;
     387                 :            :         }
     388                 :            : 
     389                 :            :         /* Gets device type */
     390         [ #  # ]:          0 :         if (otx_cpt_get_dev_type(cptvf)) {
     391                 :          0 :                 CPT_LOG_ERR("Failed to get device type");
     392                 :          0 :                 return -1;
     393                 :            :         }
     394                 :            : 
     395                 :            :         return 0;
     396                 :            : }
     397                 :            : 
     398                 :            : int
     399                 :          0 : otx_cpt_deinit_device(void *dev)
     400                 :            : {
     401                 :            :         struct cpt_vf *cptvf = (struct cpt_vf *)dev;
     402                 :            : 
     403                 :            :         /* Do misc work one last time */
     404                 :          0 :         otx_cpt_poll_misc(cptvf);
     405                 :            : 
     406                 :          0 :         return 0;
     407                 :            : }
     408                 :            : 
     409                 :            : static int
     410                 :          0 : otx_cpt_metabuf_mempool_create(const struct rte_cryptodev *dev,
     411                 :            :                                struct cpt_instance *instance, uint8_t qp_id,
     412                 :            :                                unsigned int nb_elements)
     413                 :            : {
     414                 :            :         char mempool_name[RTE_MEMPOOL_NAMESIZE];
     415                 :            :         struct cpt_qp_meta_info *meta_info;
     416                 :            :         struct rte_mempool *pool;
     417                 :            :         int max_mlen = 0;
     418                 :            :         int sg_mlen = 0;
     419                 :            :         int lb_mlen = 0;
     420                 :            :         int mb_pool_sz;
     421                 :            :         int ret;
     422                 :            : 
     423                 :            :         /*
     424                 :            :          * Calculate metabuf length required. The 'crypto_octeontx' device
     425                 :            :          * would be either SYMMETRIC or ASYMMETRIC.
     426                 :            :          */
     427                 :            : 
     428         [ #  # ]:          0 :         if (dev->feature_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) {
     429                 :            : 
     430                 :            :                 /* Get meta len for scatter gather mode */
     431                 :          0 :                 sg_mlen = cpt_pmd_ops_helper_get_mlen_sg_mode();
     432                 :            : 
     433                 :            :                 /* Extra 32B saved for future considerations */
     434                 :          0 :                 sg_mlen += 4 * sizeof(uint64_t);
     435                 :            : 
     436                 :            :                 /* Get meta len for linear buffer (direct) mode */
     437                 :          0 :                 lb_mlen = cpt_pmd_ops_helper_get_mlen_direct_mode();
     438                 :            : 
     439                 :            :                 /* Extra 32B saved for future considerations */
     440                 :          0 :                 lb_mlen += 4 * sizeof(uint64_t);
     441                 :            : 
     442                 :            :                 /* Check max requirement for meta buffer */
     443                 :          0 :                 max_mlen = RTE_MAX(lb_mlen, sg_mlen);
     444                 :            :         } else {
     445                 :            : 
     446                 :            :                 /* Asymmetric device */
     447                 :            : 
     448                 :            :                 /* Get meta len for asymmetric operations */
     449                 :          0 :                 max_mlen = cpt_pmd_ops_helper_asym_get_mlen();
     450                 :            :         }
     451                 :            : 
     452                 :            :         /* Allocate mempool */
     453                 :            : 
     454                 :          0 :         snprintf(mempool_name, RTE_MEMPOOL_NAMESIZE, "otx_cpt_mb_%u:%u",
     455                 :          0 :                  dev->data->dev_id, qp_id);
     456                 :            : 
     457                 :          0 :         mb_pool_sz = RTE_MAX(nb_elements, (METABUF_POOL_CACHE_SIZE * rte_lcore_count()));
     458                 :            : 
     459                 :          0 :         pool = rte_mempool_create_empty(mempool_name, mb_pool_sz, max_mlen,
     460                 :            :                                         METABUF_POOL_CACHE_SIZE, 0,
     461                 :          0 :                                         rte_socket_id(), 0);
     462                 :            : 
     463         [ #  # ]:          0 :         if (pool == NULL) {
     464                 :          0 :                 CPT_LOG_ERR("Could not create mempool for metabuf");
     465                 :          0 :                 return rte_errno;
     466                 :            :         }
     467                 :            : 
     468                 :          0 :         ret = rte_mempool_set_ops_byname(pool, RTE_MBUF_DEFAULT_MEMPOOL_OPS,
     469                 :            :                                          NULL);
     470         [ #  # ]:          0 :         if (ret) {
     471                 :          0 :                 CPT_LOG_ERR("Could not set mempool ops");
     472                 :          0 :                 goto mempool_free;
     473                 :            :         }
     474                 :            : 
     475                 :          0 :         ret = rte_mempool_populate_default(pool);
     476         [ #  # ]:          0 :         if (ret <= 0) {
     477                 :          0 :                 CPT_LOG_ERR("Could not populate metabuf pool");
     478                 :          0 :                 goto mempool_free;
     479                 :            :         }
     480                 :            : 
     481                 :            :         meta_info = &instance->meta_info;
     482                 :            : 
     483                 :          0 :         meta_info->pool = pool;
     484                 :          0 :         meta_info->lb_mlen = lb_mlen;
     485                 :          0 :         meta_info->sg_mlen = sg_mlen;
     486                 :            : 
     487                 :          0 :         return 0;
     488                 :            : 
     489                 :          0 : mempool_free:
     490                 :          0 :         rte_mempool_free(pool);
     491                 :          0 :         return ret;
     492                 :            : }
     493                 :            : 
     494                 :            : static void
     495                 :            : otx_cpt_metabuf_mempool_destroy(struct cpt_instance *instance)
     496                 :            : {
     497                 :            :         struct cpt_qp_meta_info *meta_info = &instance->meta_info;
     498                 :            : 
     499                 :          0 :         rte_mempool_free(meta_info->pool);
     500                 :            : 
     501                 :          0 :         meta_info->pool = NULL;
     502                 :          0 :         meta_info->lb_mlen = 0;
     503                 :          0 :         meta_info->sg_mlen = 0;
     504                 :          0 : }
     505                 :            : 
     506                 :            : int
     507                 :          0 : otx_cpt_get_resource(const struct rte_cryptodev *dev, uint8_t group,
     508                 :            :                      struct cpt_instance **instance, uint16_t qp_id)
     509                 :            : {
     510                 :            :         int ret = -ENOENT, len, qlen, i;
     511                 :            :         int chunk_len, chunks, chunk_size;
     512                 :          0 :         struct cpt_vf *cptvf = dev->data->dev_private;
     513                 :            :         struct cpt_instance *cpt_instance;
     514                 :            :         struct command_chunk *chunk_head = NULL, *chunk_prev = NULL;
     515                 :            :         struct command_chunk *chunk = NULL;
     516                 :            :         uint8_t *mem;
     517                 :            :         const struct rte_memzone *rz;
     518                 :            :         uint64_t dma_addr = 0, alloc_len, used_len;
     519                 :            :         uint64_t *next_ptr;
     520                 :          0 :         uint64_t pg_sz = sysconf(_SC_PAGESIZE);
     521                 :            : 
     522                 :            :         CPT_LOG_DP_DEBUG("Initializing cpt resource %s", cptvf->dev_name);
     523                 :            : 
     524                 :          0 :         cpt_instance = &cptvf->instance;
     525                 :            : 
     526                 :          0 :         memset(&cptvf->cqueue, 0, sizeof(cptvf->cqueue));
     527                 :          0 :         memset(&cptvf->pqueue, 0, sizeof(cptvf->pqueue));
     528                 :            : 
     529                 :            :         /* Chunks are of fixed size buffers */
     530                 :            : 
     531                 :            :         qlen = DEFAULT_CMD_QLEN;
     532                 :            :         chunks = DEFAULT_CMD_QCHUNKS;
     533                 :            :         chunk_len = DEFAULT_CMD_QCHUNK_SIZE;
     534                 :            :         /* Chunk size includes 8 bytes of next chunk ptr */
     535                 :            :         chunk_size = chunk_len * CPT_INST_SIZE + CPT_NEXT_CHUNK_PTR_SIZE;
     536                 :            : 
     537                 :            :         /* For command chunk structures */
     538                 :            :         len = chunks * RTE_ALIGN(sizeof(struct command_chunk), 8);
     539                 :            : 
     540                 :            :         /* For pending queue */
     541                 :            :         len += qlen * RTE_ALIGN(sizeof(cptvf->pqueue.rid_queue[0]), 8);
     542                 :            : 
     543                 :            :         /* So that instruction queues start as pg size aligned */
     544                 :          0 :         len = RTE_ALIGN(len, pg_sz);
     545                 :            : 
     546                 :            :         /* For Instruction queues */
     547                 :          0 :         len += chunks * RTE_ALIGN(chunk_size, 128);
     548                 :            : 
     549                 :            :         /* Wastage after instruction queues */
     550                 :          0 :         len = RTE_ALIGN(len, pg_sz);
     551                 :            : 
     552                 :          0 :         rz = rte_memzone_reserve_aligned(cptvf->dev_name, len, cptvf->node,
     553                 :            :                                          RTE_MEMZONE_SIZE_HINT_ONLY |
     554                 :            :                                          RTE_MEMZONE_256MB,
     555                 :            :                                          RTE_CACHE_LINE_SIZE);
     556         [ #  # ]:          0 :         if (!rz) {
     557                 :          0 :                 ret = rte_errno;
     558                 :          0 :                 goto exit;
     559                 :            :         }
     560                 :            : 
     561                 :          0 :         mem = rz->addr;
     562                 :          0 :         dma_addr = rz->iova;
     563                 :            :         alloc_len = len;
     564                 :            : 
     565                 :            :         memset(mem, 0, len);
     566                 :            : 
     567                 :          0 :         cpt_instance->rsvd = (uintptr_t)rz;
     568                 :            : 
     569                 :          0 :         ret = otx_cpt_metabuf_mempool_create(dev, cpt_instance, qp_id, qlen);
     570         [ #  # ]:          0 :         if (ret) {
     571                 :          0 :                 CPT_LOG_ERR("Could not create mempool for metabuf");
     572                 :          0 :                 goto memzone_free;
     573                 :            :         }
     574                 :            : 
     575                 :            :         /* Pending queue setup */
     576                 :          0 :         cptvf->pqueue.rid_queue = (void **)mem;
     577                 :            : 
     578                 :            :         mem +=  qlen * RTE_ALIGN(sizeof(cptvf->pqueue.rid_queue[0]), 8);
     579                 :          0 :         len -=  qlen * RTE_ALIGN(sizeof(cptvf->pqueue.rid_queue[0]), 8);
     580                 :          0 :         dma_addr += qlen * RTE_ALIGN(sizeof(cptvf->pqueue.rid_queue[0]), 8);
     581                 :            : 
     582                 :            :         /* Alignment wastage */
     583                 :          0 :         used_len = alloc_len - len;
     584                 :          0 :         mem += RTE_ALIGN(used_len, pg_sz) - used_len;
     585                 :          0 :         len -= RTE_ALIGN(used_len, pg_sz) - used_len;
     586                 :          0 :         dma_addr += RTE_ALIGN(used_len, pg_sz) - used_len;
     587                 :            : 
     588                 :            :         /* Init instruction queues */
     589                 :            :         chunk_head = &cptvf->cqueue.chead[0];
     590                 :            :         i = qlen;
     591                 :            : 
     592                 :            :         chunk_prev = NULL;
     593         [ #  # ]:          0 :         for (i = 0; i < DEFAULT_CMD_QCHUNKS; i++) {
     594                 :            :                 int csize;
     595                 :            : 
     596                 :          0 :                 chunk = &cptvf->cqueue.chead[i];
     597                 :          0 :                 chunk->head = mem;
     598                 :          0 :                 chunk->dma_addr = dma_addr;
     599                 :            : 
     600                 :            :                 csize = RTE_ALIGN(chunk_size, 128);
     601                 :          0 :                 mem += csize;
     602                 :          0 :                 dma_addr += csize;
     603                 :          0 :                 len -= csize;
     604                 :            : 
     605         [ #  # ]:          0 :                 if (chunk_prev) {
     606                 :          0 :                         next_ptr = (uint64_t *)(chunk_prev->head +
     607                 :            :                                                 chunk_size - 8);
     608                 :          0 :                         *next_ptr = (uint64_t)chunk->dma_addr;
     609                 :            :                 }
     610                 :            :                 chunk_prev = chunk;
     611                 :            :         }
     612                 :            :         /* Circular loop */
     613                 :          0 :         next_ptr = (uint64_t *)(chunk_prev->head + chunk_size - 8);
     614                 :          0 :         *next_ptr = (uint64_t)chunk_head->dma_addr;
     615                 :            : 
     616         [ #  # ]:          0 :         assert(!len);
     617                 :            : 
     618                 :            :         /* This is used for CPT(0)_PF_Q(0..15)_CTL.size config */
     619                 :          0 :         cptvf->qsize = chunk_size / 8;
     620                 :          0 :         cptvf->cqueue.qhead = chunk_head->head;
     621                 :          0 :         cptvf->cqueue.idx = 0;
     622                 :          0 :         cptvf->cqueue.cchunk = 0;
     623                 :            : 
     624         [ #  # ]:          0 :         if (cpt_vq_init(cptvf, group)) {
     625                 :          0 :                 CPT_LOG_ERR("Failed to initialize CPT VQ of device %s",
     626                 :            :                             cptvf->dev_name);
     627                 :            :                 ret = -EBUSY;
     628                 :          0 :                 goto mempool_destroy;
     629                 :            :         }
     630                 :            : 
     631                 :          0 :         *instance = cpt_instance;
     632                 :            : 
     633                 :            :         CPT_LOG_DP_DEBUG("Crypto device (%s) initialized", cptvf->dev_name);
     634                 :            : 
     635                 :          0 :         return 0;
     636                 :            : 
     637                 :            : mempool_destroy:
     638                 :            :         otx_cpt_metabuf_mempool_destroy(cpt_instance);
     639                 :          0 : memzone_free:
     640                 :          0 :         rte_memzone_free(rz);
     641                 :          0 : exit:
     642                 :          0 :         *instance = NULL;
     643                 :          0 :         return ret;
     644                 :            : }
     645                 :            : 
     646                 :            : int
     647                 :          0 : otx_cpt_put_resource(struct cpt_instance *instance)
     648                 :            : {
     649                 :            :         struct cpt_vf *cptvf = (struct cpt_vf *)instance;
     650                 :            :         struct rte_memzone *rz;
     651                 :            : 
     652         [ #  # ]:          0 :         if (!cptvf) {
     653                 :          0 :                 CPT_LOG_ERR("Invalid CPTVF handle");
     654                 :          0 :                 return -EINVAL;
     655                 :            :         }
     656                 :            : 
     657                 :            :         CPT_LOG_DP_DEBUG("Releasing cpt device %s", cptvf->dev_name);
     658                 :            : 
     659                 :            :         otx_cpt_metabuf_mempool_destroy(instance);
     660                 :            : 
     661                 :          0 :         rz = (struct rte_memzone *)instance->rsvd;
     662                 :          0 :         rte_memzone_free(rz);
     663                 :          0 :         return 0;
     664                 :            : }
     665                 :            : 
     666                 :            : int
     667                 :          0 : otx_cpt_start_device(void *dev)
     668                 :            : {
     669                 :            :         int rc;
     670                 :            :         struct cpt_vf *cptvf = (struct cpt_vf *)dev;
     671                 :            : 
     672                 :          0 :         rc = otx_cpt_send_vf_up(cptvf);
     673         [ #  # ]:          0 :         if (rc) {
     674                 :          0 :                 CPT_LOG_ERR("Failed to mark CPT VF device %s UP, rc = %d",
     675                 :            :                             cptvf->dev_name, rc);
     676                 :          0 :                 return -EFAULT;
     677                 :            :         }
     678                 :            : 
     679                 :            :         return 0;
     680                 :            : }
     681                 :            : 
     682                 :            : void
     683                 :          0 : otx_cpt_stop_device(void *dev)
     684                 :            : {
     685                 :            :         int rc;
     686                 :            :         uint32_t pending, retries = 5;
     687                 :            :         struct cpt_vf *cptvf = (struct cpt_vf *)dev;
     688                 :            : 
     689                 :            :         /* Wait for pending entries to complete */
     690                 :            :         pending = otx_cpt_read_vq_doorbell(cptvf);
     691         [ #  # ]:          0 :         while (pending) {
     692                 :            :                 CPT_LOG_DP_DEBUG("%s: Waiting for pending %u cmds to complete",
     693                 :            :                                  cptvf->dev_name, pending);
     694                 :          0 :                 sleep(1);
     695                 :            :                 pending = otx_cpt_read_vq_doorbell(cptvf);
     696                 :          0 :                 retries--;
     697         [ #  # ]:          0 :                 if (!retries)
     698                 :            :                         break;
     699                 :            :         }
     700                 :            : 
     701         [ #  # ]:          0 :         if (!retries && pending) {
     702                 :          0 :                 CPT_LOG_ERR("%s: Timeout waiting for commands(%u)",
     703                 :            :                             cptvf->dev_name, pending);
     704                 :          0 :                 return;
     705                 :            :         }
     706                 :            : 
     707                 :          0 :         rc = otx_cpt_send_vf_down(cptvf);
     708         [ #  # ]:          0 :         if (rc) {
     709                 :          0 :                 CPT_LOG_ERR("Failed to bring down vf %s, rc %d",
     710                 :            :                             cptvf->dev_name, rc);
     711                 :          0 :                 return;
     712                 :            :         }
     713                 :            : }

Generated by: LCOV version 1.14