LCOV - code coverage report
Current view: top level - drivers/crypto/ionic - ionic_crypto_ops.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 246 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 18 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 97 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2021-2024 Advanced Micro Devices, Inc.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_cryptodev.h>
       6                 :            : #include <cryptodev_pmd.h>
       7                 :            : #include <rte_errno.h>
       8                 :            : #include <rte_malloc.h>
       9                 :            : #include <rte_mempool.h>
      10                 :            : 
      11                 :            : #include "ionic_crypto.h"
      12                 :            : 
      13                 :            : static int
      14                 :          0 : iocpt_op_config(struct rte_cryptodev *cdev,
      15                 :            :                 struct rte_cryptodev_config *config __rte_unused)
      16                 :            : {
      17                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
      18                 :            : 
      19                 :          0 :         iocpt_configure(dev);
      20                 :            : 
      21                 :          0 :         return 0;
      22                 :            : }
      23                 :            : 
      24                 :            : static int
      25                 :          0 : iocpt_op_start(struct rte_cryptodev *cdev)
      26                 :            : {
      27                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
      28                 :            : 
      29                 :          0 :         return iocpt_start(dev);
      30                 :            : }
      31                 :            : 
      32                 :            : static void
      33                 :          0 : iocpt_op_stop(struct rte_cryptodev *cdev)
      34                 :            : {
      35                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
      36                 :            : 
      37                 :          0 :         return iocpt_stop(dev);
      38                 :            : }
      39                 :            : 
      40                 :            : static int
      41                 :          0 : iocpt_op_close(struct rte_cryptodev *cdev)
      42                 :            : {
      43                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
      44                 :            : 
      45                 :          0 :         iocpt_deinit(dev);
      46                 :            : 
      47                 :          0 :         return 0;
      48                 :            : }
      49                 :            : 
      50                 :            : static void
      51                 :          0 : iocpt_op_info_get(struct rte_cryptodev *cdev, struct rte_cryptodev_info *info)
      52                 :            : {
      53                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
      54                 :            : 
      55         [ #  # ]:          0 :         if (info == NULL)
      56                 :            :                 return;
      57                 :            : 
      58                 :          0 :         info->max_nb_queue_pairs = dev->max_qps;
      59                 :          0 :         info->feature_flags = dev->features;
      60                 :          0 :         info->capabilities = iocpt_get_caps(info->feature_flags);
      61                 :            :         /* Reserve one session for watchdog */
      62                 :          0 :         info->sym.max_nb_sessions = dev->max_sessions - 1;
      63                 :          0 :         info->driver_id = dev->driver_id;
      64                 :          0 :         info->min_mbuf_headroom_req = 0;
      65                 :          0 :         info->min_mbuf_tailroom_req = 0;
      66                 :            : }
      67                 :            : 
      68                 :            : static void
      69                 :          0 : iocpt_op_stats_get(struct rte_cryptodev *cdev,
      70                 :            :                 struct rte_cryptodev_stats *stats)
      71                 :            : {
      72                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
      73                 :            : 
      74                 :          0 :         iocpt_get_stats(dev, stats);
      75                 :          0 : }
      76                 :            : 
      77                 :            : static void
      78                 :          0 : iocpt_op_stats_reset(struct rte_cryptodev *cdev)
      79                 :            : {
      80                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
      81                 :            : 
      82                 :          0 :         iocpt_reset_stats(dev);
      83                 :          0 : }
      84                 :            : 
      85                 :            : static int
      86                 :          0 : iocpt_op_queue_release(struct rte_cryptodev *cdev, uint16_t queue_id)
      87                 :            : {
      88                 :          0 :         struct iocpt_crypto_q *cptq = cdev->data->queue_pairs[queue_id];
      89                 :            : 
      90                 :          0 :         IOCPT_PRINT(DEBUG, "queue_id %u", queue_id);
      91                 :            : 
      92         [ #  # ]:          0 :         assert(!(cptq->flags & IOCPT_Q_F_INITED));
      93                 :            : 
      94                 :          0 :         iocpt_cryptoq_free(cptq);
      95                 :            : 
      96                 :          0 :         cdev->data->queue_pairs[queue_id] = NULL;
      97                 :            : 
      98                 :          0 :         return 0;
      99                 :            : }
     100                 :            : 
     101                 :            : static int
     102                 :          0 : iocpt_op_queue_setup(struct rte_cryptodev *cdev, uint16_t queue_id,
     103                 :            :                 const struct rte_cryptodev_qp_conf *qp_conf,
     104                 :            :                 int socket_id)
     105                 :            : {
     106                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
     107                 :            :         int err;
     108                 :            : 
     109         [ #  # ]:          0 :         if (cdev->data->queue_pairs[queue_id] != NULL)
     110                 :          0 :                 iocpt_op_queue_release(cdev, queue_id);
     111                 :            : 
     112         [ #  # ]:          0 :         if (qp_conf->nb_descriptors < (1 << IOCPT_QSIZE_MIN_LG2) ||
     113                 :            :             qp_conf->nb_descriptors > (1 << IOCPT_QSIZE_MAX_LG2)) {
     114                 :          0 :                 IOCPT_PRINT(ERR, "invalid nb_descriptors %u, use range %u..%u",
     115                 :            :                         qp_conf->nb_descriptors,
     116                 :            :                         1 << IOCPT_QSIZE_MIN_LG2, 1 << IOCPT_QSIZE_MAX_LG2);
     117                 :          0 :                 return -ERANGE;
     118                 :            :         }
     119                 :            : 
     120                 :          0 :         IOCPT_PRINT(DEBUG, "queue_id %u", queue_id);
     121                 :            : 
     122                 :          0 :         err = iocpt_cryptoq_alloc(dev, socket_id, queue_id,
     123                 :          0 :                                 qp_conf->nb_descriptors);
     124         [ #  # ]:          0 :         if (err != 0)
     125                 :            :                 return err;
     126                 :            : 
     127                 :          0 :         cdev->data->queue_pairs[queue_id] = dev->cryptoqs[queue_id];
     128                 :            : 
     129                 :          0 :         return 0;
     130                 :            : }
     131                 :            : 
     132                 :            : static unsigned int
     133                 :          0 : iocpt_op_get_session_size(struct rte_cryptodev *cdev __rte_unused)
     134                 :            : {
     135                 :          0 :         return iocpt_session_size();
     136                 :            : }
     137                 :            : 
     138                 :            : static inline int
     139                 :          0 : iocpt_is_algo_supported(struct rte_crypto_sym_xform *xform)
     140                 :            : {
     141         [ #  # ]:          0 :         if (xform->next != NULL) {
     142                 :          0 :                 IOCPT_PRINT(ERR, "chaining not supported");
     143                 :          0 :                 return -ENOTSUP;
     144                 :            :         }
     145                 :            : 
     146         [ #  # ]:          0 :         if (xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
     147                 :          0 :                 IOCPT_PRINT(ERR, "xform->type %d not supported", xform->type);
     148                 :          0 :                 return -ENOTSUP;
     149                 :            :         }
     150                 :            : 
     151                 :            :         return 0;
     152                 :            : }
     153                 :            : 
     154                 :            : static __rte_always_inline int
     155                 :            : iocpt_fill_sess_aead(struct rte_crypto_sym_xform *xform,
     156                 :            :                 struct iocpt_session_priv *priv)
     157                 :            : {
     158                 :            :         struct rte_crypto_aead_xform *aead_form = &xform->aead;
     159                 :            : 
     160         [ #  # ]:          0 :         if (aead_form->algo != RTE_CRYPTO_AEAD_AES_GCM) {
     161                 :          0 :                 IOCPT_PRINT(ERR, "Unknown algo");
     162                 :            :                 return -EINVAL;
     163                 :            :         }
     164         [ #  # ]:          0 :         if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
     165                 :          0 :                 priv->op = IOCPT_DESC_OPCODE_GCM_AEAD_ENCRYPT;
     166         [ #  # ]:          0 :         } else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT) {
     167                 :          0 :                 priv->op = IOCPT_DESC_OPCODE_GCM_AEAD_DECRYPT;
     168                 :            :         } else {
     169                 :          0 :                 IOCPT_PRINT(ERR, "Unknown cipher operations");
     170                 :            :                 return -1;
     171                 :            :         }
     172                 :            : 
     173         [ #  # ]:          0 :         if (aead_form->key.length < IOCPT_SESS_KEY_LEN_MIN ||
     174                 :            :             aead_form->key.length > IOCPT_SESS_KEY_LEN_MAX_SYMM) {
     175                 :          0 :                 IOCPT_PRINT(ERR, "Invalid cipher keylen %u",
     176                 :            :                         aead_form->key.length);
     177                 :            :                 return -1;
     178                 :            :         }
     179                 :          0 :         priv->key_len = aead_form->key.length;
     180                 :          0 :         memcpy(priv->key, aead_form->key.data, priv->key_len);
     181                 :            : 
     182                 :          0 :         priv->type = IOCPT_SESS_AEAD_AES_GCM;
     183                 :          0 :         priv->iv_offset = aead_form->iv.offset;
     184                 :          0 :         priv->iv_length = aead_form->iv.length;
     185                 :          0 :         priv->digest_length = aead_form->digest_length;
     186                 :          0 :         priv->aad_length = aead_form->aad_length;
     187                 :            : 
     188                 :            :         return 0;
     189                 :            : }
     190                 :            : 
     191                 :            : static int
     192                 :          0 : iocpt_session_cfg(struct iocpt_dev *dev,
     193                 :            :                 struct rte_crypto_sym_xform *xform,
     194                 :            :                 struct rte_cryptodev_sym_session *sess)
     195                 :            : {
     196                 :            :         struct rte_crypto_sym_xform *chain;
     197                 :            :         struct iocpt_session_priv *priv = NULL;
     198                 :            : 
     199         [ #  # ]:          0 :         if (iocpt_is_algo_supported(xform) < 0)
     200                 :            :                 return -ENOTSUP;
     201                 :            : 
     202         [ #  # ]:          0 :         if (unlikely(sess == NULL)) {
     203                 :          0 :                 IOCPT_PRINT(ERR, "invalid session");
     204                 :          0 :                 return -EINVAL;
     205                 :            :         }
     206                 :            : 
     207                 :          0 :         priv = CRYPTODEV_GET_SYM_SESS_PRIV(sess);
     208                 :          0 :         priv->dev = dev;
     209                 :            : 
     210                 :            :         chain = xform;
     211         [ #  # ]:          0 :         while (chain) {
     212         [ #  # ]:          0 :                 switch (chain->type) {
     213                 :            :                 case RTE_CRYPTO_SYM_XFORM_AEAD:
     214                 :            :                         if (iocpt_fill_sess_aead(chain, priv))
     215                 :          0 :                                 return -EIO;
     216                 :            :                         break;
     217                 :          0 :                 default:
     218                 :          0 :                         IOCPT_PRINT(ERR, "invalid crypto xform type %d",
     219                 :            :                                 chain->type);
     220                 :          0 :                         return -ENOTSUP;
     221                 :            :                 }
     222                 :          0 :                 chain = chain->next;
     223                 :            :         }
     224                 :            : 
     225                 :          0 :         return iocpt_session_init(priv);
     226                 :            : }
     227                 :            : 
     228                 :            : static int
     229                 :          0 : iocpt_op_session_cfg(struct rte_cryptodev *cdev,
     230                 :            :                 struct rte_crypto_sym_xform *xform,
     231                 :            :                 struct rte_cryptodev_sym_session *sess)
     232                 :            : {
     233                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
     234                 :            : 
     235                 :          0 :         return iocpt_session_cfg(dev, xform, sess);
     236                 :            : }
     237                 :            : 
     238                 :            : static void
     239                 :            : iocpt_session_clear(struct rte_cryptodev_sym_session *sess)
     240                 :            : {
     241                 :          0 :         iocpt_session_deinit(CRYPTODEV_GET_SYM_SESS_PRIV(sess));
     242                 :            : }
     243                 :            : 
     244                 :            : static void
     245                 :          0 : iocpt_op_session_clear(struct rte_cryptodev *cdev __rte_unused,
     246                 :            :                 struct rte_cryptodev_sym_session *sess)
     247                 :            : {
     248                 :            :         iocpt_session_clear(sess);
     249                 :          0 : }
     250                 :            : 
     251                 :            : static inline void
     252                 :            : iocpt_fill_sge(struct iocpt_crypto_sg_elem *arr, uint8_t idx,
     253                 :            :                 uint64_t addr, uint16_t len)
     254                 :            : {
     255                 :          0 :         arr[idx].addr = rte_cpu_to_le_64(addr);
     256                 :          0 :         arr[idx].len = rte_cpu_to_le_16(len);
     257                 :          0 : }
     258                 :            : 
     259                 :            : static __rte_always_inline int
     260                 :            : iocpt_enq_one_aead(struct iocpt_crypto_q *cptq,
     261                 :            :                 struct iocpt_session_priv *priv, struct rte_crypto_op *op)
     262                 :            : {
     263                 :            :         struct rte_crypto_sym_op *sym_op = op->sym;
     264                 :            :         struct iocpt_queue *q = &cptq->q;
     265                 :          0 :         struct iocpt_crypto_desc *desc, *desc_base = q->base;
     266                 :          0 :         struct iocpt_crypto_sg_desc *sg_desc, *sg_desc_base = q->sg_base;
     267                 :            :         struct iocpt_crypto_sg_elem *src, *dst;
     268                 :            :         rte_iova_t aad_addr, digest_addr, iv_addr, seg_addr;
     269                 :            :         uint32_t data_len, data_offset, seg_len;
     270                 :            :         uint8_t nsge_src = 0, nsge_dst = 0, flags = 0;
     271                 :            :         struct rte_mbuf *m;
     272                 :            : 
     273                 :          0 :         desc = &desc_base[q->head_idx];
     274                 :          0 :         sg_desc = &sg_desc_base[q->head_idx];
     275                 :          0 :         src = sg_desc->src_elems;
     276                 :          0 :         dst = sg_desc->dst_elems;
     277                 :            : 
     278                 :            :         /* Fill the first SGE with the IV / Nonce */
     279                 :          0 :         iv_addr = rte_crypto_op_ctophys_offset(op, priv->iv_offset);
     280                 :          0 :         iocpt_fill_sge(src, nsge_src++, iv_addr, priv->iv_length);
     281                 :            : 
     282                 :            :         /* Fill the second SGE with the AAD, if applicable */
     283                 :          0 :         if (priv->aad_length > 0) {
     284                 :          0 :                 aad_addr = sym_op->aead.aad.phys_addr;
     285                 :            :                 iocpt_fill_sge(src, nsge_src++, aad_addr, priv->aad_length);
     286                 :            :                 flags |= IOCPT_DESC_F_AAD_VALID;
     287                 :            :         }
     288                 :            : 
     289                 :          0 :         m = sym_op->m_src;
     290                 :          0 :         data_len = sym_op->aead.data.length;
     291                 :            : 
     292                 :            :         /* Fast-forward through mbuf chain to account for data offset */
     293                 :          0 :         data_offset = sym_op->aead.data.offset;
     294   [ #  #  #  # ]:          0 :         while (m != NULL && data_offset >= m->data_len) {
     295                 :          0 :                 data_offset -= m->data_len;
     296                 :          0 :                 m = m->next;
     297                 :            :         }
     298                 :            : 
     299                 :            :         /* Fill the next SGEs with the payload segments */
     300         [ #  # ]:          0 :         while (m != NULL && data_len > 0) {
     301                 :          0 :                 seg_addr = rte_mbuf_data_iova(m) + data_offset;
     302                 :          0 :                 seg_len = RTE_MIN(m->data_len - data_offset, data_len);
     303                 :            :                 data_offset = 0;
     304                 :          0 :                 data_len -= seg_len;
     305                 :            : 
     306                 :            :                 /* Use -1 to save room for digest */
     307         [ #  # ]:          0 :                 if (nsge_src >= IOCPT_CRYPTO_MAX_SG_ELEMS - 1)
     308                 :            :                         return -ERANGE;
     309                 :            : 
     310                 :          0 :                 iocpt_fill_sge(src, nsge_src++, seg_addr, seg_len);
     311                 :            : 
     312                 :          0 :                 m = m->next;
     313                 :            :         }
     314                 :            : 
     315                 :            :         /* AEAD AES-GCM: digest == authentication tag */
     316                 :          0 :         digest_addr = sym_op->aead.digest.phys_addr;
     317                 :          0 :         iocpt_fill_sge(src, nsge_src++, digest_addr, priv->digest_length);
     318                 :            : 
     319                 :            :         /* Process Out-Of-Place destination SGL */
     320         [ #  # ]:          0 :         if (sym_op->m_dst != NULL) {
     321                 :            :                 /* Put the AAD here, too */
     322         [ #  # ]:          0 :                 if (priv->aad_length > 0)
     323                 :          0 :                         iocpt_fill_sge(dst, nsge_dst++,
     324                 :            :                                 sym_op->aead.aad.phys_addr, priv->aad_length);
     325                 :            : 
     326                 :            :                 m = sym_op->m_dst;
     327                 :            :                 data_len = sym_op->aead.data.length;
     328                 :            : 
     329                 :            :                 /* Fast-forward through chain to account for data offset */
     330                 :            :                 data_offset = sym_op->aead.data.offset;
     331   [ #  #  #  # ]:          0 :                 while (m != NULL && data_offset >= m->data_len) {
     332                 :          0 :                         data_offset -= m->data_len;
     333                 :          0 :                         m = m->next;
     334                 :            :                 }
     335                 :            : 
     336                 :            :                 /* Fill in the SGEs with the payload segments */
     337         [ #  # ]:          0 :                 while (m != NULL && data_len > 0) {
     338                 :          0 :                         seg_addr = rte_mbuf_data_iova(m) + data_offset;
     339                 :          0 :                         seg_len = RTE_MIN(m->data_len - data_offset, data_len);
     340                 :            :                         data_offset = 0;
     341                 :          0 :                         data_len -= seg_len;
     342                 :            : 
     343         [ #  # ]:          0 :                         if (nsge_dst >= IOCPT_CRYPTO_MAX_SG_ELEMS)
     344                 :            :                                 return -ERANGE;
     345                 :            : 
     346                 :          0 :                         iocpt_fill_sge(dst, nsge_dst++, seg_addr, seg_len);
     347                 :            : 
     348                 :          0 :                         m = m->next;
     349                 :            :                 }
     350                 :            :         }
     351                 :            : 
     352                 :          0 :         desc->opcode = priv->op;
     353                 :          0 :         desc->flags = flags;
     354                 :          0 :         desc->num_src_dst_sgs = iocpt_encode_nsge_src_dst(nsge_src, nsge_dst);
     355                 :          0 :         desc->session_tag = rte_cpu_to_le_32(priv->index);
     356                 :            : 
     357                 :          0 :         op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
     358                 :          0 :         q->info[q->head_idx] = op;
     359                 :          0 :         q->head_idx = Q_NEXT_TO_POST(q, 1);
     360                 :            : 
     361                 :          0 :         return 0;
     362                 :            : }
     363                 :            : 
     364                 :            : static uint16_t
     365         [ #  # ]:          0 : iocpt_enqueue_sym(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
     366                 :            : {
     367                 :            :         struct iocpt_crypto_q *cptq = qp;
     368                 :            :         struct rte_crypto_op *op;
     369                 :            :         struct iocpt_session_priv *priv;
     370                 :            :         struct rte_cryptodev_stats *stats = &cptq->stats;
     371                 :            :         uint16_t avail, count;
     372                 :            :         int err;
     373                 :            : 
     374                 :            :         avail = iocpt_q_space_avail(&cptq->q);
     375         [ #  # ]:          0 :         if (unlikely(nb_ops > avail))
     376                 :            :                 nb_ops = avail;
     377                 :            : 
     378                 :            :         count = 0;
     379         [ #  # ]:          0 :         while (likely(count < nb_ops)) {
     380                 :          0 :                 op = ops[count];
     381                 :            : 
     382         [ #  # ]:          0 :                 if (unlikely(op->sess_type != RTE_CRYPTO_OP_WITH_SESSION)) {
     383                 :          0 :                         op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
     384                 :          0 :                         break;
     385                 :            :                 }
     386                 :            : 
     387         [ #  # ]:          0 :                 priv = CRYPTODEV_GET_SYM_SESS_PRIV(op->sym->session);
     388                 :            :                 if (unlikely(priv == NULL)) {
     389                 :            :                         op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
     390                 :            :                         break;
     391                 :            :                 }
     392                 :            : 
     393                 :            :                 err = iocpt_enq_one_aead(cptq, priv, op);
     394         [ #  # ]:          0 :                 if (unlikely(err != 0)) {
     395                 :          0 :                         op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
     396                 :          0 :                         stats->enqueue_err_count++;
     397                 :          0 :                         break;
     398                 :            :                 }
     399                 :            : 
     400                 :          0 :                 count++;
     401                 :            :         }
     402                 :            : 
     403         [ #  # ]:          0 :         if (likely(count > 0)) {
     404                 :            :                 iocpt_q_flush(&cptq->q);
     405                 :            : 
     406                 :            :                 /* Restart timer if ops are being enqueued */
     407                 :          0 :                 cptq->last_wdog_cycles = rte_get_timer_cycles();
     408                 :            : 
     409                 :          0 :                 stats->enqueued_count += count;
     410                 :            :         }
     411                 :            : 
     412                 :          0 :         return count;
     413                 :            : }
     414                 :            : 
     415                 :            : static void
     416                 :          0 : iocpt_enqueue_wdog(struct iocpt_crypto_q *cptq)
     417                 :            : {
     418                 :            :         struct iocpt_queue *q = &cptq->q;
     419                 :          0 :         struct iocpt_crypto_desc *desc, *desc_base = q->base;
     420         [ #  # ]:          0 :         struct iocpt_crypto_sg_desc *sg_desc, *sg_desc_base = q->sg_base;
     421                 :            :         struct iocpt_crypto_sg_elem *src;
     422                 :            :         struct rte_crypto_op *wdog_op;
     423                 :            :         rte_iova_t iv_addr, pld_addr, tag_addr;
     424                 :            :         uint8_t nsge_src = 0;
     425                 :            :         uint16_t avail;
     426                 :            : 
     427                 :            :         avail = iocpt_q_space_avail(&cptq->q);
     428         [ #  # ]:          0 :         if (avail < 1)
     429                 :          0 :                 goto out_flush;
     430                 :            : 
     431                 :          0 :         wdog_op = rte_zmalloc_socket("iocpt", sizeof(*wdog_op),
     432                 :          0 :                                 RTE_CACHE_LINE_SIZE, rte_socket_id());
     433         [ #  # ]:          0 :         if (wdog_op == NULL)
     434                 :          0 :                 goto out_flush;
     435                 :            : 
     436                 :          0 :         wdog_op->type = IOCPT_Q_WDOG_OP_TYPE;
     437                 :          0 :         wdog_op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
     438                 :            : 
     439                 :          0 :         desc = &desc_base[q->head_idx];
     440                 :          0 :         sg_desc = &sg_desc_base[q->head_idx];
     441                 :            :         src = sg_desc->src_elems;
     442                 :            : 
     443                 :            :         /* Fill the first SGE with the IV / Nonce */
     444                 :          0 :         iv_addr = rte_mem_virt2iova(cptq->wdog_iv);
     445                 :            :         iocpt_fill_sge(src, nsge_src++, iv_addr, IOCPT_Q_WDOG_IV_LEN);
     446                 :            : 
     447                 :            :         /* Fill the second SGE with the payload segment */
     448                 :          0 :         pld_addr = rte_mem_virt2iova(cptq->wdog_pld);
     449                 :            :         iocpt_fill_sge(src, nsge_src++, pld_addr, IOCPT_Q_WDOG_PLD_LEN);
     450                 :            : 
     451                 :            :         /* AEAD AES-GCM: digest == authentication tag */
     452                 :          0 :         tag_addr = rte_mem_virt2iova(cptq->wdog_tag);
     453                 :            :         iocpt_fill_sge(src, nsge_src++, tag_addr, IOCPT_Q_WDOG_TAG_LEN);
     454                 :            : 
     455                 :          0 :         desc->opcode = IOCPT_DESC_OPCODE_GCM_AEAD_ENCRYPT;
     456                 :          0 :         desc->flags = 0;
     457                 :          0 :         desc->num_src_dst_sgs = iocpt_encode_nsge_src_dst(nsge_src, 0);
     458                 :          0 :         desc->session_tag = rte_cpu_to_le_32(IOCPT_Q_WDOG_SESS_IDX);
     459                 :            : 
     460                 :          0 :         q->info[q->head_idx] = wdog_op;
     461                 :          0 :         q->head_idx = Q_NEXT_TO_POST(q, 1);
     462                 :            : 
     463                 :          0 :         IOCPT_PRINT(DEBUG, "Queue %u wdog enq %p ops %"PRIu64,
     464                 :            :                 q->index, wdog_op, cptq->stats.enqueued_count);
     465                 :          0 :         cptq->enqueued_wdogs++;
     466                 :            : 
     467                 :          0 : out_flush:
     468                 :            :         iocpt_q_flush(q);
     469                 :          0 : }
     470                 :            : 
     471                 :            : static uint16_t
     472                 :          0 : iocpt_dequeue_sym(void *qp, struct rte_crypto_op **ops, uint16_t nb_ops)
     473                 :            : {
     474                 :            :         struct iocpt_crypto_q *cptq = qp;
     475                 :            :         struct iocpt_queue *q = &cptq->q;
     476                 :            :         struct iocpt_cq *cq = &cptq->cq;
     477                 :            :         struct rte_crypto_op *op;
     478                 :          0 :         struct iocpt_crypto_comp *cq_desc_base = cq->base;
     479                 :            :         volatile struct iocpt_crypto_comp *cq_desc;
     480                 :            :         struct rte_cryptodev_stats *stats = &cptq->stats;
     481                 :            :         uint64_t then, now, hz, delta;
     482                 :            :         uint16_t count = 0;
     483                 :            : 
     484                 :          0 :         cq_desc = &cq_desc_base[cq->tail_idx];
     485                 :            : 
     486                 :            :         /* First walk the CQ to update any completed op's status
     487                 :            :          * NB: These can arrive out of order!
     488                 :            :          */
     489         [ #  # ]:          0 :         while ((cq_desc->color & 0x1) == cq->done_color) {
     490                 :          0 :                 cq->tail_idx = Q_NEXT_TO_SRVC(cq, 1);
     491         [ #  # ]:          0 :                 if (unlikely(cq->tail_idx == 0))
     492                 :          0 :                         cq->done_color = !cq->done_color;
     493                 :            : 
     494                 :          0 :                 op = q->info[rte_le_to_cpu_16(cq_desc->comp_index)];
     495                 :            : 
     496                 :            :                 /* Process returned CQ descriptor status */
     497         [ #  # ]:          0 :                 if (unlikely(cq_desc->status)) {
     498      [ #  #  # ]:          0 :                         switch (cq_desc->status) {
     499                 :          0 :                         case IOCPT_COMP_SYMM_AUTH_VERIFY_ERROR:
     500                 :          0 :                                 op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
     501                 :          0 :                                 break;
     502                 :          0 :                         case IOCPT_COMP_INVAL_OPCODE_ERROR:
     503                 :            :                         case IOCPT_COMP_UNSUPP_OPCODE_ERROR:
     504                 :            :                         case IOCPT_COMP_SYMM_SRC_SG_ERROR:
     505                 :            :                         case IOCPT_COMP_SYMM_DST_SG_ERROR:
     506                 :            :                         case IOCPT_COMP_SYMM_SRC_DST_LEN_MISMATCH:
     507                 :            :                         case IOCPT_COMP_SYMM_KEY_IDX_ERROR:
     508                 :          0 :                                 op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
     509                 :          0 :                                 break;
     510                 :          0 :                         default:
     511                 :          0 :                                 op->status = RTE_CRYPTO_OP_STATUS_ERROR;
     512                 :          0 :                                 break;
     513                 :            :                         }
     514                 :            :                 } else
     515                 :          0 :                         op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
     516                 :            : 
     517                 :          0 :                 cq_desc = &cq_desc_base[cq->tail_idx];
     518                 :            :         }
     519                 :            : 
     520                 :            :         /* Next walk the SQ to pop off completed ops in-order */
     521         [ #  # ]:          0 :         while (count < nb_ops) {
     522                 :          0 :                 op = q->info[q->tail_idx];
     523                 :            : 
     524                 :            :                 /* No more completions */
     525         [ #  # ]:          0 :                 if (op == NULL ||
     526         [ #  # ]:          0 :                     op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
     527                 :            :                         break;
     528                 :            : 
     529                 :            :                 /* Handle watchdog operations */
     530         [ #  # ]:          0 :                 if (unlikely(op->type == IOCPT_Q_WDOG_OP_TYPE)) {
     531                 :          0 :                         IOCPT_PRINT(DEBUG, "Queue %u wdog deq %p st %d",
     532                 :            :                                 q->index, op, op->status);
     533                 :          0 :                         q->info[q->tail_idx] = NULL;
     534                 :          0 :                         q->tail_idx = Q_NEXT_TO_SRVC(q, 1);
     535                 :          0 :                         cptq->dequeued_wdogs++;
     536                 :          0 :                         rte_free(op);
     537                 :          0 :                         continue;
     538                 :            :                 }
     539                 :            : 
     540         [ #  # ]:          0 :                 if (unlikely(op->status != RTE_CRYPTO_OP_STATUS_SUCCESS))
     541                 :          0 :                         stats->dequeue_err_count++;
     542                 :            : 
     543                 :          0 :                 ops[count] = op;
     544                 :          0 :                 q->info[q->tail_idx] = NULL;
     545                 :            : 
     546                 :          0 :                 q->tail_idx = Q_NEXT_TO_SRVC(q, 1);
     547                 :          0 :                 count++;
     548                 :            :         }
     549                 :            : 
     550         [ #  # ]:          0 :         if (!count) {
     551                 :            :                 /*
     552                 :            :                  * Ring the doorbell again if no work was dequeued and work
     553                 :            :                  * is still pending after the deadline.
     554                 :            :                  */
     555         [ #  # ]:          0 :                 if (q->head_idx != q->tail_idx) {
     556                 :          0 :                         then = cptq->last_wdog_cycles;
     557                 :            :                         now = rte_get_timer_cycles();
     558                 :            :                         hz = rte_get_timer_hz();
     559                 :          0 :                         delta = (now - then) * 1000;
     560                 :            : 
     561         [ #  # ]:          0 :                         if (delta >= hz * IONIC_Q_WDOG_MS) {
     562                 :          0 :                                 iocpt_enqueue_wdog(cptq);
     563                 :          0 :                                 cptq->last_wdog_cycles = now;
     564                 :            :                         }
     565                 :            :                 }
     566                 :            :         } else
     567                 :            :                 /* Restart timer if the queue is making progress */
     568                 :          0 :                 cptq->last_wdog_cycles = rte_get_timer_cycles();
     569                 :            : 
     570                 :          0 :         stats->dequeued_count += count;
     571                 :            : 
     572                 :          0 :         return count;
     573                 :            : }
     574                 :            : 
     575                 :            : static struct rte_cryptodev_ops iocpt_ops = {
     576                 :            :         .dev_configure = iocpt_op_config,
     577                 :            :         .dev_start = iocpt_op_start,
     578                 :            :         .dev_stop = iocpt_op_stop,
     579                 :            :         .dev_close = iocpt_op_close,
     580                 :            :         .dev_infos_get = iocpt_op_info_get,
     581                 :            : 
     582                 :            :         .stats_get = iocpt_op_stats_get,
     583                 :            :         .stats_reset = iocpt_op_stats_reset,
     584                 :            :         .queue_pair_setup = iocpt_op_queue_setup,
     585                 :            :         .queue_pair_release = iocpt_op_queue_release,
     586                 :            : 
     587                 :            :         .sym_session_get_size = iocpt_op_get_session_size,
     588                 :            :         .sym_session_configure = iocpt_op_session_cfg,
     589                 :            :         .sym_session_clear = iocpt_op_session_clear,
     590                 :            : };
     591                 :            : 
     592                 :            : int
     593                 :          0 : iocpt_assign_ops(struct rte_cryptodev *cdev)
     594                 :            : {
     595                 :          0 :         struct iocpt_dev *dev = cdev->data->dev_private;
     596                 :            : 
     597                 :          0 :         cdev->dev_ops = &iocpt_ops;
     598                 :          0 :         cdev->feature_flags = dev->features;
     599                 :            : 
     600         [ #  # ]:          0 :         if (dev->features & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) {
     601                 :          0 :                 cdev->enqueue_burst = iocpt_enqueue_sym;
     602                 :          0 :                 cdev->dequeue_burst = iocpt_dequeue_sym;
     603                 :            :         }
     604                 :            : 
     605                 :          0 :         return 0;
     606                 :            : }

Generated by: LCOV version 1.14