18769079aSJay Zhou /* SPDX-License-Identifier: BSD-3-Clause 28769079aSJay Zhou * Copyright(c) 2018 HUAWEI TECHNOLOGIES CO., LTD. 38769079aSJay Zhou */ 4b7fa78c7SJay Zhou #include <stdbool.h> 5b7fa78c7SJay Zhou #include <unistd.h> 6b7fa78c7SJay Zhou 7b7fa78c7SJay Zhou #include <rte_common.h> 86f0175ffSJay Zhou #include <rte_errno.h> 98769079aSJay Zhou #include <rte_pci.h> 108769079aSJay Zhou #include <rte_bus_pci.h> 1125500d4bSJay Zhou #include <rte_cryptodev.h> 128769079aSJay Zhou #include <rte_cryptodev_pmd.h> 1325500d4bSJay Zhou #include <rte_eal.h> 148769079aSJay Zhou 158769079aSJay Zhou #include "virtio_cryptodev.h" 1625500d4bSJay Zhou #include "virtqueue.h" 17b7fa78c7SJay Zhou #include "virtio_crypto_algs.h" 185889e1ffSJay Zhou #include "virtio_crypto_capabilities.h" 1925500d4bSJay Zhou 206f0175ffSJay Zhou static int virtio_crypto_dev_configure(struct rte_cryptodev *dev, 216f0175ffSJay Zhou struct rte_cryptodev_config *config); 226f0175ffSJay Zhou static int virtio_crypto_dev_start(struct rte_cryptodev *dev); 236f0175ffSJay Zhou static void virtio_crypto_dev_stop(struct rte_cryptodev *dev); 246f0175ffSJay Zhou static int virtio_crypto_dev_close(struct rte_cryptodev *dev); 256f0175ffSJay Zhou static void virtio_crypto_dev_info_get(struct rte_cryptodev *dev, 266f0175ffSJay Zhou struct rte_cryptodev_info *dev_info); 27efd3ac6bSJay Zhou static void virtio_crypto_dev_stats_get(struct rte_cryptodev *dev, 28efd3ac6bSJay Zhou struct rte_cryptodev_stats *stats); 29efd3ac6bSJay Zhou static void virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev); 306f0175ffSJay Zhou static int virtio_crypto_qp_setup(struct rte_cryptodev *dev, 316f0175ffSJay Zhou uint16_t queue_pair_id, 326f0175ffSJay Zhou const struct rte_cryptodev_qp_conf *qp_conf, 33725d2a7fSFan Zhang int socket_id); 346f0175ffSJay Zhou static int virtio_crypto_qp_release(struct rte_cryptodev *dev, 356f0175ffSJay Zhou uint16_t queue_pair_id); 366f0175ffSJay Zhou static void virtio_crypto_dev_free_mbufs(struct rte_cryptodev *dev); 37b7fa78c7SJay Zhou static unsigned int virtio_crypto_sym_get_session_private_size( 38b7fa78c7SJay Zhou struct rte_cryptodev *dev); 39b7fa78c7SJay Zhou static void virtio_crypto_sym_clear_session(struct rte_cryptodev *dev, 40b7fa78c7SJay Zhou struct rte_cryptodev_sym_session *sess); 41b7fa78c7SJay Zhou static int virtio_crypto_sym_configure_session(struct rte_cryptodev *dev, 42b7fa78c7SJay Zhou struct rte_crypto_sym_xform *xform, 43b7fa78c7SJay Zhou struct rte_cryptodev_sym_session *session, 44b7fa78c7SJay Zhou struct rte_mempool *mp); 456f0175ffSJay Zhou 4625500d4bSJay Zhou /* 4725500d4bSJay Zhou * The set of PCI devices this driver supports 4825500d4bSJay Zhou */ 4925500d4bSJay Zhou static const struct rte_pci_id pci_id_virtio_crypto_map[] = { 5025500d4bSJay Zhou { RTE_PCI_DEVICE(VIRTIO_CRYPTO_PCI_VENDORID, 5125500d4bSJay Zhou VIRTIO_CRYPTO_PCI_DEVICEID) }, 5225500d4bSJay Zhou { .vendor_id = 0, /* sentinel */ }, 5325500d4bSJay Zhou }; 548769079aSJay Zhou 555889e1ffSJay Zhou static const struct rte_cryptodev_capabilities virtio_capabilities[] = { 565889e1ffSJay Zhou VIRTIO_SYM_CAPABILITIES, 575889e1ffSJay Zhou RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() 585889e1ffSJay Zhou }; 595889e1ffSJay Zhou 608769079aSJay Zhou uint8_t cryptodev_virtio_driver_id; 618769079aSJay Zhou 62b7fa78c7SJay Zhou #define NUM_ENTRY_SYM_CREATE_SESSION 4 63b7fa78c7SJay Zhou 64b7fa78c7SJay Zhou static int 65b7fa78c7SJay Zhou virtio_crypto_send_command(struct virtqueue *vq, 66b7fa78c7SJay Zhou struct virtio_crypto_op_ctrl_req *ctrl, uint8_t *cipher_key, 67b7fa78c7SJay Zhou uint8_t *auth_key, struct virtio_crypto_session *session) 68b7fa78c7SJay Zhou { 69b7fa78c7SJay Zhou uint8_t idx = 0; 70b7fa78c7SJay Zhou uint8_t needed = 1; 71b7fa78c7SJay Zhou uint32_t head = 0; 72b7fa78c7SJay Zhou uint32_t len_cipher_key = 0; 73b7fa78c7SJay Zhou uint32_t len_auth_key = 0; 74b7fa78c7SJay Zhou uint32_t len_ctrl_req = sizeof(struct virtio_crypto_op_ctrl_req); 75b7fa78c7SJay Zhou uint32_t len_session_input = sizeof(struct virtio_crypto_session_input); 76b7fa78c7SJay Zhou uint32_t len_total = 0; 77b7fa78c7SJay Zhou uint32_t input_offset = 0; 78b7fa78c7SJay Zhou void *virt_addr_started = NULL; 79b7fa78c7SJay Zhou phys_addr_t phys_addr_started; 80b7fa78c7SJay Zhou struct vring_desc *desc; 81b7fa78c7SJay Zhou uint32_t desc_offset; 82b7fa78c7SJay Zhou struct virtio_crypto_session_input *input; 83b7fa78c7SJay Zhou int ret; 84b7fa78c7SJay Zhou 85b7fa78c7SJay Zhou PMD_INIT_FUNC_TRACE(); 86b7fa78c7SJay Zhou 87b7fa78c7SJay Zhou if (session == NULL) { 88b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("session is NULL."); 89b7fa78c7SJay Zhou return -EINVAL; 90b7fa78c7SJay Zhou } 91b7fa78c7SJay Zhou /* cipher only is supported, it is available if auth_key is NULL */ 92b7fa78c7SJay Zhou if (!cipher_key) { 93b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("cipher key is NULL."); 94b7fa78c7SJay Zhou return -EINVAL; 95b7fa78c7SJay Zhou } 96b7fa78c7SJay Zhou 97b7fa78c7SJay Zhou head = vq->vq_desc_head_idx; 98b7fa78c7SJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_desc_head_idx = %d, vq = %p", 99b7fa78c7SJay Zhou head, vq); 100b7fa78c7SJay Zhou 101b7fa78c7SJay Zhou if (vq->vq_free_cnt < needed) { 102b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Not enough entry"); 103b7fa78c7SJay Zhou return -ENOSPC; 104b7fa78c7SJay Zhou } 105b7fa78c7SJay Zhou 106b7fa78c7SJay Zhou /* calculate the length of cipher key */ 107b7fa78c7SJay Zhou if (cipher_key) { 108b7fa78c7SJay Zhou switch (ctrl->u.sym_create_session.op_type) { 109b7fa78c7SJay Zhou case VIRTIO_CRYPTO_SYM_OP_CIPHER: 110b7fa78c7SJay Zhou len_cipher_key 111b7fa78c7SJay Zhou = ctrl->u.sym_create_session.u.cipher 112b7fa78c7SJay Zhou .para.keylen; 113b7fa78c7SJay Zhou break; 114b7fa78c7SJay Zhou case VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING: 115b7fa78c7SJay Zhou len_cipher_key 116b7fa78c7SJay Zhou = ctrl->u.sym_create_session.u.chain 117b7fa78c7SJay Zhou .para.cipher_param.keylen; 118b7fa78c7SJay Zhou break; 119b7fa78c7SJay Zhou default: 120b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("invalid op type"); 121b7fa78c7SJay Zhou return -EINVAL; 122b7fa78c7SJay Zhou } 123b7fa78c7SJay Zhou } 124b7fa78c7SJay Zhou 125b7fa78c7SJay Zhou /* calculate the length of auth key */ 126b7fa78c7SJay Zhou if (auth_key) { 127b7fa78c7SJay Zhou len_auth_key = 128b7fa78c7SJay Zhou ctrl->u.sym_create_session.u.chain.para.u.mac_param 129b7fa78c7SJay Zhou .auth_key_len; 130b7fa78c7SJay Zhou } 131b7fa78c7SJay Zhou 132b7fa78c7SJay Zhou /* 133b7fa78c7SJay Zhou * malloc memory to store indirect vring_desc entries, including 134b7fa78c7SJay Zhou * ctrl request, cipher key, auth key, session input and desc vring 135b7fa78c7SJay Zhou */ 136b7fa78c7SJay Zhou desc_offset = len_ctrl_req + len_cipher_key + len_auth_key 137b7fa78c7SJay Zhou + len_session_input; 138b7fa78c7SJay Zhou virt_addr_started = rte_malloc(NULL, 139b7fa78c7SJay Zhou desc_offset + NUM_ENTRY_SYM_CREATE_SESSION 140b7fa78c7SJay Zhou * sizeof(struct vring_desc), RTE_CACHE_LINE_SIZE); 141b7fa78c7SJay Zhou if (virt_addr_started == NULL) { 142b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("not enough heap memory"); 143b7fa78c7SJay Zhou return -ENOSPC; 144b7fa78c7SJay Zhou } 145b7fa78c7SJay Zhou phys_addr_started = rte_malloc_virt2iova(virt_addr_started); 146b7fa78c7SJay Zhou 147b7fa78c7SJay Zhou /* address to store indirect vring desc entries */ 148b7fa78c7SJay Zhou desc = (struct vring_desc *) 149b7fa78c7SJay Zhou ((uint8_t *)virt_addr_started + desc_offset); 150b7fa78c7SJay Zhou 151b7fa78c7SJay Zhou /* ctrl req part */ 152b7fa78c7SJay Zhou memcpy(virt_addr_started, ctrl, len_ctrl_req); 153b7fa78c7SJay Zhou desc[idx].addr = phys_addr_started; 154b7fa78c7SJay Zhou desc[idx].len = len_ctrl_req; 155b7fa78c7SJay Zhou desc[idx].flags = VRING_DESC_F_NEXT; 156b7fa78c7SJay Zhou desc[idx].next = idx + 1; 157b7fa78c7SJay Zhou idx++; 158b7fa78c7SJay Zhou len_total += len_ctrl_req; 159b7fa78c7SJay Zhou input_offset += len_ctrl_req; 160b7fa78c7SJay Zhou 161b7fa78c7SJay Zhou /* cipher key part */ 162b7fa78c7SJay Zhou if (len_cipher_key > 0) { 163b7fa78c7SJay Zhou memcpy((uint8_t *)virt_addr_started + len_total, 164b7fa78c7SJay Zhou cipher_key, len_cipher_key); 165b7fa78c7SJay Zhou 166b7fa78c7SJay Zhou desc[idx].addr = phys_addr_started + len_total; 167b7fa78c7SJay Zhou desc[idx].len = len_cipher_key; 168b7fa78c7SJay Zhou desc[idx].flags = VRING_DESC_F_NEXT; 169b7fa78c7SJay Zhou desc[idx].next = idx + 1; 170b7fa78c7SJay Zhou idx++; 171b7fa78c7SJay Zhou len_total += len_cipher_key; 172b7fa78c7SJay Zhou input_offset += len_cipher_key; 173b7fa78c7SJay Zhou } 174b7fa78c7SJay Zhou 175b7fa78c7SJay Zhou /* auth key part */ 176b7fa78c7SJay Zhou if (len_auth_key > 0) { 177b7fa78c7SJay Zhou memcpy((uint8_t *)virt_addr_started + len_total, 178b7fa78c7SJay Zhou auth_key, len_auth_key); 179b7fa78c7SJay Zhou 180b7fa78c7SJay Zhou desc[idx].addr = phys_addr_started + len_total; 181b7fa78c7SJay Zhou desc[idx].len = len_auth_key; 182b7fa78c7SJay Zhou desc[idx].flags = VRING_DESC_F_NEXT; 183b7fa78c7SJay Zhou desc[idx].next = idx + 1; 184b7fa78c7SJay Zhou idx++; 185b7fa78c7SJay Zhou len_total += len_auth_key; 186b7fa78c7SJay Zhou input_offset += len_auth_key; 187b7fa78c7SJay Zhou } 188b7fa78c7SJay Zhou 189b7fa78c7SJay Zhou /* input part */ 190b7fa78c7SJay Zhou input = (struct virtio_crypto_session_input *) 191b7fa78c7SJay Zhou ((uint8_t *)virt_addr_started + input_offset); 192b7fa78c7SJay Zhou input->status = VIRTIO_CRYPTO_ERR; 193b7fa78c7SJay Zhou input->session_id = ~0ULL; 194b7fa78c7SJay Zhou desc[idx].addr = phys_addr_started + len_total; 195b7fa78c7SJay Zhou desc[idx].len = len_session_input; 196b7fa78c7SJay Zhou desc[idx].flags = VRING_DESC_F_WRITE; 197b7fa78c7SJay Zhou idx++; 198b7fa78c7SJay Zhou 199b7fa78c7SJay Zhou /* use a single desc entry */ 200b7fa78c7SJay Zhou vq->vq_ring.desc[head].addr = phys_addr_started + desc_offset; 201b7fa78c7SJay Zhou vq->vq_ring.desc[head].len = idx * sizeof(struct vring_desc); 202b7fa78c7SJay Zhou vq->vq_ring.desc[head].flags = VRING_DESC_F_INDIRECT; 203b7fa78c7SJay Zhou vq->vq_free_cnt--; 204b7fa78c7SJay Zhou 205b7fa78c7SJay Zhou vq->vq_desc_head_idx = vq->vq_ring.desc[head].next; 206b7fa78c7SJay Zhou 207b7fa78c7SJay Zhou vq_update_avail_ring(vq, head); 208b7fa78c7SJay Zhou vq_update_avail_idx(vq); 209b7fa78c7SJay Zhou 210b7fa78c7SJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_queue_index = %d", 211b7fa78c7SJay Zhou vq->vq_queue_index); 212b7fa78c7SJay Zhou 213b7fa78c7SJay Zhou virtqueue_notify(vq); 214b7fa78c7SJay Zhou 215b7fa78c7SJay Zhou rte_rmb(); 216b7fa78c7SJay Zhou while (vq->vq_used_cons_idx == vq->vq_ring.used->idx) { 217b7fa78c7SJay Zhou rte_rmb(); 218b7fa78c7SJay Zhou usleep(100); 219b7fa78c7SJay Zhou } 220b7fa78c7SJay Zhou 221b7fa78c7SJay Zhou while (vq->vq_used_cons_idx != vq->vq_ring.used->idx) { 222b7fa78c7SJay Zhou uint32_t idx, desc_idx, used_idx; 223b7fa78c7SJay Zhou struct vring_used_elem *uep; 224b7fa78c7SJay Zhou 225b7fa78c7SJay Zhou used_idx = (uint32_t)(vq->vq_used_cons_idx 226b7fa78c7SJay Zhou & (vq->vq_nentries - 1)); 227b7fa78c7SJay Zhou uep = &vq->vq_ring.used->ring[used_idx]; 228b7fa78c7SJay Zhou idx = (uint32_t) uep->id; 229b7fa78c7SJay Zhou desc_idx = idx; 230b7fa78c7SJay Zhou 231b7fa78c7SJay Zhou while (vq->vq_ring.desc[desc_idx].flags & VRING_DESC_F_NEXT) { 232b7fa78c7SJay Zhou desc_idx = vq->vq_ring.desc[desc_idx].next; 233b7fa78c7SJay Zhou vq->vq_free_cnt++; 234b7fa78c7SJay Zhou } 235b7fa78c7SJay Zhou 236b7fa78c7SJay Zhou vq->vq_ring.desc[desc_idx].next = vq->vq_desc_head_idx; 237b7fa78c7SJay Zhou vq->vq_desc_head_idx = idx; 238b7fa78c7SJay Zhou 239b7fa78c7SJay Zhou vq->vq_used_cons_idx++; 240b7fa78c7SJay Zhou vq->vq_free_cnt++; 241b7fa78c7SJay Zhou } 242b7fa78c7SJay Zhou 243b7fa78c7SJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_free_cnt=%d\n" 244b7fa78c7SJay Zhou "vq->vq_desc_head_idx=%d", 245b7fa78c7SJay Zhou vq->vq_free_cnt, vq->vq_desc_head_idx); 246b7fa78c7SJay Zhou 247b7fa78c7SJay Zhou /* get the result */ 248b7fa78c7SJay Zhou if (input->status != VIRTIO_CRYPTO_OK) { 249b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Something wrong on backend! " 250b7fa78c7SJay Zhou "status=%u, session_id=%" PRIu64 "", 251b7fa78c7SJay Zhou input->status, input->session_id); 252b7fa78c7SJay Zhou rte_free(virt_addr_started); 253b7fa78c7SJay Zhou ret = -1; 254b7fa78c7SJay Zhou } else { 255b7fa78c7SJay Zhou session->session_id = input->session_id; 256b7fa78c7SJay Zhou 257b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_INFO("Create session successfully, " 258b7fa78c7SJay Zhou "session_id=%" PRIu64 "", input->session_id); 259b7fa78c7SJay Zhou rte_free(virt_addr_started); 260b7fa78c7SJay Zhou ret = 0; 261b7fa78c7SJay Zhou } 262b7fa78c7SJay Zhou 263b7fa78c7SJay Zhou return ret; 264b7fa78c7SJay Zhou } 265b7fa78c7SJay Zhou 2666f0175ffSJay Zhou void 2676f0175ffSJay Zhou virtio_crypto_queue_release(struct virtqueue *vq) 2686f0175ffSJay Zhou { 2696f0175ffSJay Zhou struct virtio_crypto_hw *hw; 2706f0175ffSJay Zhou 2716f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 2726f0175ffSJay Zhou 2736f0175ffSJay Zhou if (vq) { 2746f0175ffSJay Zhou hw = vq->hw; 2756f0175ffSJay Zhou /* Select and deactivate the queue */ 2766f0175ffSJay Zhou VTPCI_OPS(hw)->del_queue(hw, vq); 2776f0175ffSJay Zhou 2786f0175ffSJay Zhou rte_memzone_free(vq->mz); 2796f0175ffSJay Zhou rte_mempool_free(vq->mpool); 2806f0175ffSJay Zhou rte_free(vq); 2816f0175ffSJay Zhou } 2826f0175ffSJay Zhou } 2836f0175ffSJay Zhou 2846f0175ffSJay Zhou #define MPOOL_MAX_NAME_SZ 32 2856f0175ffSJay Zhou 2866f0175ffSJay Zhou int 2876f0175ffSJay Zhou virtio_crypto_queue_setup(struct rte_cryptodev *dev, 2886f0175ffSJay Zhou int queue_type, 2896f0175ffSJay Zhou uint16_t vtpci_queue_idx, 2906f0175ffSJay Zhou uint16_t nb_desc, 2916f0175ffSJay Zhou int socket_id, 2926f0175ffSJay Zhou struct virtqueue **pvq) 2936f0175ffSJay Zhou { 2946f0175ffSJay Zhou char vq_name[VIRTQUEUE_MAX_NAME_SZ]; 2956f0175ffSJay Zhou char mpool_name[MPOOL_MAX_NAME_SZ]; 2966f0175ffSJay Zhou const struct rte_memzone *mz; 2976f0175ffSJay Zhou unsigned int vq_size, size; 2986f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 2996f0175ffSJay Zhou struct virtqueue *vq = NULL; 3006f0175ffSJay Zhou uint32_t i = 0; 3016f0175ffSJay Zhou uint32_t j; 3026f0175ffSJay Zhou 3036f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 3046f0175ffSJay Zhou 3056f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("setting up queue: %u", vtpci_queue_idx); 3066f0175ffSJay Zhou 3076f0175ffSJay Zhou /* 3086f0175ffSJay Zhou * Read the virtqueue size from the Queue Size field 3096f0175ffSJay Zhou * Always power of 2 and if 0 virtqueue does not exist 3106f0175ffSJay Zhou */ 3116f0175ffSJay Zhou vq_size = VTPCI_OPS(hw)->get_queue_num(hw, vtpci_queue_idx); 3126f0175ffSJay Zhou if (vq_size == 0) { 3136f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("virtqueue does not exist"); 3146f0175ffSJay Zhou return -EINVAL; 3156f0175ffSJay Zhou } 3166f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq_size: %u", vq_size); 3176f0175ffSJay Zhou 3186f0175ffSJay Zhou if (!rte_is_power_of_2(vq_size)) { 3196f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("virtqueue size is not powerof 2"); 3206f0175ffSJay Zhou return -EINVAL; 3216f0175ffSJay Zhou } 3226f0175ffSJay Zhou 3236f0175ffSJay Zhou if (queue_type == VTCRYPTO_DATAQ) { 3246f0175ffSJay Zhou snprintf(vq_name, sizeof(vq_name), "dev%d_dataqueue%d", 3256f0175ffSJay Zhou dev->data->dev_id, vtpci_queue_idx); 3266f0175ffSJay Zhou snprintf(mpool_name, sizeof(mpool_name), 3276f0175ffSJay Zhou "dev%d_dataqueue%d_mpool", 3286f0175ffSJay Zhou dev->data->dev_id, vtpci_queue_idx); 3296f0175ffSJay Zhou } else if (queue_type == VTCRYPTO_CTRLQ) { 3306f0175ffSJay Zhou snprintf(vq_name, sizeof(vq_name), "dev%d_controlqueue", 3316f0175ffSJay Zhou dev->data->dev_id); 3326f0175ffSJay Zhou snprintf(mpool_name, sizeof(mpool_name), 3336f0175ffSJay Zhou "dev%d_controlqueue_mpool", 3346f0175ffSJay Zhou dev->data->dev_id); 3356f0175ffSJay Zhou } 3366f0175ffSJay Zhou size = RTE_ALIGN_CEIL(sizeof(*vq) + 3376f0175ffSJay Zhou vq_size * sizeof(struct vq_desc_extra), 3386f0175ffSJay Zhou RTE_CACHE_LINE_SIZE); 3396f0175ffSJay Zhou vq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE, 3406f0175ffSJay Zhou socket_id); 3416f0175ffSJay Zhou if (vq == NULL) { 3426f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("Can not allocate virtqueue"); 3436f0175ffSJay Zhou return -ENOMEM; 3446f0175ffSJay Zhou } 3456f0175ffSJay Zhou 3466f0175ffSJay Zhou if (queue_type == VTCRYPTO_DATAQ) { 3476f0175ffSJay Zhou /* pre-allocate a mempool and use it in the data plane to 3486f0175ffSJay Zhou * improve performance 3496f0175ffSJay Zhou */ 3506f0175ffSJay Zhou vq->mpool = rte_mempool_lookup(mpool_name); 3516f0175ffSJay Zhou if (vq->mpool == NULL) 3526f0175ffSJay Zhou vq->mpool = rte_mempool_create(mpool_name, 3536f0175ffSJay Zhou vq_size, 3546f0175ffSJay Zhou sizeof(struct virtio_crypto_op_cookie), 3556f0175ffSJay Zhou RTE_CACHE_LINE_SIZE, 0, 3566f0175ffSJay Zhou NULL, NULL, NULL, NULL, socket_id, 3576f0175ffSJay Zhou 0); 3586f0175ffSJay Zhou if (!vq->mpool) { 3596f0175ffSJay Zhou VIRTIO_CRYPTO_DRV_LOG_ERR("Virtio Crypto PMD " 3606f0175ffSJay Zhou "Cannot create mempool"); 3616f0175ffSJay Zhou goto mpool_create_err; 3626f0175ffSJay Zhou } 3636f0175ffSJay Zhou for (i = 0; i < vq_size; i++) { 3646f0175ffSJay Zhou vq->vq_descx[i].cookie = 3656f0175ffSJay Zhou rte_zmalloc("crypto PMD op cookie pointer", 3666f0175ffSJay Zhou sizeof(struct virtio_crypto_op_cookie), 3676f0175ffSJay Zhou RTE_CACHE_LINE_SIZE); 3686f0175ffSJay Zhou if (vq->vq_descx[i].cookie == NULL) { 3696f0175ffSJay Zhou VIRTIO_CRYPTO_DRV_LOG_ERR("Failed to " 3706f0175ffSJay Zhou "alloc mem for cookie"); 3716f0175ffSJay Zhou goto cookie_alloc_err; 3726f0175ffSJay Zhou } 3736f0175ffSJay Zhou } 3746f0175ffSJay Zhou } 3756f0175ffSJay Zhou 3766f0175ffSJay Zhou vq->hw = hw; 3776f0175ffSJay Zhou vq->dev_id = dev->data->dev_id; 3786f0175ffSJay Zhou vq->vq_queue_index = vtpci_queue_idx; 3796f0175ffSJay Zhou vq->vq_nentries = vq_size; 3806f0175ffSJay Zhou 3816f0175ffSJay Zhou /* 3826f0175ffSJay Zhou * Using part of the vring entries is permitted, but the maximum 3836f0175ffSJay Zhou * is vq_size 3846f0175ffSJay Zhou */ 3856f0175ffSJay Zhou if (nb_desc == 0 || nb_desc > vq_size) 3866f0175ffSJay Zhou nb_desc = vq_size; 3876f0175ffSJay Zhou vq->vq_free_cnt = nb_desc; 3886f0175ffSJay Zhou 3896f0175ffSJay Zhou /* 3906f0175ffSJay Zhou * Reserve a memzone for vring elements 3916f0175ffSJay Zhou */ 3926f0175ffSJay Zhou size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN); 3936f0175ffSJay Zhou vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN); 3946f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("%s vring_size: %d, rounded_vring_size: %d", 3956f0175ffSJay Zhou (queue_type == VTCRYPTO_DATAQ) ? "dataq" : "ctrlq", 3966f0175ffSJay Zhou size, vq->vq_ring_size); 3976f0175ffSJay Zhou 3986f0175ffSJay Zhou mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size, 3996f0175ffSJay Zhou socket_id, 0, VIRTIO_PCI_VRING_ALIGN); 4006f0175ffSJay Zhou if (mz == NULL) { 4016f0175ffSJay Zhou if (rte_errno == EEXIST) 4026f0175ffSJay Zhou mz = rte_memzone_lookup(vq_name); 4036f0175ffSJay Zhou if (mz == NULL) { 4046f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("not enough memory"); 4056f0175ffSJay Zhou goto mz_reserve_err; 4066f0175ffSJay Zhou } 4076f0175ffSJay Zhou } 4086f0175ffSJay Zhou 4096f0175ffSJay Zhou /* 4106f0175ffSJay Zhou * Virtio PCI device VIRTIO_PCI_QUEUE_PF register is 32bit, 4116f0175ffSJay Zhou * and only accepts 32 bit page frame number. 4126f0175ffSJay Zhou * Check if the allocated physical memory exceeds 16TB. 4136f0175ffSJay Zhou */ 414*72f82c43SThomas Monjalon if ((mz->iova + vq->vq_ring_size - 1) 4156f0175ffSJay Zhou >> (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) { 4166f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("vring address shouldn't be " 4176f0175ffSJay Zhou "above 16TB!"); 4186f0175ffSJay Zhou goto vring_addr_err; 4196f0175ffSJay Zhou } 4206f0175ffSJay Zhou 4216f0175ffSJay Zhou memset(mz->addr, 0, sizeof(mz->len)); 4226f0175ffSJay Zhou vq->mz = mz; 423*72f82c43SThomas Monjalon vq->vq_ring_mem = mz->iova; 4246f0175ffSJay Zhou vq->vq_ring_virt_mem = mz->addr; 4256f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_ring_mem(physical): 0x%"PRIx64, 426*72f82c43SThomas Monjalon (uint64_t)mz->iova); 4276f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_ring_virt_mem: 0x%"PRIx64, 4286f0175ffSJay Zhou (uint64_t)(uintptr_t)mz->addr); 4296f0175ffSJay Zhou 4306f0175ffSJay Zhou *pvq = vq; 4316f0175ffSJay Zhou 4326f0175ffSJay Zhou return 0; 4336f0175ffSJay Zhou 4346f0175ffSJay Zhou vring_addr_err: 4356f0175ffSJay Zhou rte_memzone_free(mz); 4366f0175ffSJay Zhou mz_reserve_err: 4376f0175ffSJay Zhou cookie_alloc_err: 4386f0175ffSJay Zhou rte_mempool_free(vq->mpool); 4396f0175ffSJay Zhou if (i != 0) { 4406f0175ffSJay Zhou for (j = 0; j < i; j++) 4416f0175ffSJay Zhou rte_free(vq->vq_descx[j].cookie); 4426f0175ffSJay Zhou } 4436f0175ffSJay Zhou mpool_create_err: 4446f0175ffSJay Zhou rte_free(vq); 4456f0175ffSJay Zhou return -ENOMEM; 4466f0175ffSJay Zhou } 4476f0175ffSJay Zhou 4486f0175ffSJay Zhou static int 4496f0175ffSJay Zhou virtio_crypto_ctrlq_setup(struct rte_cryptodev *dev, uint16_t queue_idx) 4506f0175ffSJay Zhou { 4516f0175ffSJay Zhou int ret; 4526f0175ffSJay Zhou struct virtqueue *vq; 4536f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 4546f0175ffSJay Zhou 4556f0175ffSJay Zhou /* if virtio device has started, do not touch the virtqueues */ 4566f0175ffSJay Zhou if (dev->data->dev_started) 4576f0175ffSJay Zhou return 0; 4586f0175ffSJay Zhou 4596f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 4606f0175ffSJay Zhou 4616f0175ffSJay Zhou ret = virtio_crypto_queue_setup(dev, VTCRYPTO_CTRLQ, queue_idx, 4626f0175ffSJay Zhou 0, SOCKET_ID_ANY, &vq); 4636f0175ffSJay Zhou if (ret < 0) { 4646f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("control vq initialization failed"); 4656f0175ffSJay Zhou return ret; 4666f0175ffSJay Zhou } 4676f0175ffSJay Zhou 4686f0175ffSJay Zhou hw->cvq = vq; 4696f0175ffSJay Zhou 4706f0175ffSJay Zhou return 0; 4716f0175ffSJay Zhou } 4726f0175ffSJay Zhou 4736f0175ffSJay Zhou static void 4746f0175ffSJay Zhou virtio_crypto_free_queues(struct rte_cryptodev *dev) 4756f0175ffSJay Zhou { 4766f0175ffSJay Zhou unsigned int i; 4776f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 4786f0175ffSJay Zhou 4796f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 4806f0175ffSJay Zhou 4816f0175ffSJay Zhou /* control queue release */ 4826f0175ffSJay Zhou virtio_crypto_queue_release(hw->cvq); 4836f0175ffSJay Zhou 4846f0175ffSJay Zhou /* data queue release */ 4856f0175ffSJay Zhou for (i = 0; i < hw->max_dataqueues; i++) 4866f0175ffSJay Zhou virtio_crypto_queue_release(dev->data->queue_pairs[i]); 4876f0175ffSJay Zhou } 4886f0175ffSJay Zhou 4896f0175ffSJay Zhou static int 4906f0175ffSJay Zhou virtio_crypto_dev_close(struct rte_cryptodev *dev __rte_unused) 4916f0175ffSJay Zhou { 4926f0175ffSJay Zhou return 0; 4936f0175ffSJay Zhou } 4946f0175ffSJay Zhou 49525500d4bSJay Zhou /* 49625500d4bSJay Zhou * dev_ops for virtio, bare necessities for basic operation 49725500d4bSJay Zhou */ 49825500d4bSJay Zhou static struct rte_cryptodev_ops virtio_crypto_dev_ops = { 49925500d4bSJay Zhou /* Device related operations */ 5006f0175ffSJay Zhou .dev_configure = virtio_crypto_dev_configure, 5016f0175ffSJay Zhou .dev_start = virtio_crypto_dev_start, 5026f0175ffSJay Zhou .dev_stop = virtio_crypto_dev_stop, 5036f0175ffSJay Zhou .dev_close = virtio_crypto_dev_close, 5046f0175ffSJay Zhou .dev_infos_get = virtio_crypto_dev_info_get, 50525500d4bSJay Zhou 506efd3ac6bSJay Zhou .stats_get = virtio_crypto_dev_stats_get, 507efd3ac6bSJay Zhou .stats_reset = virtio_crypto_dev_stats_reset, 50825500d4bSJay Zhou 5096f0175ffSJay Zhou .queue_pair_setup = virtio_crypto_qp_setup, 5106f0175ffSJay Zhou .queue_pair_release = virtio_crypto_qp_release, 51125500d4bSJay Zhou 51225500d4bSJay Zhou /* Crypto related operations */ 513012c5076SPablo de Lara .sym_session_get_size = virtio_crypto_sym_get_session_private_size, 514012c5076SPablo de Lara .sym_session_configure = virtio_crypto_sym_configure_session, 515012c5076SPablo de Lara .sym_session_clear = virtio_crypto_sym_clear_session 51625500d4bSJay Zhou }; 51725500d4bSJay Zhou 518efd3ac6bSJay Zhou static void 519efd3ac6bSJay Zhou virtio_crypto_update_stats(struct rte_cryptodev *dev, 520efd3ac6bSJay Zhou struct rte_cryptodev_stats *stats) 521efd3ac6bSJay Zhou { 522efd3ac6bSJay Zhou unsigned int i; 523efd3ac6bSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 524efd3ac6bSJay Zhou 525efd3ac6bSJay Zhou PMD_INIT_FUNC_TRACE(); 526efd3ac6bSJay Zhou 527efd3ac6bSJay Zhou if (stats == NULL) { 528efd3ac6bSJay Zhou VIRTIO_CRYPTO_DRV_LOG_ERR("invalid pointer"); 529efd3ac6bSJay Zhou return; 530efd3ac6bSJay Zhou } 531efd3ac6bSJay Zhou 532efd3ac6bSJay Zhou for (i = 0; i < hw->max_dataqueues; i++) { 533efd3ac6bSJay Zhou const struct virtqueue *data_queue 534efd3ac6bSJay Zhou = dev->data->queue_pairs[i]; 535efd3ac6bSJay Zhou if (data_queue == NULL) 536efd3ac6bSJay Zhou continue; 537efd3ac6bSJay Zhou 538efd3ac6bSJay Zhou stats->enqueued_count += data_queue->packets_sent_total; 539efd3ac6bSJay Zhou stats->enqueue_err_count += data_queue->packets_sent_failed; 540efd3ac6bSJay Zhou 541efd3ac6bSJay Zhou stats->dequeued_count += data_queue->packets_received_total; 542efd3ac6bSJay Zhou stats->dequeue_err_count 543efd3ac6bSJay Zhou += data_queue->packets_received_failed; 544efd3ac6bSJay Zhou } 545efd3ac6bSJay Zhou } 546efd3ac6bSJay Zhou 547efd3ac6bSJay Zhou static void 548efd3ac6bSJay Zhou virtio_crypto_dev_stats_get(struct rte_cryptodev *dev, 549efd3ac6bSJay Zhou struct rte_cryptodev_stats *stats) 550efd3ac6bSJay Zhou { 551efd3ac6bSJay Zhou PMD_INIT_FUNC_TRACE(); 552efd3ac6bSJay Zhou 553efd3ac6bSJay Zhou virtio_crypto_update_stats(dev, stats); 554efd3ac6bSJay Zhou } 555efd3ac6bSJay Zhou 556efd3ac6bSJay Zhou static void 557efd3ac6bSJay Zhou virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev) 558efd3ac6bSJay Zhou { 559efd3ac6bSJay Zhou unsigned int i; 560efd3ac6bSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 561efd3ac6bSJay Zhou 562efd3ac6bSJay Zhou PMD_INIT_FUNC_TRACE(); 563efd3ac6bSJay Zhou 564efd3ac6bSJay Zhou for (i = 0; i < hw->max_dataqueues; i++) { 565efd3ac6bSJay Zhou struct virtqueue *data_queue = dev->data->queue_pairs[i]; 566efd3ac6bSJay Zhou if (data_queue == NULL) 567efd3ac6bSJay Zhou continue; 568efd3ac6bSJay Zhou 569efd3ac6bSJay Zhou data_queue->packets_sent_total = 0; 570efd3ac6bSJay Zhou data_queue->packets_sent_failed = 0; 571efd3ac6bSJay Zhou 572efd3ac6bSJay Zhou data_queue->packets_received_total = 0; 573efd3ac6bSJay Zhou data_queue->packets_received_failed = 0; 574efd3ac6bSJay Zhou } 575efd3ac6bSJay Zhou } 576efd3ac6bSJay Zhou 57725500d4bSJay Zhou static int 5786f0175ffSJay Zhou virtio_crypto_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id, 5796f0175ffSJay Zhou const struct rte_cryptodev_qp_conf *qp_conf, 580725d2a7fSFan Zhang int socket_id) 5816f0175ffSJay Zhou { 5826f0175ffSJay Zhou int ret; 5836f0175ffSJay Zhou struct virtqueue *vq; 5846f0175ffSJay Zhou 5856f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 5866f0175ffSJay Zhou 5876f0175ffSJay Zhou /* if virtio dev is started, do not touch the virtqueues */ 5886f0175ffSJay Zhou if (dev->data->dev_started) 5896f0175ffSJay Zhou return 0; 5906f0175ffSJay Zhou 5916f0175ffSJay Zhou ret = virtio_crypto_queue_setup(dev, VTCRYPTO_DATAQ, queue_pair_id, 5926f0175ffSJay Zhou qp_conf->nb_descriptors, socket_id, &vq); 5936f0175ffSJay Zhou if (ret < 0) { 5946f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR( 5956f0175ffSJay Zhou "virtio crypto data queue initialization failed\n"); 5966f0175ffSJay Zhou return ret; 5976f0175ffSJay Zhou } 5986f0175ffSJay Zhou 5996f0175ffSJay Zhou dev->data->queue_pairs[queue_pair_id] = vq; 6006f0175ffSJay Zhou 6016f0175ffSJay Zhou return 0; 6026f0175ffSJay Zhou } 6036f0175ffSJay Zhou 6046f0175ffSJay Zhou static int 6056f0175ffSJay Zhou virtio_crypto_qp_release(struct rte_cryptodev *dev, uint16_t queue_pair_id) 6066f0175ffSJay Zhou { 6076f0175ffSJay Zhou struct virtqueue *vq 6086f0175ffSJay Zhou = (struct virtqueue *)dev->data->queue_pairs[queue_pair_id]; 6096f0175ffSJay Zhou 6106f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 6116f0175ffSJay Zhou 6126f0175ffSJay Zhou if (vq == NULL) { 6136f0175ffSJay Zhou VIRTIO_CRYPTO_DRV_LOG_DBG("vq already freed"); 6146f0175ffSJay Zhou return 0; 6156f0175ffSJay Zhou } 6166f0175ffSJay Zhou 6176f0175ffSJay Zhou virtio_crypto_queue_release(vq); 6186f0175ffSJay Zhou return 0; 6196f0175ffSJay Zhou } 6206f0175ffSJay Zhou 6216f0175ffSJay Zhou static int 62225500d4bSJay Zhou virtio_negotiate_features(struct virtio_crypto_hw *hw, uint64_t req_features) 62325500d4bSJay Zhou { 62425500d4bSJay Zhou uint64_t host_features; 62525500d4bSJay Zhou 62625500d4bSJay Zhou PMD_INIT_FUNC_TRACE(); 62725500d4bSJay Zhou 62825500d4bSJay Zhou /* Prepare guest_features: feature that driver wants to support */ 62925500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("guest_features before negotiate = %" PRIx64, 63025500d4bSJay Zhou req_features); 63125500d4bSJay Zhou 63225500d4bSJay Zhou /* Read device(host) feature bits */ 63325500d4bSJay Zhou host_features = VTPCI_OPS(hw)->get_features(hw); 63425500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("host_features before negotiate = %" PRIx64, 63525500d4bSJay Zhou host_features); 63625500d4bSJay Zhou 63725500d4bSJay Zhou /* 63825500d4bSJay Zhou * Negotiate features: Subset of device feature bits are written back 63925500d4bSJay Zhou * guest feature bits. 64025500d4bSJay Zhou */ 64125500d4bSJay Zhou hw->guest_features = req_features; 64225500d4bSJay Zhou hw->guest_features = vtpci_cryptodev_negotiate_features(hw, 64325500d4bSJay Zhou host_features); 64425500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("features after negotiate = %" PRIx64, 64525500d4bSJay Zhou hw->guest_features); 64625500d4bSJay Zhou 64725500d4bSJay Zhou if (hw->modern) { 64825500d4bSJay Zhou if (!vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) { 64925500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR( 65025500d4bSJay Zhou "VIRTIO_F_VERSION_1 features is not enabled."); 65125500d4bSJay Zhou return -1; 65225500d4bSJay Zhou } 65325500d4bSJay Zhou vtpci_cryptodev_set_status(hw, 65425500d4bSJay Zhou VIRTIO_CONFIG_STATUS_FEATURES_OK); 65525500d4bSJay Zhou if (!(vtpci_cryptodev_get_status(hw) & 65625500d4bSJay Zhou VIRTIO_CONFIG_STATUS_FEATURES_OK)) { 65725500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("failed to set FEATURES_OK " 65825500d4bSJay Zhou "status!"); 65925500d4bSJay Zhou return -1; 66025500d4bSJay Zhou } 66125500d4bSJay Zhou } 66225500d4bSJay Zhou 66325500d4bSJay Zhou hw->req_guest_features = req_features; 66425500d4bSJay Zhou 66525500d4bSJay Zhou return 0; 66625500d4bSJay Zhou } 66725500d4bSJay Zhou 66825500d4bSJay Zhou /* reset device and renegotiate features if needed */ 66925500d4bSJay Zhou static int 67025500d4bSJay Zhou virtio_crypto_init_device(struct rte_cryptodev *cryptodev, 67125500d4bSJay Zhou uint64_t req_features) 67225500d4bSJay Zhou { 67325500d4bSJay Zhou struct virtio_crypto_hw *hw = cryptodev->data->dev_private; 67425500d4bSJay Zhou struct virtio_crypto_config local_config; 67525500d4bSJay Zhou struct virtio_crypto_config *config = &local_config; 67625500d4bSJay Zhou 67725500d4bSJay Zhou PMD_INIT_FUNC_TRACE(); 67825500d4bSJay Zhou 67925500d4bSJay Zhou /* Reset the device although not necessary at startup */ 68025500d4bSJay Zhou vtpci_cryptodev_reset(hw); 68125500d4bSJay Zhou 68225500d4bSJay Zhou /* Tell the host we've noticed this device. */ 68325500d4bSJay Zhou vtpci_cryptodev_set_status(hw, VIRTIO_CONFIG_STATUS_ACK); 68425500d4bSJay Zhou 68525500d4bSJay Zhou /* Tell the host we've known how to drive the device. */ 68625500d4bSJay Zhou vtpci_cryptodev_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER); 68725500d4bSJay Zhou if (virtio_negotiate_features(hw, req_features) < 0) 68825500d4bSJay Zhou return -1; 68925500d4bSJay Zhou 69025500d4bSJay Zhou /* Get status of the device */ 69125500d4bSJay Zhou vtpci_read_cryptodev_config(hw, 69225500d4bSJay Zhou offsetof(struct virtio_crypto_config, status), 69325500d4bSJay Zhou &config->status, sizeof(config->status)); 69425500d4bSJay Zhou if (config->status != VIRTIO_CRYPTO_S_HW_READY) { 69525500d4bSJay Zhou VIRTIO_CRYPTO_DRV_LOG_ERR("accelerator hardware is " 69625500d4bSJay Zhou "not ready"); 69725500d4bSJay Zhou return -1; 69825500d4bSJay Zhou } 69925500d4bSJay Zhou 70025500d4bSJay Zhou /* Get number of data queues */ 70125500d4bSJay Zhou vtpci_read_cryptodev_config(hw, 70225500d4bSJay Zhou offsetof(struct virtio_crypto_config, max_dataqueues), 70325500d4bSJay Zhou &config->max_dataqueues, 70425500d4bSJay Zhou sizeof(config->max_dataqueues)); 70525500d4bSJay Zhou hw->max_dataqueues = config->max_dataqueues; 70625500d4bSJay Zhou 70725500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("hw->max_dataqueues=%d", 70825500d4bSJay Zhou hw->max_dataqueues); 70925500d4bSJay Zhou 71025500d4bSJay Zhou return 0; 71125500d4bSJay Zhou } 71225500d4bSJay Zhou 71325500d4bSJay Zhou /* 71425500d4bSJay Zhou * This function is based on probe() function 71525500d4bSJay Zhou * It returns 0 on success. 71625500d4bSJay Zhou */ 71725500d4bSJay Zhou static int 71825500d4bSJay Zhou crypto_virtio_create(const char *name, struct rte_pci_device *pci_dev, 71925500d4bSJay Zhou struct rte_cryptodev_pmd_init_params *init_params) 72025500d4bSJay Zhou { 72125500d4bSJay Zhou struct rte_cryptodev *cryptodev; 72225500d4bSJay Zhou struct virtio_crypto_hw *hw; 72325500d4bSJay Zhou 72425500d4bSJay Zhou PMD_INIT_FUNC_TRACE(); 72525500d4bSJay Zhou 72625500d4bSJay Zhou cryptodev = rte_cryptodev_pmd_create(name, &pci_dev->device, 72725500d4bSJay Zhou init_params); 72825500d4bSJay Zhou if (cryptodev == NULL) 72925500d4bSJay Zhou return -ENODEV; 73025500d4bSJay Zhou 73125500d4bSJay Zhou cryptodev->driver_id = cryptodev_virtio_driver_id; 73225500d4bSJay Zhou cryptodev->dev_ops = &virtio_crypto_dev_ops; 73325500d4bSJay Zhou 73425500d4bSJay Zhou cryptodev->enqueue_burst = virtio_crypto_pkt_tx_burst; 73525500d4bSJay Zhou cryptodev->dequeue_burst = virtio_crypto_pkt_rx_burst; 73625500d4bSJay Zhou 73725500d4bSJay Zhou cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | 738b7aa3b5bSJay Zhou RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | 739b7aa3b5bSJay Zhou RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT; 74025500d4bSJay Zhou 74125500d4bSJay Zhou hw = cryptodev->data->dev_private; 74225500d4bSJay Zhou hw->dev_id = cryptodev->data->dev_id; 7435889e1ffSJay Zhou hw->virtio_dev_capabilities = virtio_capabilities; 74425500d4bSJay Zhou 74525500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("dev %d vendorID=0x%x deviceID=0x%x", 74625500d4bSJay Zhou cryptodev->data->dev_id, pci_dev->id.vendor_id, 74725500d4bSJay Zhou pci_dev->id.device_id); 74825500d4bSJay Zhou 74925500d4bSJay Zhou /* pci device init */ 75025500d4bSJay Zhou if (vtpci_cryptodev_init(pci_dev, hw)) 75125500d4bSJay Zhou return -1; 75225500d4bSJay Zhou 75325500d4bSJay Zhou if (virtio_crypto_init_device(cryptodev, 75425500d4bSJay Zhou VIRTIO_CRYPTO_PMD_GUEST_FEATURES) < 0) 75525500d4bSJay Zhou return -1; 75625500d4bSJay Zhou 75725500d4bSJay Zhou return 0; 75825500d4bSJay Zhou } 75925500d4bSJay Zhou 7608769079aSJay Zhou static int 7616f0175ffSJay Zhou virtio_crypto_dev_uninit(struct rte_cryptodev *cryptodev) 7626f0175ffSJay Zhou { 7636f0175ffSJay Zhou struct virtio_crypto_hw *hw = cryptodev->data->dev_private; 7646f0175ffSJay Zhou 7656f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 7666f0175ffSJay Zhou 7676f0175ffSJay Zhou if (rte_eal_process_type() == RTE_PROC_SECONDARY) 7686f0175ffSJay Zhou return -EPERM; 7696f0175ffSJay Zhou 7706f0175ffSJay Zhou if (cryptodev->data->dev_started) { 7716f0175ffSJay Zhou virtio_crypto_dev_stop(cryptodev); 7726f0175ffSJay Zhou virtio_crypto_dev_close(cryptodev); 7736f0175ffSJay Zhou } 7746f0175ffSJay Zhou 7756f0175ffSJay Zhou cryptodev->dev_ops = NULL; 7766f0175ffSJay Zhou cryptodev->enqueue_burst = NULL; 7776f0175ffSJay Zhou cryptodev->dequeue_burst = NULL; 7786f0175ffSJay Zhou 7796f0175ffSJay Zhou /* release control queue */ 7806f0175ffSJay Zhou virtio_crypto_queue_release(hw->cvq); 7816f0175ffSJay Zhou 7826f0175ffSJay Zhou rte_free(cryptodev->data); 7836f0175ffSJay Zhou cryptodev->data = NULL; 7846f0175ffSJay Zhou 7856f0175ffSJay Zhou VIRTIO_CRYPTO_DRV_LOG_INFO("dev_uninit completed"); 7866f0175ffSJay Zhou 7876f0175ffSJay Zhou return 0; 7886f0175ffSJay Zhou } 7896f0175ffSJay Zhou 7906f0175ffSJay Zhou static int 7916f0175ffSJay Zhou virtio_crypto_dev_configure(struct rte_cryptodev *cryptodev, 7926f0175ffSJay Zhou struct rte_cryptodev_config *config __rte_unused) 7936f0175ffSJay Zhou { 7946f0175ffSJay Zhou struct virtio_crypto_hw *hw = cryptodev->data->dev_private; 7956f0175ffSJay Zhou 7966f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 7976f0175ffSJay Zhou 7986f0175ffSJay Zhou if (virtio_crypto_init_device(cryptodev, 7996f0175ffSJay Zhou VIRTIO_CRYPTO_PMD_GUEST_FEATURES) < 0) 8006f0175ffSJay Zhou return -1; 8016f0175ffSJay Zhou 8026f0175ffSJay Zhou /* setup control queue 8036f0175ffSJay Zhou * [0, 1, ... ,(config->max_dataqueues - 1)] are data queues 8046f0175ffSJay Zhou * config->max_dataqueues is the control queue 8056f0175ffSJay Zhou */ 8066f0175ffSJay Zhou if (virtio_crypto_ctrlq_setup(cryptodev, hw->max_dataqueues) < 0) { 8076f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("control queue setup error"); 8086f0175ffSJay Zhou return -1; 8096f0175ffSJay Zhou } 8106f0175ffSJay Zhou virtio_crypto_ctrlq_start(cryptodev); 8116f0175ffSJay Zhou 8126f0175ffSJay Zhou return 0; 8136f0175ffSJay Zhou } 8146f0175ffSJay Zhou 8156f0175ffSJay Zhou static void 8166f0175ffSJay Zhou virtio_crypto_dev_stop(struct rte_cryptodev *dev) 8176f0175ffSJay Zhou { 8186f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 8196f0175ffSJay Zhou 8206f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 8216f0175ffSJay Zhou VIRTIO_CRYPTO_DRV_LOG_DBG("virtio_dev_stop"); 8226f0175ffSJay Zhou 8236f0175ffSJay Zhou vtpci_cryptodev_reset(hw); 8246f0175ffSJay Zhou 8256f0175ffSJay Zhou virtio_crypto_dev_free_mbufs(dev); 8266f0175ffSJay Zhou virtio_crypto_free_queues(dev); 8276f0175ffSJay Zhou 8286f0175ffSJay Zhou dev->data->dev_started = 0; 8296f0175ffSJay Zhou } 8306f0175ffSJay Zhou 8316f0175ffSJay Zhou static int 8326f0175ffSJay Zhou virtio_crypto_dev_start(struct rte_cryptodev *dev) 8336f0175ffSJay Zhou { 8346f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 8356f0175ffSJay Zhou 8366f0175ffSJay Zhou if (dev->data->dev_started) 8376f0175ffSJay Zhou return 0; 8386f0175ffSJay Zhou 8396f0175ffSJay Zhou /* Do final configuration before queue engine starts */ 8406f0175ffSJay Zhou virtio_crypto_dataq_start(dev); 8416f0175ffSJay Zhou vtpci_cryptodev_reinit_complete(hw); 8426f0175ffSJay Zhou 8436f0175ffSJay Zhou dev->data->dev_started = 1; 8446f0175ffSJay Zhou 8456f0175ffSJay Zhou return 0; 8466f0175ffSJay Zhou } 8476f0175ffSJay Zhou 8486f0175ffSJay Zhou static void 8496f0175ffSJay Zhou virtio_crypto_dev_free_mbufs(struct rte_cryptodev *dev) 8506f0175ffSJay Zhou { 8516f0175ffSJay Zhou uint32_t i; 8526f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 8536f0175ffSJay Zhou 8546f0175ffSJay Zhou for (i = 0; i < hw->max_dataqueues; i++) { 8556f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("Before freeing dataq[%d] used " 8566f0175ffSJay Zhou "and unused buf", i); 8576f0175ffSJay Zhou VIRTQUEUE_DUMP((struct virtqueue *) 8586f0175ffSJay Zhou dev->data->queue_pairs[i]); 8596f0175ffSJay Zhou 8606f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("queue_pairs[%d]=%p", 8616f0175ffSJay Zhou i, dev->data->queue_pairs[i]); 8626f0175ffSJay Zhou 8636f0175ffSJay Zhou virtqueue_detatch_unused(dev->data->queue_pairs[i]); 8646f0175ffSJay Zhou 8656f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("After freeing dataq[%d] used and " 8666f0175ffSJay Zhou "unused buf", i); 8676f0175ffSJay Zhou VIRTQUEUE_DUMP( 8686f0175ffSJay Zhou (struct virtqueue *)dev->data->queue_pairs[i]); 8696f0175ffSJay Zhou } 8706f0175ffSJay Zhou } 8716f0175ffSJay Zhou 872b7fa78c7SJay Zhou static unsigned int 873b7fa78c7SJay Zhou virtio_crypto_sym_get_session_private_size( 874b7fa78c7SJay Zhou struct rte_cryptodev *dev __rte_unused) 875b7fa78c7SJay Zhou { 876b7fa78c7SJay Zhou PMD_INIT_FUNC_TRACE(); 877b7fa78c7SJay Zhou 878b7fa78c7SJay Zhou return RTE_ALIGN_CEIL(sizeof(struct virtio_crypto_session), 16); 879b7fa78c7SJay Zhou } 880b7fa78c7SJay Zhou 881b7fa78c7SJay Zhou static int 882b7fa78c7SJay Zhou virtio_crypto_check_sym_session_paras( 883b7fa78c7SJay Zhou struct rte_cryptodev *dev) 884b7fa78c7SJay Zhou { 885b7fa78c7SJay Zhou struct virtio_crypto_hw *hw; 886b7fa78c7SJay Zhou 887b7fa78c7SJay Zhou PMD_INIT_FUNC_TRACE(); 888b7fa78c7SJay Zhou 889b7fa78c7SJay Zhou if (unlikely(dev == NULL)) { 890b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("dev is NULL"); 891b7fa78c7SJay Zhou return -1; 892b7fa78c7SJay Zhou } 893b7fa78c7SJay Zhou if (unlikely(dev->data == NULL)) { 894b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("dev->data is NULL"); 895b7fa78c7SJay Zhou return -1; 896b7fa78c7SJay Zhou } 897b7fa78c7SJay Zhou hw = dev->data->dev_private; 898b7fa78c7SJay Zhou if (unlikely(hw == NULL)) { 899b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("hw is NULL"); 900b7fa78c7SJay Zhou return -1; 901b7fa78c7SJay Zhou } 902b7fa78c7SJay Zhou if (unlikely(hw->cvq == NULL)) { 903b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("vq is NULL"); 904b7fa78c7SJay Zhou return -1; 905b7fa78c7SJay Zhou } 906b7fa78c7SJay Zhou 907b7fa78c7SJay Zhou return 0; 908b7fa78c7SJay Zhou } 909b7fa78c7SJay Zhou 910b7fa78c7SJay Zhou static int 911b7fa78c7SJay Zhou virtio_crypto_check_sym_clear_session_paras( 912b7fa78c7SJay Zhou struct rte_cryptodev *dev, 913b7fa78c7SJay Zhou struct rte_cryptodev_sym_session *sess) 914b7fa78c7SJay Zhou { 915b7fa78c7SJay Zhou PMD_INIT_FUNC_TRACE(); 916b7fa78c7SJay Zhou 917b7fa78c7SJay Zhou if (sess == NULL) { 918b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("sym_session is NULL"); 919b7fa78c7SJay Zhou return -1; 920b7fa78c7SJay Zhou } 921b7fa78c7SJay Zhou 922b7fa78c7SJay Zhou return virtio_crypto_check_sym_session_paras(dev); 923b7fa78c7SJay Zhou } 924b7fa78c7SJay Zhou 925b7fa78c7SJay Zhou #define NUM_ENTRY_SYM_CLEAR_SESSION 2 926b7fa78c7SJay Zhou 927b7fa78c7SJay Zhou static void 928b7fa78c7SJay Zhou virtio_crypto_sym_clear_session( 929b7fa78c7SJay Zhou struct rte_cryptodev *dev, 930b7fa78c7SJay Zhou struct rte_cryptodev_sym_session *sess) 931b7fa78c7SJay Zhou { 932b7fa78c7SJay Zhou struct virtio_crypto_hw *hw; 933b7fa78c7SJay Zhou struct virtqueue *vq; 934b7fa78c7SJay Zhou struct virtio_crypto_session *session; 935b7fa78c7SJay Zhou struct virtio_crypto_op_ctrl_req *ctrl; 936b7fa78c7SJay Zhou struct vring_desc *desc; 937b7fa78c7SJay Zhou uint8_t *status; 938b7fa78c7SJay Zhou uint8_t needed = 1; 939b7fa78c7SJay Zhou uint32_t head; 940b7fa78c7SJay Zhou uint8_t *malloc_virt_addr; 941b7fa78c7SJay Zhou uint64_t malloc_phys_addr; 942b7fa78c7SJay Zhou uint8_t len_inhdr = sizeof(struct virtio_crypto_inhdr); 943b7fa78c7SJay Zhou uint32_t len_op_ctrl_req = sizeof(struct virtio_crypto_op_ctrl_req); 944b7fa78c7SJay Zhou uint32_t desc_offset = len_op_ctrl_req + len_inhdr; 945b7fa78c7SJay Zhou 946b7fa78c7SJay Zhou PMD_INIT_FUNC_TRACE(); 947b7fa78c7SJay Zhou 948b7fa78c7SJay Zhou if (virtio_crypto_check_sym_clear_session_paras(dev, sess) < 0) 949b7fa78c7SJay Zhou return; 950b7fa78c7SJay Zhou 951b7fa78c7SJay Zhou hw = dev->data->dev_private; 952b7fa78c7SJay Zhou vq = hw->cvq; 953012c5076SPablo de Lara session = (struct virtio_crypto_session *)get_sym_session_private_data( 954b7fa78c7SJay Zhou sess, cryptodev_virtio_driver_id); 955b7fa78c7SJay Zhou if (session == NULL) { 956b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Invalid session parameter"); 957b7fa78c7SJay Zhou return; 958b7fa78c7SJay Zhou } 959b7fa78c7SJay Zhou 960b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_INFO("vq->vq_desc_head_idx = %d, " 961b7fa78c7SJay Zhou "vq = %p", vq->vq_desc_head_idx, vq); 962b7fa78c7SJay Zhou 963b7fa78c7SJay Zhou if (vq->vq_free_cnt < needed) { 964b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 965b7fa78c7SJay Zhou "vq->vq_free_cnt = %d is less than %d, " 966b7fa78c7SJay Zhou "not enough", vq->vq_free_cnt, needed); 967b7fa78c7SJay Zhou return; 968b7fa78c7SJay Zhou } 969b7fa78c7SJay Zhou 970b7fa78c7SJay Zhou /* 971b7fa78c7SJay Zhou * malloc memory to store information of ctrl request op, 972b7fa78c7SJay Zhou * returned status and desc vring 973b7fa78c7SJay Zhou */ 974b7fa78c7SJay Zhou malloc_virt_addr = rte_malloc(NULL, len_op_ctrl_req + len_inhdr 975b7fa78c7SJay Zhou + NUM_ENTRY_SYM_CLEAR_SESSION 976b7fa78c7SJay Zhou * sizeof(struct vring_desc), RTE_CACHE_LINE_SIZE); 977b7fa78c7SJay Zhou if (malloc_virt_addr == NULL) { 978b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("not enough heap room"); 979b7fa78c7SJay Zhou return; 980b7fa78c7SJay Zhou } 981b7fa78c7SJay Zhou malloc_phys_addr = rte_malloc_virt2iova(malloc_virt_addr); 982b7fa78c7SJay Zhou 983b7fa78c7SJay Zhou /* assign ctrl request op part */ 984b7fa78c7SJay Zhou ctrl = (struct virtio_crypto_op_ctrl_req *)malloc_virt_addr; 985b7fa78c7SJay Zhou ctrl->header.opcode = VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION; 986b7fa78c7SJay Zhou /* default data virtqueue is 0 */ 987b7fa78c7SJay Zhou ctrl->header.queue_id = 0; 988b7fa78c7SJay Zhou ctrl->u.destroy_session.session_id = session->session_id; 989b7fa78c7SJay Zhou 990b7fa78c7SJay Zhou /* status part */ 991b7fa78c7SJay Zhou status = &(((struct virtio_crypto_inhdr *) 992b7fa78c7SJay Zhou ((uint8_t *)malloc_virt_addr + len_op_ctrl_req))->status); 993b7fa78c7SJay Zhou *status = VIRTIO_CRYPTO_ERR; 994b7fa78c7SJay Zhou 995b7fa78c7SJay Zhou /* indirect desc vring part */ 996b7fa78c7SJay Zhou desc = (struct vring_desc *)((uint8_t *)malloc_virt_addr 997b7fa78c7SJay Zhou + desc_offset); 998b7fa78c7SJay Zhou 999b7fa78c7SJay Zhou /* ctrl request part */ 1000b7fa78c7SJay Zhou desc[0].addr = malloc_phys_addr; 1001b7fa78c7SJay Zhou desc[0].len = len_op_ctrl_req; 1002b7fa78c7SJay Zhou desc[0].flags = VRING_DESC_F_NEXT; 1003b7fa78c7SJay Zhou desc[0].next = 1; 1004b7fa78c7SJay Zhou 1005b7fa78c7SJay Zhou /* status part */ 1006b7fa78c7SJay Zhou desc[1].addr = malloc_phys_addr + len_op_ctrl_req; 1007b7fa78c7SJay Zhou desc[1].len = len_inhdr; 1008b7fa78c7SJay Zhou desc[1].flags = VRING_DESC_F_WRITE; 1009b7fa78c7SJay Zhou 1010b7fa78c7SJay Zhou /* use only a single desc entry */ 1011b7fa78c7SJay Zhou head = vq->vq_desc_head_idx; 1012b7fa78c7SJay Zhou vq->vq_ring.desc[head].flags = VRING_DESC_F_INDIRECT; 1013b7fa78c7SJay Zhou vq->vq_ring.desc[head].addr = malloc_phys_addr + desc_offset; 1014b7fa78c7SJay Zhou vq->vq_ring.desc[head].len 1015b7fa78c7SJay Zhou = NUM_ENTRY_SYM_CLEAR_SESSION 1016b7fa78c7SJay Zhou * sizeof(struct vring_desc); 1017b7fa78c7SJay Zhou vq->vq_free_cnt -= needed; 1018b7fa78c7SJay Zhou 1019b7fa78c7SJay Zhou vq->vq_desc_head_idx = vq->vq_ring.desc[head].next; 1020b7fa78c7SJay Zhou 1021b7fa78c7SJay Zhou vq_update_avail_ring(vq, head); 1022b7fa78c7SJay Zhou vq_update_avail_idx(vq); 1023b7fa78c7SJay Zhou 1024b7fa78c7SJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_queue_index = %d", 1025b7fa78c7SJay Zhou vq->vq_queue_index); 1026b7fa78c7SJay Zhou 1027b7fa78c7SJay Zhou virtqueue_notify(vq); 1028b7fa78c7SJay Zhou 1029b7fa78c7SJay Zhou rte_rmb(); 1030b7fa78c7SJay Zhou while (vq->vq_used_cons_idx == vq->vq_ring.used->idx) { 1031b7fa78c7SJay Zhou rte_rmb(); 1032b7fa78c7SJay Zhou usleep(100); 1033b7fa78c7SJay Zhou } 1034b7fa78c7SJay Zhou 1035b7fa78c7SJay Zhou while (vq->vq_used_cons_idx != vq->vq_ring.used->idx) { 1036b7fa78c7SJay Zhou uint32_t idx, desc_idx, used_idx; 1037b7fa78c7SJay Zhou struct vring_used_elem *uep; 1038b7fa78c7SJay Zhou 1039b7fa78c7SJay Zhou used_idx = (uint32_t)(vq->vq_used_cons_idx 1040b7fa78c7SJay Zhou & (vq->vq_nentries - 1)); 1041b7fa78c7SJay Zhou uep = &vq->vq_ring.used->ring[used_idx]; 1042b7fa78c7SJay Zhou idx = (uint32_t) uep->id; 1043b7fa78c7SJay Zhou desc_idx = idx; 1044b7fa78c7SJay Zhou while (vq->vq_ring.desc[desc_idx].flags 1045b7fa78c7SJay Zhou & VRING_DESC_F_NEXT) { 1046b7fa78c7SJay Zhou desc_idx = vq->vq_ring.desc[desc_idx].next; 1047b7fa78c7SJay Zhou vq->vq_free_cnt++; 1048b7fa78c7SJay Zhou } 1049b7fa78c7SJay Zhou 1050b7fa78c7SJay Zhou vq->vq_ring.desc[desc_idx].next = vq->vq_desc_head_idx; 1051b7fa78c7SJay Zhou vq->vq_desc_head_idx = idx; 1052b7fa78c7SJay Zhou vq->vq_used_cons_idx++; 1053b7fa78c7SJay Zhou vq->vq_free_cnt++; 1054b7fa78c7SJay Zhou } 1055b7fa78c7SJay Zhou 1056b7fa78c7SJay Zhou if (*status != VIRTIO_CRYPTO_OK) { 1057b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Close session failed " 1058b7fa78c7SJay Zhou "status=%"PRIu32", session_id=%"PRIu64"", 1059b7fa78c7SJay Zhou *status, session->session_id); 1060b7fa78c7SJay Zhou rte_free(malloc_virt_addr); 1061b7fa78c7SJay Zhou return; 1062b7fa78c7SJay Zhou } 1063b7fa78c7SJay Zhou 1064b7fa78c7SJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_free_cnt=%d\n" 1065b7fa78c7SJay Zhou "vq->vq_desc_head_idx=%d", 1066b7fa78c7SJay Zhou vq->vq_free_cnt, vq->vq_desc_head_idx); 1067b7fa78c7SJay Zhou 1068b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_INFO("Close session %"PRIu64" successfully ", 1069b7fa78c7SJay Zhou session->session_id); 1070b7fa78c7SJay Zhou 10714487cfa1SPablo de Lara memset(session, 0, sizeof(struct virtio_crypto_session)); 10724487cfa1SPablo de Lara struct rte_mempool *sess_mp = rte_mempool_from_obj(session); 10734487cfa1SPablo de Lara set_sym_session_private_data(sess, cryptodev_virtio_driver_id, NULL); 10744487cfa1SPablo de Lara rte_mempool_put(sess_mp, session); 1075b7fa78c7SJay Zhou rte_free(malloc_virt_addr); 1076b7fa78c7SJay Zhou } 1077b7fa78c7SJay Zhou 1078b7fa78c7SJay Zhou static struct rte_crypto_cipher_xform * 1079b7fa78c7SJay Zhou virtio_crypto_get_cipher_xform(struct rte_crypto_sym_xform *xform) 1080b7fa78c7SJay Zhou { 1081b7fa78c7SJay Zhou do { 1082b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) 1083b7fa78c7SJay Zhou return &xform->cipher; 1084b7fa78c7SJay Zhou 1085b7fa78c7SJay Zhou xform = xform->next; 1086b7fa78c7SJay Zhou } while (xform); 1087b7fa78c7SJay Zhou 1088b7fa78c7SJay Zhou return NULL; 1089b7fa78c7SJay Zhou } 1090b7fa78c7SJay Zhou 1091b7fa78c7SJay Zhou static struct rte_crypto_auth_xform * 1092b7fa78c7SJay Zhou virtio_crypto_get_auth_xform(struct rte_crypto_sym_xform *xform) 1093b7fa78c7SJay Zhou { 1094b7fa78c7SJay Zhou do { 1095b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) 1096b7fa78c7SJay Zhou return &xform->auth; 1097b7fa78c7SJay Zhou 1098b7fa78c7SJay Zhou xform = xform->next; 1099b7fa78c7SJay Zhou } while (xform); 1100b7fa78c7SJay Zhou 1101b7fa78c7SJay Zhou return NULL; 1102b7fa78c7SJay Zhou } 1103b7fa78c7SJay Zhou 1104b7fa78c7SJay Zhou /** Get xform chain order */ 1105b7fa78c7SJay Zhou static int 1106b7fa78c7SJay Zhou virtio_crypto_get_chain_order(struct rte_crypto_sym_xform *xform) 1107b7fa78c7SJay Zhou { 1108b7fa78c7SJay Zhou if (xform == NULL) 1109b7fa78c7SJay Zhou return -1; 1110b7fa78c7SJay Zhou 1111b7fa78c7SJay Zhou /* Cipher Only */ 1112b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 1113b7fa78c7SJay Zhou xform->next == NULL) 1114b7fa78c7SJay Zhou return VIRTIO_CRYPTO_CMD_CIPHER; 1115b7fa78c7SJay Zhou 1116b7fa78c7SJay Zhou /* Authentication Only */ 1117b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 1118b7fa78c7SJay Zhou xform->next == NULL) 1119b7fa78c7SJay Zhou return VIRTIO_CRYPTO_CMD_AUTH; 1120b7fa78c7SJay Zhou 1121b7fa78c7SJay Zhou /* Authenticate then Cipher */ 1122b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 1123b7fa78c7SJay Zhou xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) 1124b7fa78c7SJay Zhou return VIRTIO_CRYPTO_CMD_HASH_CIPHER; 1125b7fa78c7SJay Zhou 1126b7fa78c7SJay Zhou /* Cipher then Authenticate */ 1127b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 1128b7fa78c7SJay Zhou xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) 1129b7fa78c7SJay Zhou return VIRTIO_CRYPTO_CMD_CIPHER_HASH; 1130b7fa78c7SJay Zhou 1131b7fa78c7SJay Zhou return -1; 1132b7fa78c7SJay Zhou } 1133b7fa78c7SJay Zhou 1134b7fa78c7SJay Zhou static int 1135b7fa78c7SJay Zhou virtio_crypto_sym_pad_cipher_param( 1136b7fa78c7SJay Zhou struct virtio_crypto_cipher_session_para *para, 1137b7fa78c7SJay Zhou struct rte_crypto_cipher_xform *cipher_xform) 1138b7fa78c7SJay Zhou { 1139b7fa78c7SJay Zhou switch (cipher_xform->algo) { 11405889e1ffSJay Zhou case RTE_CRYPTO_CIPHER_AES_CBC: 11415889e1ffSJay Zhou para->algo = VIRTIO_CRYPTO_CIPHER_AES_CBC; 11425889e1ffSJay Zhou break; 1143b7fa78c7SJay Zhou default: 1144b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Crypto: Unsupported " 1145b7fa78c7SJay Zhou "Cipher alg %u", cipher_xform->algo); 1146b7fa78c7SJay Zhou return -1; 1147b7fa78c7SJay Zhou } 1148b7fa78c7SJay Zhou 1149b7fa78c7SJay Zhou para->keylen = cipher_xform->key.length; 1150b7fa78c7SJay Zhou switch (cipher_xform->op) { 1151b7fa78c7SJay Zhou case RTE_CRYPTO_CIPHER_OP_ENCRYPT: 1152b7fa78c7SJay Zhou para->op = VIRTIO_CRYPTO_OP_ENCRYPT; 1153b7fa78c7SJay Zhou break; 1154b7fa78c7SJay Zhou case RTE_CRYPTO_CIPHER_OP_DECRYPT: 1155b7fa78c7SJay Zhou para->op = VIRTIO_CRYPTO_OP_DECRYPT; 1156b7fa78c7SJay Zhou break; 1157b7fa78c7SJay Zhou default: 1158b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Unsupported cipher operation " 1159b7fa78c7SJay Zhou "parameter"); 1160b7fa78c7SJay Zhou return -1; 1161b7fa78c7SJay Zhou } 1162b7fa78c7SJay Zhou 1163b7fa78c7SJay Zhou return 0; 1164b7fa78c7SJay Zhou } 1165b7fa78c7SJay Zhou 1166b7fa78c7SJay Zhou static int 1167b7fa78c7SJay Zhou virtio_crypto_sym_pad_auth_param( 1168b7fa78c7SJay Zhou struct virtio_crypto_op_ctrl_req *ctrl, 1169b7fa78c7SJay Zhou struct rte_crypto_auth_xform *auth_xform) 1170b7fa78c7SJay Zhou { 1171b7fa78c7SJay Zhou uint32_t *algo; 1172b7fa78c7SJay Zhou struct virtio_crypto_alg_chain_session_para *para = 1173b7fa78c7SJay Zhou &(ctrl->u.sym_create_session.u.chain.para); 1174b7fa78c7SJay Zhou 1175b7fa78c7SJay Zhou switch (ctrl->u.sym_create_session.u.chain.para.hash_mode) { 1176b7fa78c7SJay Zhou case VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN: 1177b7fa78c7SJay Zhou algo = &(para->u.hash_param.algo); 1178b7fa78c7SJay Zhou break; 1179b7fa78c7SJay Zhou case VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH: 1180b7fa78c7SJay Zhou algo = &(para->u.mac_param.algo); 1181b7fa78c7SJay Zhou break; 1182b7fa78c7SJay Zhou default: 1183b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Unsupported hash mode %u " 1184b7fa78c7SJay Zhou "specified", 1185b7fa78c7SJay Zhou ctrl->u.sym_create_session.u.chain.para.hash_mode); 1186b7fa78c7SJay Zhou return -1; 1187b7fa78c7SJay Zhou } 1188b7fa78c7SJay Zhou 1189b7fa78c7SJay Zhou switch (auth_xform->algo) { 11908144eadaSJay Zhou case RTE_CRYPTO_AUTH_SHA1_HMAC: 11918144eadaSJay Zhou *algo = VIRTIO_CRYPTO_MAC_HMAC_SHA1; 11928144eadaSJay Zhou break; 1193b7fa78c7SJay Zhou default: 1194b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1195b7fa78c7SJay Zhou "Crypto: Undefined Hash algo %u specified", 1196b7fa78c7SJay Zhou auth_xform->algo); 1197b7fa78c7SJay Zhou return -1; 1198b7fa78c7SJay Zhou } 1199b7fa78c7SJay Zhou 1200b7fa78c7SJay Zhou return 0; 1201b7fa78c7SJay Zhou } 1202b7fa78c7SJay Zhou 1203b7fa78c7SJay Zhou static int 1204b7fa78c7SJay Zhou virtio_crypto_sym_pad_op_ctrl_req( 1205b7fa78c7SJay Zhou struct virtio_crypto_op_ctrl_req *ctrl, 1206b7fa78c7SJay Zhou struct rte_crypto_sym_xform *xform, bool is_chainned, 1207186b14d6SFan Zhang uint8_t *cipher_key_data, uint8_t *auth_key_data, 1208b7fa78c7SJay Zhou struct virtio_crypto_session *session) 1209b7fa78c7SJay Zhou { 1210b7fa78c7SJay Zhou int ret; 1211b7fa78c7SJay Zhou struct rte_crypto_auth_xform *auth_xform = NULL; 1212b7fa78c7SJay Zhou struct rte_crypto_cipher_xform *cipher_xform = NULL; 1213b7fa78c7SJay Zhou 1214b7fa78c7SJay Zhou /* Get cipher xform from crypto xform chain */ 1215b7fa78c7SJay Zhou cipher_xform = virtio_crypto_get_cipher_xform(xform); 1216b7fa78c7SJay Zhou if (cipher_xform) { 1217186b14d6SFan Zhang if (cipher_xform->key.length > VIRTIO_CRYPTO_MAX_KEY_SIZE) { 1218186b14d6SFan Zhang VIRTIO_CRYPTO_SESSION_LOG_ERR( 1219186b14d6SFan Zhang "cipher key size cannot be longer than %u", 1220186b14d6SFan Zhang VIRTIO_CRYPTO_MAX_KEY_SIZE); 1221186b14d6SFan Zhang return -1; 1222186b14d6SFan Zhang } 1223b063e843SFan Zhang if (cipher_xform->iv.length > VIRTIO_CRYPTO_MAX_IV_SIZE) { 1224b063e843SFan Zhang VIRTIO_CRYPTO_SESSION_LOG_ERR( 1225b063e843SFan Zhang "cipher IV size cannot be longer than %u", 1226b063e843SFan Zhang VIRTIO_CRYPTO_MAX_IV_SIZE); 1227b063e843SFan Zhang return -1; 1228b063e843SFan Zhang } 1229b7fa78c7SJay Zhou if (is_chainned) 1230b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_cipher_param( 1231b7fa78c7SJay Zhou &ctrl->u.sym_create_session.u.chain.para 1232b7fa78c7SJay Zhou .cipher_param, cipher_xform); 1233b7fa78c7SJay Zhou else 1234b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_cipher_param( 1235b7fa78c7SJay Zhou &ctrl->u.sym_create_session.u.cipher.para, 1236b7fa78c7SJay Zhou cipher_xform); 1237b7fa78c7SJay Zhou 1238b7fa78c7SJay Zhou if (ret < 0) { 1239b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1240b7fa78c7SJay Zhou "pad cipher parameter failed"); 1241b7fa78c7SJay Zhou return -1; 1242b7fa78c7SJay Zhou } 1243b7fa78c7SJay Zhou 1244186b14d6SFan Zhang memcpy(cipher_key_data, cipher_xform->key.data, 1245186b14d6SFan Zhang cipher_xform->key.length); 1246b7fa78c7SJay Zhou 1247b7fa78c7SJay Zhou session->iv.offset = cipher_xform->iv.offset; 1248b7fa78c7SJay Zhou session->iv.length = cipher_xform->iv.length; 1249b7fa78c7SJay Zhou } 1250b7fa78c7SJay Zhou 1251b7fa78c7SJay Zhou /* Get auth xform from crypto xform chain */ 1252b7fa78c7SJay Zhou auth_xform = virtio_crypto_get_auth_xform(xform); 1253b7fa78c7SJay Zhou if (auth_xform) { 1254b7fa78c7SJay Zhou /* FIXME: support VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED */ 1255b7fa78c7SJay Zhou struct virtio_crypto_alg_chain_session_para *para = 1256b7fa78c7SJay Zhou &(ctrl->u.sym_create_session.u.chain.para); 1257b7fa78c7SJay Zhou if (auth_xform->key.length) { 1258186b14d6SFan Zhang if (auth_xform->key.length > 1259186b14d6SFan Zhang VIRTIO_CRYPTO_MAX_KEY_SIZE) { 1260186b14d6SFan Zhang VIRTIO_CRYPTO_SESSION_LOG_ERR( 1261186b14d6SFan Zhang "auth key size cannot be longer than %u", 1262186b14d6SFan Zhang VIRTIO_CRYPTO_MAX_KEY_SIZE); 1263186b14d6SFan Zhang return -1; 1264186b14d6SFan Zhang } 1265b7fa78c7SJay Zhou para->hash_mode = VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH; 1266b7fa78c7SJay Zhou para->u.mac_param.auth_key_len = 1267b7fa78c7SJay Zhou (uint32_t)auth_xform->key.length; 1268b7fa78c7SJay Zhou para->u.mac_param.hash_result_len = 1269b7fa78c7SJay Zhou auth_xform->digest_length; 1270186b14d6SFan Zhang memcpy(auth_key_data, auth_xform->key.data, 1271186b14d6SFan Zhang auth_xform->key.length); 1272b7fa78c7SJay Zhou } else { 1273b7fa78c7SJay Zhou para->hash_mode = VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN; 1274b7fa78c7SJay Zhou para->u.hash_param.hash_result_len = 1275b7fa78c7SJay Zhou auth_xform->digest_length; 1276b7fa78c7SJay Zhou } 1277b7fa78c7SJay Zhou 1278b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_auth_param(ctrl, auth_xform); 1279b7fa78c7SJay Zhou if (ret < 0) { 1280b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("pad auth parameter " 1281b7fa78c7SJay Zhou "failed"); 1282b7fa78c7SJay Zhou return -1; 1283b7fa78c7SJay Zhou } 1284b7fa78c7SJay Zhou } 1285b7fa78c7SJay Zhou 1286b7fa78c7SJay Zhou return 0; 1287b7fa78c7SJay Zhou } 1288b7fa78c7SJay Zhou 1289b7fa78c7SJay Zhou static int 1290b7fa78c7SJay Zhou virtio_crypto_check_sym_configure_session_paras( 1291b7fa78c7SJay Zhou struct rte_cryptodev *dev, 1292b7fa78c7SJay Zhou struct rte_crypto_sym_xform *xform, 1293b7fa78c7SJay Zhou struct rte_cryptodev_sym_session *sym_sess, 1294b7fa78c7SJay Zhou struct rte_mempool *mempool) 1295b7fa78c7SJay Zhou { 1296b7fa78c7SJay Zhou if (unlikely(xform == NULL) || unlikely(sym_sess == NULL) || 1297b7fa78c7SJay Zhou unlikely(mempool == NULL)) { 1298b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("NULL pointer"); 1299b7fa78c7SJay Zhou return -1; 1300b7fa78c7SJay Zhou } 1301b7fa78c7SJay Zhou 1302b7fa78c7SJay Zhou if (virtio_crypto_check_sym_session_paras(dev) < 0) 1303b7fa78c7SJay Zhou return -1; 1304b7fa78c7SJay Zhou 1305b7fa78c7SJay Zhou return 0; 1306b7fa78c7SJay Zhou } 1307b7fa78c7SJay Zhou 1308b7fa78c7SJay Zhou static int 1309b7fa78c7SJay Zhou virtio_crypto_sym_configure_session( 1310b7fa78c7SJay Zhou struct rte_cryptodev *dev, 1311b7fa78c7SJay Zhou struct rte_crypto_sym_xform *xform, 1312b7fa78c7SJay Zhou struct rte_cryptodev_sym_session *sess, 1313b7fa78c7SJay Zhou struct rte_mempool *mempool) 1314b7fa78c7SJay Zhou { 1315b7fa78c7SJay Zhou int ret; 1316b7fa78c7SJay Zhou struct virtio_crypto_session crypto_sess; 1317b7fa78c7SJay Zhou void *session_private = &crypto_sess; 1318b7fa78c7SJay Zhou struct virtio_crypto_session *session; 1319b7fa78c7SJay Zhou struct virtio_crypto_op_ctrl_req *ctrl_req; 1320b7fa78c7SJay Zhou enum virtio_crypto_cmd_id cmd_id; 1321186b14d6SFan Zhang uint8_t cipher_key_data[VIRTIO_CRYPTO_MAX_KEY_SIZE] = {0}; 1322186b14d6SFan Zhang uint8_t auth_key_data[VIRTIO_CRYPTO_MAX_KEY_SIZE] = {0}; 1323b7fa78c7SJay Zhou struct virtio_crypto_hw *hw; 1324b7fa78c7SJay Zhou struct virtqueue *control_vq; 1325b7fa78c7SJay Zhou 1326b7fa78c7SJay Zhou PMD_INIT_FUNC_TRACE(); 1327b7fa78c7SJay Zhou 1328b7fa78c7SJay Zhou ret = virtio_crypto_check_sym_configure_session_paras(dev, xform, 1329b7fa78c7SJay Zhou sess, mempool); 1330b7fa78c7SJay Zhou if (ret < 0) { 1331b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Invalid parameters"); 1332b7fa78c7SJay Zhou return ret; 1333b7fa78c7SJay Zhou } 1334b7fa78c7SJay Zhou 1335b7fa78c7SJay Zhou if (rte_mempool_get(mempool, &session_private)) { 1336b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1337b7fa78c7SJay Zhou "Couldn't get object from session mempool"); 1338b7fa78c7SJay Zhou return -ENOMEM; 1339b7fa78c7SJay Zhou } 1340b7fa78c7SJay Zhou 1341b7fa78c7SJay Zhou session = (struct virtio_crypto_session *)session_private; 1342b7fa78c7SJay Zhou memset(session, 0, sizeof(struct virtio_crypto_session)); 1343b7fa78c7SJay Zhou ctrl_req = &session->ctrl; 1344b7fa78c7SJay Zhou ctrl_req->header.opcode = VIRTIO_CRYPTO_CIPHER_CREATE_SESSION; 1345b7fa78c7SJay Zhou /* FIXME: support multiqueue */ 1346b7fa78c7SJay Zhou ctrl_req->header.queue_id = 0; 1347b7fa78c7SJay Zhou 1348b7fa78c7SJay Zhou hw = dev->data->dev_private; 1349b7fa78c7SJay Zhou control_vq = hw->cvq; 1350b7fa78c7SJay Zhou 1351b7fa78c7SJay Zhou cmd_id = virtio_crypto_get_chain_order(xform); 1352b7fa78c7SJay Zhou if (cmd_id == VIRTIO_CRYPTO_CMD_CIPHER_HASH) 1353b7fa78c7SJay Zhou ctrl_req->u.sym_create_session.u.chain.para.alg_chain_order 1354b7fa78c7SJay Zhou = VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH; 1355b7fa78c7SJay Zhou if (cmd_id == VIRTIO_CRYPTO_CMD_HASH_CIPHER) 1356b7fa78c7SJay Zhou ctrl_req->u.sym_create_session.u.chain.para.alg_chain_order 1357b7fa78c7SJay Zhou = VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER; 1358b7fa78c7SJay Zhou 1359b7fa78c7SJay Zhou switch (cmd_id) { 1360b7fa78c7SJay Zhou case VIRTIO_CRYPTO_CMD_CIPHER_HASH: 1361b7fa78c7SJay Zhou case VIRTIO_CRYPTO_CMD_HASH_CIPHER: 1362b7fa78c7SJay Zhou ctrl_req->u.sym_create_session.op_type 1363b7fa78c7SJay Zhou = VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING; 1364b7fa78c7SJay Zhou 1365b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl_req, 1366186b14d6SFan Zhang xform, true, cipher_key_data, auth_key_data, session); 1367b7fa78c7SJay Zhou if (ret < 0) { 1368b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1369b7fa78c7SJay Zhou "padding sym op ctrl req failed"); 1370b7fa78c7SJay Zhou goto error_out; 1371b7fa78c7SJay Zhou } 1372b7fa78c7SJay Zhou ret = virtio_crypto_send_command(control_vq, ctrl_req, 1373b7fa78c7SJay Zhou cipher_key_data, auth_key_data, session); 1374b7fa78c7SJay Zhou if (ret < 0) { 1375b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1376b7fa78c7SJay Zhou "create session failed: %d", ret); 1377b7fa78c7SJay Zhou goto error_out; 1378b7fa78c7SJay Zhou } 1379b7fa78c7SJay Zhou break; 1380b7fa78c7SJay Zhou case VIRTIO_CRYPTO_CMD_CIPHER: 1381b7fa78c7SJay Zhou ctrl_req->u.sym_create_session.op_type 1382b7fa78c7SJay Zhou = VIRTIO_CRYPTO_SYM_OP_CIPHER; 1383b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl_req, xform, 1384186b14d6SFan Zhang false, cipher_key_data, auth_key_data, session); 1385b7fa78c7SJay Zhou if (ret < 0) { 1386b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1387b7fa78c7SJay Zhou "padding sym op ctrl req failed"); 1388b7fa78c7SJay Zhou goto error_out; 1389b7fa78c7SJay Zhou } 1390b7fa78c7SJay Zhou ret = virtio_crypto_send_command(control_vq, ctrl_req, 1391b7fa78c7SJay Zhou cipher_key_data, NULL, session); 1392b7fa78c7SJay Zhou if (ret < 0) { 1393b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1394b7fa78c7SJay Zhou "create session failed: %d", ret); 1395b7fa78c7SJay Zhou goto error_out; 1396b7fa78c7SJay Zhou } 1397b7fa78c7SJay Zhou break; 1398b7fa78c7SJay Zhou default: 1399b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1400b7fa78c7SJay Zhou "Unsupported operation chain order parameter"); 1401b7fa78c7SJay Zhou goto error_out; 1402b7fa78c7SJay Zhou } 1403b7fa78c7SJay Zhou 1404012c5076SPablo de Lara set_sym_session_private_data(sess, dev->driver_id, 1405b7fa78c7SJay Zhou session_private); 1406b7fa78c7SJay Zhou 1407b7fa78c7SJay Zhou return 0; 1408b7fa78c7SJay Zhou 1409b7fa78c7SJay Zhou error_out: 1410b7fa78c7SJay Zhou return -1; 1411b7fa78c7SJay Zhou } 1412b7fa78c7SJay Zhou 14136f0175ffSJay Zhou static void 14146f0175ffSJay Zhou virtio_crypto_dev_info_get(struct rte_cryptodev *dev, 14156f0175ffSJay Zhou struct rte_cryptodev_info *info) 14166f0175ffSJay Zhou { 14176f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 14186f0175ffSJay Zhou 14196f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 14206f0175ffSJay Zhou 14216f0175ffSJay Zhou if (info != NULL) { 14226f0175ffSJay Zhou info->driver_id = cryptodev_virtio_driver_id; 14236f0175ffSJay Zhou info->feature_flags = dev->feature_flags; 14246f0175ffSJay Zhou info->max_nb_queue_pairs = hw->max_dataqueues; 1425e1fc5b76SPablo de Lara /* No limit of number of sessions */ 1426e1fc5b76SPablo de Lara info->sym.max_nb_sessions = 0; 14275889e1ffSJay Zhou info->capabilities = hw->virtio_dev_capabilities; 14286f0175ffSJay Zhou } 14296f0175ffSJay Zhou } 14306f0175ffSJay Zhou 14316f0175ffSJay Zhou static int 14328769079aSJay Zhou crypto_virtio_pci_probe( 14338769079aSJay Zhou struct rte_pci_driver *pci_drv __rte_unused, 143425500d4bSJay Zhou struct rte_pci_device *pci_dev) 14358769079aSJay Zhou { 143625500d4bSJay Zhou struct rte_cryptodev_pmd_init_params init_params = { 143725500d4bSJay Zhou .name = "", 1438933f42eaSXiao Wang .socket_id = pci_dev->device.numa_node, 1439e1fc5b76SPablo de Lara .private_data_size = sizeof(struct virtio_crypto_hw) 144025500d4bSJay Zhou }; 144125500d4bSJay Zhou char name[RTE_CRYPTODEV_NAME_MAX_LEN]; 144225500d4bSJay Zhou 144325500d4bSJay Zhou VIRTIO_CRYPTO_DRV_LOG_DBG("Found Crypto device at %02x:%02x.%x", 144425500d4bSJay Zhou pci_dev->addr.bus, 144525500d4bSJay Zhou pci_dev->addr.devid, 144625500d4bSJay Zhou pci_dev->addr.function); 144725500d4bSJay Zhou 144825500d4bSJay Zhou rte_pci_device_name(&pci_dev->addr, name, sizeof(name)); 144925500d4bSJay Zhou 145025500d4bSJay Zhou return crypto_virtio_create(name, pci_dev, &init_params); 14518769079aSJay Zhou } 14528769079aSJay Zhou 14538769079aSJay Zhou static int 14548769079aSJay Zhou crypto_virtio_pci_remove( 14558769079aSJay Zhou struct rte_pci_device *pci_dev __rte_unused) 14568769079aSJay Zhou { 145725500d4bSJay Zhou struct rte_cryptodev *cryptodev; 145825500d4bSJay Zhou char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN]; 145925500d4bSJay Zhou 146025500d4bSJay Zhou if (pci_dev == NULL) 146125500d4bSJay Zhou return -EINVAL; 146225500d4bSJay Zhou 146325500d4bSJay Zhou rte_pci_device_name(&pci_dev->addr, cryptodev_name, 146425500d4bSJay Zhou sizeof(cryptodev_name)); 146525500d4bSJay Zhou 146625500d4bSJay Zhou cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name); 146725500d4bSJay Zhou if (cryptodev == NULL) 146825500d4bSJay Zhou return -ENODEV; 146925500d4bSJay Zhou 14706f0175ffSJay Zhou return virtio_crypto_dev_uninit(cryptodev); 14718769079aSJay Zhou } 14728769079aSJay Zhou 14738769079aSJay Zhou static struct rte_pci_driver rte_virtio_crypto_driver = { 147425500d4bSJay Zhou .id_table = pci_id_virtio_crypto_map, 147525500d4bSJay Zhou .drv_flags = 0, 14768769079aSJay Zhou .probe = crypto_virtio_pci_probe, 14778769079aSJay Zhou .remove = crypto_virtio_pci_remove 14788769079aSJay Zhou }; 14798769079aSJay Zhou 14808769079aSJay Zhou static struct cryptodev_driver virtio_crypto_drv; 14818769079aSJay Zhou 14828769079aSJay Zhou RTE_PMD_REGISTER_PCI(CRYPTODEV_NAME_VIRTIO_PMD, rte_virtio_crypto_driver); 14838769079aSJay Zhou RTE_PMD_REGISTER_CRYPTO_DRIVER(virtio_crypto_drv, 14848769079aSJay Zhou rte_virtio_crypto_driver.driver, 14858769079aSJay Zhou cryptodev_virtio_driver_id); 14869c99878aSJerin Jacob RTE_LOG_REGISTER(virtio_crypto_logtype_init, pmd.crypto.virtio.init, NOTICE); 14879c99878aSJerin Jacob RTE_LOG_REGISTER(virtio_crypto_logtype_session, pmd.crypto.virtio.session, 14889c99878aSJerin Jacob NOTICE); 14899c99878aSJerin Jacob RTE_LOG_REGISTER(virtio_crypto_logtype_rx, pmd.crypto.virtio.rx, NOTICE); 14909c99878aSJerin Jacob RTE_LOG_REGISTER(virtio_crypto_logtype_tx, pmd.crypto.virtio.tx, NOTICE); 14919c99878aSJerin Jacob RTE_LOG_REGISTER(virtio_crypto_logtype_driver, pmd.crypto.virtio.driver, 14929c99878aSJerin Jacob NOTICE); 1493