LCOV - code coverage report
Current view: top level - drivers/crypto/octeontx - otx_cryptodev_hw_access.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 46 0.0 %
Date: 2024-04-01 19:00:53 Functions: 0 0 -
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 90 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018 Cavium, Inc
       3                 :            :  */
       4                 :            : #ifndef _OTX_CRYPTODEV_HW_ACCESS_H_
       5                 :            : #define _OTX_CRYPTODEV_HW_ACCESS_H_
       6                 :            : 
       7                 :            : #include <stdbool.h>
       8                 :            : 
       9                 :            : #include <rte_branch_prediction.h>
      10                 :            : #include <cryptodev_pmd.h>
      11                 :            : #include <rte_cycles.h>
      12                 :            : #include <rte_io.h>
      13                 :            : #include <rte_memory.h>
      14                 :            : #include <rte_prefetch.h>
      15                 :            : 
      16                 :            : #include "otx_cryptodev.h"
      17                 :            : 
      18                 :            : #include "cpt_common.h"
      19                 :            : #include "cpt_hw_types.h"
      20                 :            : #include "cpt_mcode_defines.h"
      21                 :            : #include "cpt_pmd_logs.h"
      22                 :            : 
      23                 :            : #define CPT_INTR_POLL_INTERVAL_MS       (50)
      24                 :            : 
      25                 :            : /* Default command queue length */
      26                 :            : #define DEFAULT_CMD_QLEN        2048
      27                 :            : #define DEFAULT_CMD_QCHUNKS     2
      28                 :            : 
      29                 :            : /* Instruction memory benefits from being 1023, so introduce
      30                 :            :  * reserved entries so we can't overrun the instruction queue
      31                 :            :  */
      32                 :            : #define DEFAULT_CMD_QRSVD_SLOTS DEFAULT_CMD_QCHUNKS
      33                 :            : #define DEFAULT_CMD_QCHUNK_SIZE \
      34                 :            :                 ((DEFAULT_CMD_QLEN - DEFAULT_CMD_QRSVD_SLOTS) / \
      35                 :            :                 DEFAULT_CMD_QCHUNKS)
      36                 :            : 
      37                 :            : #define CPT_CSR_REG_BASE(cpt)           ((cpt)->reg_base)
      38                 :            : 
      39                 :            : /* Read hw register */
      40                 :            : #define CPT_READ_CSR(__hw_addr, __offset) \
      41                 :            :         rte_read64_relaxed((uint8_t *)__hw_addr + __offset)
      42                 :            : 
      43                 :            : /* Write hw register */
      44                 :            : #define CPT_WRITE_CSR(__hw_addr, __offset, __val) \
      45                 :            :         rte_write64_relaxed((__val), ((uint8_t *)__hw_addr + __offset))
      46                 :            : 
      47                 :            : /* cpt instance */
      48                 :            : struct cpt_instance {
      49                 :            :         uint32_t queue_id;
      50                 :            :         uintptr_t rsvd;
      51                 :            :         struct rte_mempool *sess_mp;
      52                 :            :         struct cpt_qp_meta_info meta_info;
      53                 :            :         uint8_t ca_enabled;
      54                 :            : };
      55                 :            : 
      56                 :            : struct command_chunk {
      57                 :            :         /** 128-byte aligned real_vaddr */
      58                 :            :         uint8_t *head;
      59                 :            :         /** 128-byte aligned real_dma_addr */
      60                 :            :         phys_addr_t dma_addr;
      61                 :            : };
      62                 :            : 
      63                 :            : /**
      64                 :            :  * Command queue structure
      65                 :            :  */
      66                 :            : struct command_queue {
      67                 :            :         /** Command queue host write idx */
      68                 :            :         uint32_t idx;
      69                 :            :         /** Command queue chunk */
      70                 :            :         uint32_t cchunk;
      71                 :            :         /** Command queue head; instructions are inserted here */
      72                 :            :         uint8_t *qhead;
      73                 :            :         /** Command chunk list head */
      74                 :            :         struct command_chunk chead[DEFAULT_CMD_QCHUNKS];
      75                 :            : };
      76                 :            : 
      77                 :            : /**
      78                 :            :  * CPT VF device structure
      79                 :            :  */
      80                 :            : struct cpt_vf {
      81                 :            :         /** CPT instance */
      82                 :            :         struct cpt_instance instance;
      83                 :            :         /** Register start address */
      84                 :            :         uint8_t *reg_base;
      85                 :            :         /** Command queue information */
      86                 :            :         struct command_queue cqueue;
      87                 :            :         /** Pending queue information */
      88                 :            :         struct pending_queue pqueue;
      89                 :            : 
      90                 :            :         /** Below fields are accessed only in control path */
      91                 :            : 
      92                 :            :         /** Env specific pdev representing the pci dev */
      93                 :            :         void *pdev;
      94                 :            :         /** Calculated queue size */
      95                 :            :         uint32_t qsize;
      96                 :            :         /** Device index (0...CPT_MAX_VQ_NUM)*/
      97                 :            :         uint8_t  vfid;
      98                 :            :         /** VF type of cpt_vf_type_t (SE_TYPE(2) or AE_TYPE(1) */
      99                 :            :         uint8_t  vftype;
     100                 :            :         /** VF group (0 - 8) */
     101                 :            :         uint8_t  vfgrp;
     102                 :            :         /** Operating node: Bits (46:44) in BAR0 address */
     103                 :            :         uint8_t  node;
     104                 :            : 
     105                 :            :         /** VF-PF mailbox communication */
     106                 :            : 
     107                 :            :         /** Flag if acked */
     108                 :            :         bool pf_acked;
     109                 :            :         /** Flag if not acked */
     110                 :            :         bool pf_nacked;
     111                 :            : 
     112                 :            :         /** Device name */
     113                 :            :         char dev_name[32];
     114                 :            : } __rte_cache_aligned;
     115                 :            : 
     116                 :            : /*
     117                 :            :  * CPT Registers map for 81xx
     118                 :            :  */
     119                 :            : 
     120                 :            : /* VF registers */
     121                 :            : #define CPTX_VQX_CTL(a, b)              (0x0000100ll + 0x1000000000ll * \
     122                 :            :                                          ((a) & 0x0) + 0x100000ll * (b))
     123                 :            : #define CPTX_VQX_SADDR(a, b)            (0x0000200ll + 0x1000000000ll * \
     124                 :            :                                          ((a) & 0x0) + 0x100000ll * (b))
     125                 :            : #define CPTX_VQX_DONE_WAIT(a, b)        (0x0000400ll + 0x1000000000ll * \
     126                 :            :                                          ((a) & 0x0) + 0x100000ll * (b))
     127                 :            : #define CPTX_VQX_INPROG(a, b)           (0x0000410ll + 0x1000000000ll * \
     128                 :            :                                          ((a) & 0x0) + 0x100000ll * (b))
     129                 :            : #define CPTX_VQX_DONE(a, b)             (0x0000420ll + 0x1000000000ll * \
     130                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     131                 :            : #define CPTX_VQX_DONE_ACK(a, b)         (0x0000440ll + 0x1000000000ll * \
     132                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     133                 :            : #define CPTX_VQX_DONE_INT_W1S(a, b)     (0x0000460ll + 0x1000000000ll * \
     134                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     135                 :            : #define CPTX_VQX_DONE_INT_W1C(a, b)     (0x0000468ll + 0x1000000000ll * \
     136                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     137                 :            : #define CPTX_VQX_DONE_ENA_W1S(a, b)     (0x0000470ll + 0x1000000000ll * \
     138                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     139                 :            : #define CPTX_VQX_DONE_ENA_W1C(a, b)     (0x0000478ll + 0x1000000000ll * \
     140                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     141                 :            : #define CPTX_VQX_MISC_INT(a, b)         (0x0000500ll + 0x1000000000ll * \
     142                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     143                 :            : #define CPTX_VQX_MISC_INT_W1S(a, b)     (0x0000508ll + 0x1000000000ll * \
     144                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     145                 :            : #define CPTX_VQX_MISC_ENA_W1S(a, b)     (0x0000510ll + 0x1000000000ll * \
     146                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     147                 :            : #define CPTX_VQX_MISC_ENA_W1C(a, b)     (0x0000518ll + 0x1000000000ll * \
     148                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     149                 :            : #define CPTX_VQX_DOORBELL(a, b)         (0x0000600ll + 0x1000000000ll * \
     150                 :            :                                          ((a) & 0x1) + 0x100000ll * (b))
     151                 :            : #define CPTX_VFX_PF_MBOXX(a, b, c)      (0x0001000ll + 0x1000000000ll * \
     152                 :            :                                          ((a) & 0x1) + 0x100000ll * (b) + \
     153                 :            :                                          8ll * ((c) & 0x1))
     154                 :            : 
     155                 :            : /* VF HAL functions */
     156                 :            : 
     157                 :            : void
     158                 :            : otx_cpt_poll_misc(struct cpt_vf *cptvf);
     159                 :            : 
     160                 :            : int
     161                 :            : otx_cpt_hw_init(struct cpt_vf *cptvf, void *pdev, void *reg_base, char *name);
     162                 :            : 
     163                 :            : int
     164                 :            : otx_cpt_deinit_device(void *dev);
     165                 :            : 
     166                 :            : int
     167                 :            : otx_cpt_get_resource(const struct rte_cryptodev *dev, uint8_t group,
     168                 :            :                      struct cpt_instance **instance, uint16_t qp_id);
     169                 :            : 
     170                 :            : int
     171                 :            : otx_cpt_put_resource(struct cpt_instance *instance);
     172                 :            : 
     173                 :            : int
     174                 :            : otx_cpt_start_device(void *cptvf);
     175                 :            : 
     176                 :            : void
     177                 :            : otx_cpt_stop_device(void *cptvf);
     178                 :            : 
     179                 :            : /* Write to VQX_DOORBELL register
     180                 :            :  */
     181                 :            : static __rte_always_inline void
     182                 :            : otx_cpt_write_vq_doorbell(struct cpt_vf *cptvf, uint32_t val)
     183                 :            : {
     184                 :            :         cptx_vqx_doorbell_t vqx_dbell;
     185                 :            : 
     186                 :          0 :         vqx_dbell.u = 0;
     187                 :          0 :         vqx_dbell.s.dbell_cnt = val * 8; /* Num of Instructions * 8 words */
     188         [ #  # ]:          0 :         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
     189                 :            :                       CPTX_VQX_DOORBELL(0, 0), vqx_dbell.u);
     190                 :            : }
     191                 :            : 
     192                 :            : static __rte_always_inline uint32_t
     193                 :            : otx_cpt_read_vq_doorbell(struct cpt_vf *cptvf)
     194                 :            : {
     195                 :            :         cptx_vqx_doorbell_t vqx_dbell;
     196                 :            : 
     197         [ #  # ]:          0 :         vqx_dbell.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
     198                 :            :                                    CPTX_VQX_DOORBELL(0, 0));
     199         [ #  # ]:          0 :         return vqx_dbell.s.dbell_cnt;
     200                 :            : }
     201                 :            : 
     202                 :            : static __rte_always_inline void
     203                 :            : otx_cpt_ring_dbell(struct cpt_instance *instance, uint16_t count)
     204                 :            : {
     205                 :            :         struct cpt_vf *cptvf = (struct cpt_vf *)instance;
     206                 :            :         /* Memory barrier to flush pending writes */
     207                 :          0 :         rte_smp_wmb();
     208                 :            :         otx_cpt_write_vq_doorbell(cptvf, count);
     209                 :          0 : }
     210                 :            : 
     211                 :            : static __rte_always_inline void *
     212                 :            : get_cpt_inst(struct command_queue *cqueue)
     213                 :            : {
     214                 :            :         CPT_LOG_DP_DEBUG("CPT queue idx %u\n", cqueue->idx);
     215                 :          0 :         return &cqueue->qhead[cqueue->idx * CPT_INST_SIZE];
     216                 :            : }
     217                 :            : 
     218                 :            : static __rte_always_inline void
     219                 :            : fill_cpt_inst(struct cpt_instance *instance, void *req, uint64_t ucmd_w3)
     220                 :            : {
     221                 :            :         struct command_queue *cqueue;
     222                 :            :         cpt_inst_s_t *cpt_ist_p;
     223                 :            :         struct cpt_vf *cptvf = (struct cpt_vf *)instance;
     224                 :            :         struct cpt_request_info *user_req = (struct cpt_request_info *)req;
     225                 :            :         cqueue = &cptvf->cqueue;
     226                 :            :         cpt_ist_p = get_cpt_inst(cqueue);
     227                 :          0 :         rte_prefetch_non_temporal(cpt_ist_p);
     228                 :            : 
     229                 :            :         /* EI0, EI1, EI2, EI3 are already prepared */
     230                 :            :         /* HW W0 */
     231                 :          0 :         cpt_ist_p->u[0] = 0;
     232                 :            :         /* HW W1 */
     233                 :          0 :         cpt_ist_p->s8x.res_addr = user_req->comp_baddr;
     234                 :            :         /* HW W2 */
     235                 :          0 :         cpt_ist_p->u[2] = 0;
     236                 :            :         /* HW W3 */
     237                 :          0 :         cpt_ist_p->s8x.wq_ptr = 0;
     238                 :            : 
     239                 :            :         /* MC EI0 */
     240                 :          0 :         cpt_ist_p->s8x.ei0 = user_req->ist.ei0;
     241                 :            :         /* MC EI1 */
     242                 :          0 :         cpt_ist_p->s8x.ei1 = user_req->ist.ei1;
     243                 :            :         /* MC EI2 */
     244                 :          0 :         cpt_ist_p->s8x.ei2 = user_req->ist.ei2;
     245                 :            :         /* MC EI3 */
     246                 :          0 :         cpt_ist_p->s8x.ei3 = ucmd_w3;
     247                 :            : }
     248                 :            : 
     249                 :            : static __rte_always_inline void
     250                 :            : mark_cpt_inst(struct cpt_instance *instance)
     251                 :            : {
     252                 :            :         struct cpt_vf *cptvf = (struct cpt_vf *)instance;
     253                 :            :         struct command_queue *queue = &cptvf->cqueue;
     254   [ #  #  #  #  :          0 :         if (unlikely(++queue->idx >= DEFAULT_CMD_QCHUNK_SIZE)) {
          #  #  #  #  #  
                #  #  # ]
     255                 :          0 :                 uint32_t cchunk = queue->cchunk;
     256   [ #  #  #  #  :          0 :                 MOD_INC(cchunk, DEFAULT_CMD_QCHUNKS);
          #  #  #  #  #  
                #  #  # ]
     257                 :          0 :                 queue->qhead = queue->chead[cchunk].head;
     258                 :          0 :                 queue->idx = 0;
     259                 :          0 :                 queue->cchunk = cchunk;
     260                 :            :         }
     261                 :            : }
     262                 :            : 
     263                 :            : static __rte_always_inline uint8_t
     264                 :            : check_nb_command_id(struct cpt_request_info *user_req,
     265                 :            :                 struct cpt_instance *instance)
     266                 :            : {
     267                 :            :         uint8_t ret = ERR_REQ_PENDING;
     268                 :            :         struct cpt_vf *cptvf = (struct cpt_vf *)instance;
     269                 :            :         volatile cpt_res_s_t *cptres;
     270                 :            : 
     271                 :          0 :         cptres = (volatile cpt_res_s_t *)user_req->completion_addr;
     272                 :            : 
     273   [ #  #  #  #  :          0 :         if (unlikely(cptres->s8x.compcode == CPT_8X_COMP_E_NOTDONE)) {
                   #  # ]
     274                 :            :                 /*
     275                 :            :                  * Wait for some time for this command to get completed
     276                 :            :                  * before timing out
     277                 :            :                  */
     278   [ #  #  #  #  :          0 :                 if (rte_get_timer_cycles() < user_req->time_out)
                   #  # ]
     279                 :            :                         return ret;
     280                 :            :                 /*
     281                 :            :                  * TODO: See if alternate caddr can be used to not loop
     282                 :            :                  * longer than needed.
     283                 :            :                  */
     284   [ #  #  #  #  :          0 :                 if ((cptres->s8x.compcode == CPT_8X_COMP_E_NOTDONE) &&
                   #  # ]
     285   [ #  #  #  #  :          0 :                     (user_req->extra_time < TIME_IN_RESET_COUNT)) {
                   #  # ]
     286                 :          0 :                         user_req->extra_time++;
     287                 :          0 :                         return ret;
     288                 :            :                 }
     289                 :            : 
     290   [ #  #  #  #  :          0 :                 if (cptres->s8x.compcode != CPT_8X_COMP_E_NOTDONE)
                   #  # ]
     291                 :          0 :                         goto complete;
     292                 :            : 
     293                 :            :                 ret = ERR_REQ_TIMEOUT;
     294                 :          0 :                 CPT_LOG_DP_ERR("Request %p timedout", user_req);
     295                 :          0 :                 otx_cpt_poll_misc(cptvf);
     296                 :          0 :                 goto exit;
     297                 :            :         }
     298                 :            : 
     299                 :          0 : complete:
     300   [ #  #  #  #  :          0 :         if (likely(cptres->s8x.compcode == CPT_8X_COMP_E_GOOD)) {
                   #  # ]
     301                 :            :                 ret = 0; /* success */
     302   [ #  #  #  #  :          0 :                 if (unlikely((uint8_t)*user_req->alternate_caddr)) {
                   #  # ]
     303                 :          0 :                         ret = (uint8_t)*user_req->alternate_caddr;
     304                 :          0 :                         CPT_LOG_DP_ERR("Request %p : failed with microcode"
     305                 :            :                                 " error, MC completion code : 0x%x", user_req,
     306                 :            :                                 ret);
     307                 :            :                 }
     308                 :            :                 CPT_LOG_DP_DEBUG("MC status %.8x\n",
     309                 :            :                            *((volatile uint32_t *)user_req->alternate_caddr));
     310                 :            :                 CPT_LOG_DP_DEBUG("HW status %.8x\n",
     311                 :            :                            *((volatile uint32_t *)user_req->completion_addr));
     312   [ #  #  #  #  :          0 :         } else if ((cptres->s8x.compcode == CPT_8X_COMP_E_SWERR) ||
                   #  # ]
     313   [ #  #  #  #  :          0 :                    (cptres->s8x.compcode == CPT_8X_COMP_E_FAULT)) {
                   #  # ]
     314                 :          0 :                 ret = (uint8_t)*user_req->alternate_caddr;
     315   [ #  #  #  #  :          0 :                 if (!ret)
                   #  # ]
     316                 :            :                         ret = ERR_BAD_ALT_CCODE;
     317                 :            :                 CPT_LOG_DP_DEBUG("Request %p : failed with %s : err code :%x",
     318                 :            :                            user_req,
     319                 :            :                            (cptres->s8x.compcode == CPT_8X_COMP_E_FAULT) ?
     320                 :            :                            "DMA Fault" : "Software error", ret);
     321                 :            :         } else {
     322                 :          0 :                 CPT_LOG_DP_ERR("Request %p : unexpected completion code %d",
     323                 :            :                            user_req, cptres->s8x.compcode);
     324                 :          0 :                 ret = (uint8_t)*user_req->alternate_caddr;
     325                 :            :         }
     326                 :            : 
     327                 :            : exit:
     328                 :            :         return ret;
     329                 :            : }
     330                 :            : 
     331                 :            : #endif /* _OTX_CRYPTODEV_HW_ACCESS_H_ */

Generated by: LCOV version 1.14