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