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, 43bdce2564SAkhil 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 242*1af8b0b2SDavid Marchand VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_free_cnt=%d", vq->vq_free_cnt); 243*1af8b0b2SDavid Marchand VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_desc_head_idx=%d", vq->vq_desc_head_idx); 244b7fa78c7SJay Zhou 245b7fa78c7SJay Zhou /* get the result */ 246b7fa78c7SJay Zhou if (input->status != VIRTIO_CRYPTO_OK) { 247b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Something wrong on backend! " 248b7fa78c7SJay Zhou "status=%u, session_id=%" PRIu64 "", 249b7fa78c7SJay Zhou input->status, input->session_id); 250b7fa78c7SJay Zhou rte_free(virt_addr_started); 251b7fa78c7SJay Zhou ret = -1; 252b7fa78c7SJay Zhou } else { 253b7fa78c7SJay Zhou session->session_id = input->session_id; 254b7fa78c7SJay Zhou 255b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_INFO("Create session successfully, " 256b7fa78c7SJay Zhou "session_id=%" PRIu64 "", input->session_id); 257b7fa78c7SJay Zhou rte_free(virt_addr_started); 258b7fa78c7SJay Zhou ret = 0; 259b7fa78c7SJay Zhou } 260b7fa78c7SJay Zhou 261b7fa78c7SJay Zhou return ret; 262b7fa78c7SJay Zhou } 263b7fa78c7SJay Zhou 2646f0175ffSJay Zhou void 2656f0175ffSJay Zhou virtio_crypto_queue_release(struct virtqueue *vq) 2666f0175ffSJay Zhou { 2676f0175ffSJay Zhou struct virtio_crypto_hw *hw; 2686f0175ffSJay Zhou 2696f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 2706f0175ffSJay Zhou 2716f0175ffSJay Zhou if (vq) { 2726f0175ffSJay Zhou hw = vq->hw; 2736f0175ffSJay Zhou /* Select and deactivate the queue */ 2746f0175ffSJay Zhou VTPCI_OPS(hw)->del_queue(hw, vq); 2756f0175ffSJay Zhou 2766f0175ffSJay Zhou rte_memzone_free(vq->mz); 2776f0175ffSJay Zhou rte_mempool_free(vq->mpool); 2786f0175ffSJay Zhou rte_free(vq); 2796f0175ffSJay Zhou } 2806f0175ffSJay Zhou } 2816f0175ffSJay Zhou 2826f0175ffSJay Zhou #define MPOOL_MAX_NAME_SZ 32 2836f0175ffSJay Zhou 2846f0175ffSJay Zhou int 2856f0175ffSJay Zhou virtio_crypto_queue_setup(struct rte_cryptodev *dev, 2866f0175ffSJay Zhou int queue_type, 2876f0175ffSJay Zhou uint16_t vtpci_queue_idx, 2886f0175ffSJay Zhou uint16_t nb_desc, 2896f0175ffSJay Zhou int socket_id, 2906f0175ffSJay Zhou struct virtqueue **pvq) 2916f0175ffSJay Zhou { 2926f0175ffSJay Zhou char vq_name[VIRTQUEUE_MAX_NAME_SZ]; 2936f0175ffSJay Zhou char mpool_name[MPOOL_MAX_NAME_SZ]; 2946f0175ffSJay Zhou const struct rte_memzone *mz; 2956f0175ffSJay Zhou unsigned int vq_size, size; 2966f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 2976f0175ffSJay Zhou struct virtqueue *vq = NULL; 2986f0175ffSJay Zhou uint32_t i = 0; 2996f0175ffSJay Zhou uint32_t j; 3006f0175ffSJay Zhou 3016f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 3026f0175ffSJay Zhou 3036f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("setting up queue: %u", vtpci_queue_idx); 3046f0175ffSJay Zhou 3056f0175ffSJay Zhou /* 3066f0175ffSJay Zhou * Read the virtqueue size from the Queue Size field 3076f0175ffSJay Zhou * Always power of 2 and if 0 virtqueue does not exist 3086f0175ffSJay Zhou */ 3096f0175ffSJay Zhou vq_size = VTPCI_OPS(hw)->get_queue_num(hw, vtpci_queue_idx); 3106f0175ffSJay Zhou if (vq_size == 0) { 3116f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("virtqueue does not exist"); 3126f0175ffSJay Zhou return -EINVAL; 3136f0175ffSJay Zhou } 3146f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq_size: %u", vq_size); 3156f0175ffSJay Zhou 3166f0175ffSJay Zhou if (!rte_is_power_of_2(vq_size)) { 3176f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("virtqueue size is not powerof 2"); 3186f0175ffSJay Zhou return -EINVAL; 3196f0175ffSJay Zhou } 3206f0175ffSJay Zhou 3216f0175ffSJay Zhou if (queue_type == VTCRYPTO_DATAQ) { 3226f0175ffSJay Zhou snprintf(vq_name, sizeof(vq_name), "dev%d_dataqueue%d", 3236f0175ffSJay Zhou dev->data->dev_id, vtpci_queue_idx); 3246f0175ffSJay Zhou snprintf(mpool_name, sizeof(mpool_name), 3256f0175ffSJay Zhou "dev%d_dataqueue%d_mpool", 3266f0175ffSJay Zhou dev->data->dev_id, vtpci_queue_idx); 3276f0175ffSJay Zhou } else if (queue_type == VTCRYPTO_CTRLQ) { 3286f0175ffSJay Zhou snprintf(vq_name, sizeof(vq_name), "dev%d_controlqueue", 3296f0175ffSJay Zhou dev->data->dev_id); 3306f0175ffSJay Zhou snprintf(mpool_name, sizeof(mpool_name), 3316f0175ffSJay Zhou "dev%d_controlqueue_mpool", 3326f0175ffSJay Zhou dev->data->dev_id); 3336f0175ffSJay Zhou } 3346f0175ffSJay Zhou size = RTE_ALIGN_CEIL(sizeof(*vq) + 3356f0175ffSJay Zhou vq_size * sizeof(struct vq_desc_extra), 3366f0175ffSJay Zhou RTE_CACHE_LINE_SIZE); 3376f0175ffSJay Zhou vq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE, 3386f0175ffSJay Zhou socket_id); 3396f0175ffSJay Zhou if (vq == NULL) { 3406f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("Can not allocate virtqueue"); 3416f0175ffSJay Zhou return -ENOMEM; 3426f0175ffSJay Zhou } 3436f0175ffSJay Zhou 3446f0175ffSJay Zhou if (queue_type == VTCRYPTO_DATAQ) { 3456f0175ffSJay Zhou /* pre-allocate a mempool and use it in the data plane to 3466f0175ffSJay Zhou * improve performance 3476f0175ffSJay Zhou */ 3486f0175ffSJay Zhou vq->mpool = rte_mempool_lookup(mpool_name); 3496f0175ffSJay Zhou if (vq->mpool == NULL) 3506f0175ffSJay Zhou vq->mpool = rte_mempool_create(mpool_name, 3516f0175ffSJay Zhou vq_size, 3526f0175ffSJay Zhou sizeof(struct virtio_crypto_op_cookie), 3536f0175ffSJay Zhou RTE_CACHE_LINE_SIZE, 0, 3546f0175ffSJay Zhou NULL, NULL, NULL, NULL, socket_id, 3556f0175ffSJay Zhou 0); 3566f0175ffSJay Zhou if (!vq->mpool) { 3576f0175ffSJay Zhou VIRTIO_CRYPTO_DRV_LOG_ERR("Virtio Crypto PMD " 3586f0175ffSJay Zhou "Cannot create mempool"); 3596f0175ffSJay Zhou goto mpool_create_err; 3606f0175ffSJay Zhou } 3616f0175ffSJay Zhou for (i = 0; i < vq_size; i++) { 3626f0175ffSJay Zhou vq->vq_descx[i].cookie = 3636f0175ffSJay Zhou rte_zmalloc("crypto PMD op cookie pointer", 3646f0175ffSJay Zhou sizeof(struct virtio_crypto_op_cookie), 3656f0175ffSJay Zhou RTE_CACHE_LINE_SIZE); 3666f0175ffSJay Zhou if (vq->vq_descx[i].cookie == NULL) { 3676f0175ffSJay Zhou VIRTIO_CRYPTO_DRV_LOG_ERR("Failed to " 3686f0175ffSJay Zhou "alloc mem for cookie"); 3696f0175ffSJay Zhou goto cookie_alloc_err; 3706f0175ffSJay Zhou } 3716f0175ffSJay Zhou } 3726f0175ffSJay Zhou } 3736f0175ffSJay Zhou 3746f0175ffSJay Zhou vq->hw = hw; 3756f0175ffSJay Zhou vq->dev_id = dev->data->dev_id; 3766f0175ffSJay Zhou vq->vq_queue_index = vtpci_queue_idx; 3776f0175ffSJay Zhou vq->vq_nentries = vq_size; 3786f0175ffSJay Zhou 3796f0175ffSJay Zhou /* 3806f0175ffSJay Zhou * Using part of the vring entries is permitted, but the maximum 3816f0175ffSJay Zhou * is vq_size 3826f0175ffSJay Zhou */ 3836f0175ffSJay Zhou if (nb_desc == 0 || nb_desc > vq_size) 3846f0175ffSJay Zhou nb_desc = vq_size; 3856f0175ffSJay Zhou vq->vq_free_cnt = nb_desc; 3866f0175ffSJay Zhou 3876f0175ffSJay Zhou /* 3886f0175ffSJay Zhou * Reserve a memzone for vring elements 3896f0175ffSJay Zhou */ 3906f0175ffSJay Zhou size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN); 3916f0175ffSJay Zhou vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN); 3926f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("%s vring_size: %d, rounded_vring_size: %d", 3936f0175ffSJay Zhou (queue_type == VTCRYPTO_DATAQ) ? "dataq" : "ctrlq", 3946f0175ffSJay Zhou size, vq->vq_ring_size); 3956f0175ffSJay Zhou 3966f0175ffSJay Zhou mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size, 3976f0175ffSJay Zhou socket_id, 0, VIRTIO_PCI_VRING_ALIGN); 3986f0175ffSJay Zhou if (mz == NULL) { 3996f0175ffSJay Zhou if (rte_errno == EEXIST) 4006f0175ffSJay Zhou mz = rte_memzone_lookup(vq_name); 4016f0175ffSJay Zhou if (mz == NULL) { 4026f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("not enough memory"); 4036f0175ffSJay Zhou goto mz_reserve_err; 4046f0175ffSJay Zhou } 4056f0175ffSJay Zhou } 4066f0175ffSJay Zhou 4076f0175ffSJay Zhou /* 4086f0175ffSJay Zhou * Virtio PCI device VIRTIO_PCI_QUEUE_PF register is 32bit, 4096f0175ffSJay Zhou * and only accepts 32 bit page frame number. 4106f0175ffSJay Zhou * Check if the allocated physical memory exceeds 16TB. 4116f0175ffSJay Zhou */ 41272f82c43SThomas Monjalon if ((mz->iova + vq->vq_ring_size - 1) 4136f0175ffSJay Zhou >> (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) { 4146f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("vring address shouldn't be " 4156f0175ffSJay Zhou "above 16TB!"); 4166f0175ffSJay Zhou goto vring_addr_err; 4176f0175ffSJay Zhou } 4186f0175ffSJay Zhou 4196f0175ffSJay Zhou memset(mz->addr, 0, sizeof(mz->len)); 4206f0175ffSJay Zhou vq->mz = mz; 42172f82c43SThomas Monjalon vq->vq_ring_mem = mz->iova; 4226f0175ffSJay Zhou vq->vq_ring_virt_mem = mz->addr; 4236f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_ring_mem(physical): 0x%"PRIx64, 42472f82c43SThomas Monjalon (uint64_t)mz->iova); 4256f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_ring_virt_mem: 0x%"PRIx64, 4266f0175ffSJay Zhou (uint64_t)(uintptr_t)mz->addr); 4276f0175ffSJay Zhou 4286f0175ffSJay Zhou *pvq = vq; 4296f0175ffSJay Zhou 4306f0175ffSJay Zhou return 0; 4316f0175ffSJay Zhou 4326f0175ffSJay Zhou vring_addr_err: 4336f0175ffSJay Zhou rte_memzone_free(mz); 4346f0175ffSJay Zhou mz_reserve_err: 4356f0175ffSJay Zhou cookie_alloc_err: 4366f0175ffSJay Zhou rte_mempool_free(vq->mpool); 4376f0175ffSJay Zhou if (i != 0) { 4386f0175ffSJay Zhou for (j = 0; j < i; j++) 4396f0175ffSJay Zhou rte_free(vq->vq_descx[j].cookie); 4406f0175ffSJay Zhou } 4416f0175ffSJay Zhou mpool_create_err: 4426f0175ffSJay Zhou rte_free(vq); 4436f0175ffSJay Zhou return -ENOMEM; 4446f0175ffSJay Zhou } 4456f0175ffSJay Zhou 4466f0175ffSJay Zhou static int 4476f0175ffSJay Zhou virtio_crypto_ctrlq_setup(struct rte_cryptodev *dev, uint16_t queue_idx) 4486f0175ffSJay Zhou { 4496f0175ffSJay Zhou int ret; 4506f0175ffSJay Zhou struct virtqueue *vq; 4516f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 4526f0175ffSJay Zhou 4536f0175ffSJay Zhou /* if virtio device has started, do not touch the virtqueues */ 4546f0175ffSJay Zhou if (dev->data->dev_started) 4556f0175ffSJay Zhou return 0; 4566f0175ffSJay Zhou 4576f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 4586f0175ffSJay Zhou 4596f0175ffSJay Zhou ret = virtio_crypto_queue_setup(dev, VTCRYPTO_CTRLQ, queue_idx, 4606f0175ffSJay Zhou 0, SOCKET_ID_ANY, &vq); 4616f0175ffSJay Zhou if (ret < 0) { 4626f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("control vq initialization failed"); 4636f0175ffSJay Zhou return ret; 4646f0175ffSJay Zhou } 4656f0175ffSJay Zhou 4666f0175ffSJay Zhou hw->cvq = vq; 4676f0175ffSJay Zhou 4686f0175ffSJay Zhou return 0; 4696f0175ffSJay Zhou } 4706f0175ffSJay Zhou 4716f0175ffSJay Zhou static void 4726f0175ffSJay Zhou virtio_crypto_free_queues(struct rte_cryptodev *dev) 4736f0175ffSJay Zhou { 4746f0175ffSJay Zhou unsigned int i; 4756f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 4766f0175ffSJay Zhou 4776f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 4786f0175ffSJay Zhou 4796f0175ffSJay Zhou /* control queue release */ 4806f0175ffSJay Zhou virtio_crypto_queue_release(hw->cvq); 4816f0175ffSJay Zhou 4826f0175ffSJay Zhou /* data queue release */ 4836f0175ffSJay Zhou for (i = 0; i < hw->max_dataqueues; i++) 4846f0175ffSJay Zhou virtio_crypto_queue_release(dev->data->queue_pairs[i]); 4856f0175ffSJay Zhou } 4866f0175ffSJay Zhou 4876f0175ffSJay Zhou static int 4886f0175ffSJay Zhou virtio_crypto_dev_close(struct rte_cryptodev *dev __rte_unused) 4896f0175ffSJay Zhou { 4906f0175ffSJay Zhou return 0; 4916f0175ffSJay Zhou } 4926f0175ffSJay Zhou 49325500d4bSJay Zhou /* 49425500d4bSJay Zhou * dev_ops for virtio, bare necessities for basic operation 49525500d4bSJay Zhou */ 49625500d4bSJay Zhou static struct rte_cryptodev_ops virtio_crypto_dev_ops = { 49725500d4bSJay Zhou /* Device related operations */ 4986f0175ffSJay Zhou .dev_configure = virtio_crypto_dev_configure, 4996f0175ffSJay Zhou .dev_start = virtio_crypto_dev_start, 5006f0175ffSJay Zhou .dev_stop = virtio_crypto_dev_stop, 5016f0175ffSJay Zhou .dev_close = virtio_crypto_dev_close, 5026f0175ffSJay Zhou .dev_infos_get = virtio_crypto_dev_info_get, 50325500d4bSJay Zhou 504efd3ac6bSJay Zhou .stats_get = virtio_crypto_dev_stats_get, 505efd3ac6bSJay Zhou .stats_reset = virtio_crypto_dev_stats_reset, 50625500d4bSJay Zhou 5076f0175ffSJay Zhou .queue_pair_setup = virtio_crypto_qp_setup, 5086f0175ffSJay Zhou .queue_pair_release = virtio_crypto_qp_release, 50925500d4bSJay Zhou 51025500d4bSJay Zhou /* Crypto related operations */ 511012c5076SPablo de Lara .sym_session_get_size = virtio_crypto_sym_get_session_private_size, 512012c5076SPablo de Lara .sym_session_configure = virtio_crypto_sym_configure_session, 513012c5076SPablo de Lara .sym_session_clear = virtio_crypto_sym_clear_session 51425500d4bSJay Zhou }; 51525500d4bSJay Zhou 516efd3ac6bSJay Zhou static void 517efd3ac6bSJay Zhou virtio_crypto_update_stats(struct rte_cryptodev *dev, 518efd3ac6bSJay Zhou struct rte_cryptodev_stats *stats) 519efd3ac6bSJay Zhou { 520efd3ac6bSJay Zhou unsigned int i; 521efd3ac6bSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 522efd3ac6bSJay Zhou 523efd3ac6bSJay Zhou PMD_INIT_FUNC_TRACE(); 524efd3ac6bSJay Zhou 525efd3ac6bSJay Zhou if (stats == NULL) { 526efd3ac6bSJay Zhou VIRTIO_CRYPTO_DRV_LOG_ERR("invalid pointer"); 527efd3ac6bSJay Zhou return; 528efd3ac6bSJay Zhou } 529efd3ac6bSJay Zhou 530efd3ac6bSJay Zhou for (i = 0; i < hw->max_dataqueues; i++) { 531efd3ac6bSJay Zhou const struct virtqueue *data_queue 532efd3ac6bSJay Zhou = dev->data->queue_pairs[i]; 533efd3ac6bSJay Zhou if (data_queue == NULL) 534efd3ac6bSJay Zhou continue; 535efd3ac6bSJay Zhou 536efd3ac6bSJay Zhou stats->enqueued_count += data_queue->packets_sent_total; 537efd3ac6bSJay Zhou stats->enqueue_err_count += data_queue->packets_sent_failed; 538efd3ac6bSJay Zhou 539efd3ac6bSJay Zhou stats->dequeued_count += data_queue->packets_received_total; 540efd3ac6bSJay Zhou stats->dequeue_err_count 541efd3ac6bSJay Zhou += data_queue->packets_received_failed; 542efd3ac6bSJay Zhou } 543efd3ac6bSJay Zhou } 544efd3ac6bSJay Zhou 545efd3ac6bSJay Zhou static void 546efd3ac6bSJay Zhou virtio_crypto_dev_stats_get(struct rte_cryptodev *dev, 547efd3ac6bSJay Zhou struct rte_cryptodev_stats *stats) 548efd3ac6bSJay Zhou { 549efd3ac6bSJay Zhou PMD_INIT_FUNC_TRACE(); 550efd3ac6bSJay Zhou 551efd3ac6bSJay Zhou virtio_crypto_update_stats(dev, stats); 552efd3ac6bSJay Zhou } 553efd3ac6bSJay Zhou 554efd3ac6bSJay Zhou static void 555efd3ac6bSJay Zhou virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev) 556efd3ac6bSJay Zhou { 557efd3ac6bSJay Zhou unsigned int i; 558efd3ac6bSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 559efd3ac6bSJay Zhou 560efd3ac6bSJay Zhou PMD_INIT_FUNC_TRACE(); 561efd3ac6bSJay Zhou 562efd3ac6bSJay Zhou for (i = 0; i < hw->max_dataqueues; i++) { 563efd3ac6bSJay Zhou struct virtqueue *data_queue = dev->data->queue_pairs[i]; 564efd3ac6bSJay Zhou if (data_queue == NULL) 565efd3ac6bSJay Zhou continue; 566efd3ac6bSJay Zhou 567efd3ac6bSJay Zhou data_queue->packets_sent_total = 0; 568efd3ac6bSJay Zhou data_queue->packets_sent_failed = 0; 569efd3ac6bSJay Zhou 570efd3ac6bSJay Zhou data_queue->packets_received_total = 0; 571efd3ac6bSJay Zhou data_queue->packets_received_failed = 0; 572efd3ac6bSJay Zhou } 573efd3ac6bSJay Zhou } 574efd3ac6bSJay Zhou 57525500d4bSJay Zhou static int 5766f0175ffSJay Zhou virtio_crypto_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id, 5776f0175ffSJay Zhou const struct rte_cryptodev_qp_conf *qp_conf, 578725d2a7fSFan Zhang int socket_id) 5796f0175ffSJay Zhou { 5806f0175ffSJay Zhou int ret; 5816f0175ffSJay Zhou struct virtqueue *vq; 5826f0175ffSJay Zhou 5836f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 5846f0175ffSJay Zhou 5856f0175ffSJay Zhou /* if virtio dev is started, do not touch the virtqueues */ 5866f0175ffSJay Zhou if (dev->data->dev_started) 5876f0175ffSJay Zhou return 0; 5886f0175ffSJay Zhou 5896f0175ffSJay Zhou ret = virtio_crypto_queue_setup(dev, VTCRYPTO_DATAQ, queue_pair_id, 5906f0175ffSJay Zhou qp_conf->nb_descriptors, socket_id, &vq); 5916f0175ffSJay Zhou if (ret < 0) { 5926f0175ffSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR( 593f665790aSDavid Marchand "virtio crypto data queue initialization failed"); 5946f0175ffSJay Zhou return ret; 5956f0175ffSJay Zhou } 5966f0175ffSJay Zhou 5976f0175ffSJay Zhou dev->data->queue_pairs[queue_pair_id] = vq; 5986f0175ffSJay Zhou 5996f0175ffSJay Zhou return 0; 6006f0175ffSJay Zhou } 6016f0175ffSJay Zhou 6026f0175ffSJay Zhou static int 6036f0175ffSJay Zhou virtio_crypto_qp_release(struct rte_cryptodev *dev, uint16_t queue_pair_id) 6046f0175ffSJay Zhou { 6056f0175ffSJay Zhou struct virtqueue *vq 6066f0175ffSJay Zhou = (struct virtqueue *)dev->data->queue_pairs[queue_pair_id]; 6076f0175ffSJay Zhou 6086f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 6096f0175ffSJay Zhou 6106f0175ffSJay Zhou if (vq == NULL) { 6116f0175ffSJay Zhou VIRTIO_CRYPTO_DRV_LOG_DBG("vq already freed"); 6126f0175ffSJay Zhou return 0; 6136f0175ffSJay Zhou } 6146f0175ffSJay Zhou 6156f0175ffSJay Zhou virtio_crypto_queue_release(vq); 6166f0175ffSJay Zhou return 0; 6176f0175ffSJay Zhou } 6186f0175ffSJay Zhou 6196f0175ffSJay Zhou static int 62025500d4bSJay Zhou virtio_negotiate_features(struct virtio_crypto_hw *hw, uint64_t req_features) 62125500d4bSJay Zhou { 62225500d4bSJay Zhou uint64_t host_features; 62325500d4bSJay Zhou 62425500d4bSJay Zhou PMD_INIT_FUNC_TRACE(); 62525500d4bSJay Zhou 62625500d4bSJay Zhou /* Prepare guest_features: feature that driver wants to support */ 62725500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("guest_features before negotiate = %" PRIx64, 62825500d4bSJay Zhou req_features); 62925500d4bSJay Zhou 63025500d4bSJay Zhou /* Read device(host) feature bits */ 63125500d4bSJay Zhou host_features = VTPCI_OPS(hw)->get_features(hw); 63225500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("host_features before negotiate = %" PRIx64, 63325500d4bSJay Zhou host_features); 63425500d4bSJay Zhou 63525500d4bSJay Zhou /* 63625500d4bSJay Zhou * Negotiate features: Subset of device feature bits are written back 63725500d4bSJay Zhou * guest feature bits. 63825500d4bSJay Zhou */ 63925500d4bSJay Zhou hw->guest_features = req_features; 64025500d4bSJay Zhou hw->guest_features = vtpci_cryptodev_negotiate_features(hw, 64125500d4bSJay Zhou host_features); 64225500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("features after negotiate = %" PRIx64, 64325500d4bSJay Zhou hw->guest_features); 64425500d4bSJay Zhou 64525500d4bSJay Zhou if (hw->modern) { 64625500d4bSJay Zhou if (!vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) { 64725500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR( 64825500d4bSJay Zhou "VIRTIO_F_VERSION_1 features is not enabled."); 64925500d4bSJay Zhou return -1; 65025500d4bSJay Zhou } 65125500d4bSJay Zhou vtpci_cryptodev_set_status(hw, 65225500d4bSJay Zhou VIRTIO_CONFIG_STATUS_FEATURES_OK); 65325500d4bSJay Zhou if (!(vtpci_cryptodev_get_status(hw) & 65425500d4bSJay Zhou VIRTIO_CONFIG_STATUS_FEATURES_OK)) { 65525500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_ERR("failed to set FEATURES_OK " 65625500d4bSJay Zhou "status!"); 65725500d4bSJay Zhou return -1; 65825500d4bSJay Zhou } 65925500d4bSJay Zhou } 66025500d4bSJay Zhou 66125500d4bSJay Zhou hw->req_guest_features = req_features; 66225500d4bSJay Zhou 66325500d4bSJay Zhou return 0; 66425500d4bSJay Zhou } 66525500d4bSJay Zhou 66625500d4bSJay Zhou /* reset device and renegotiate features if needed */ 66725500d4bSJay Zhou static int 66825500d4bSJay Zhou virtio_crypto_init_device(struct rte_cryptodev *cryptodev, 66925500d4bSJay Zhou uint64_t req_features) 67025500d4bSJay Zhou { 67125500d4bSJay Zhou struct virtio_crypto_hw *hw = cryptodev->data->dev_private; 67225500d4bSJay Zhou struct virtio_crypto_config local_config; 67325500d4bSJay Zhou struct virtio_crypto_config *config = &local_config; 67425500d4bSJay Zhou 67525500d4bSJay Zhou PMD_INIT_FUNC_TRACE(); 67625500d4bSJay Zhou 67725500d4bSJay Zhou /* Reset the device although not necessary at startup */ 67825500d4bSJay Zhou vtpci_cryptodev_reset(hw); 67925500d4bSJay Zhou 68025500d4bSJay Zhou /* Tell the host we've noticed this device. */ 68125500d4bSJay Zhou vtpci_cryptodev_set_status(hw, VIRTIO_CONFIG_STATUS_ACK); 68225500d4bSJay Zhou 68325500d4bSJay Zhou /* Tell the host we've known how to drive the device. */ 68425500d4bSJay Zhou vtpci_cryptodev_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER); 68525500d4bSJay Zhou if (virtio_negotiate_features(hw, req_features) < 0) 68625500d4bSJay Zhou return -1; 68725500d4bSJay Zhou 68825500d4bSJay Zhou /* Get status of the device */ 68925500d4bSJay Zhou vtpci_read_cryptodev_config(hw, 69025500d4bSJay Zhou offsetof(struct virtio_crypto_config, status), 69125500d4bSJay Zhou &config->status, sizeof(config->status)); 69225500d4bSJay Zhou if (config->status != VIRTIO_CRYPTO_S_HW_READY) { 69325500d4bSJay Zhou VIRTIO_CRYPTO_DRV_LOG_ERR("accelerator hardware is " 69425500d4bSJay Zhou "not ready"); 69525500d4bSJay Zhou return -1; 69625500d4bSJay Zhou } 69725500d4bSJay Zhou 69825500d4bSJay Zhou /* Get number of data queues */ 69925500d4bSJay Zhou vtpci_read_cryptodev_config(hw, 70025500d4bSJay Zhou offsetof(struct virtio_crypto_config, max_dataqueues), 70125500d4bSJay Zhou &config->max_dataqueues, 70225500d4bSJay Zhou sizeof(config->max_dataqueues)); 70325500d4bSJay Zhou hw->max_dataqueues = config->max_dataqueues; 70425500d4bSJay Zhou 70525500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("hw->max_dataqueues=%d", 70625500d4bSJay Zhou hw->max_dataqueues); 70725500d4bSJay Zhou 70825500d4bSJay Zhou return 0; 70925500d4bSJay Zhou } 71025500d4bSJay Zhou 71125500d4bSJay Zhou /* 71225500d4bSJay Zhou * This function is based on probe() function 71325500d4bSJay Zhou * It returns 0 on success. 71425500d4bSJay Zhou */ 71525500d4bSJay Zhou static int 71625500d4bSJay Zhou crypto_virtio_create(const char *name, struct rte_pci_device *pci_dev, 71725500d4bSJay Zhou struct rte_cryptodev_pmd_init_params *init_params) 71825500d4bSJay Zhou { 71925500d4bSJay Zhou struct rte_cryptodev *cryptodev; 72025500d4bSJay Zhou struct virtio_crypto_hw *hw; 72125500d4bSJay Zhou 72225500d4bSJay Zhou PMD_INIT_FUNC_TRACE(); 72325500d4bSJay Zhou 72425500d4bSJay Zhou cryptodev = rte_cryptodev_pmd_create(name, &pci_dev->device, 72525500d4bSJay Zhou init_params); 72625500d4bSJay Zhou if (cryptodev == NULL) 72725500d4bSJay Zhou return -ENODEV; 72825500d4bSJay Zhou 72925500d4bSJay Zhou cryptodev->driver_id = cryptodev_virtio_driver_id; 73025500d4bSJay Zhou cryptodev->dev_ops = &virtio_crypto_dev_ops; 73125500d4bSJay Zhou 73225500d4bSJay Zhou cryptodev->enqueue_burst = virtio_crypto_pkt_tx_burst; 73325500d4bSJay Zhou cryptodev->dequeue_burst = virtio_crypto_pkt_rx_burst; 73425500d4bSJay Zhou 73525500d4bSJay Zhou cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | 736b7aa3b5bSJay Zhou RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING | 737b7aa3b5bSJay Zhou RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT; 73825500d4bSJay Zhou 73925500d4bSJay Zhou hw = cryptodev->data->dev_private; 74025500d4bSJay Zhou hw->dev_id = cryptodev->data->dev_id; 7415889e1ffSJay Zhou hw->virtio_dev_capabilities = virtio_capabilities; 74225500d4bSJay Zhou 74325500d4bSJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("dev %d vendorID=0x%x deviceID=0x%x", 74425500d4bSJay Zhou cryptodev->data->dev_id, pci_dev->id.vendor_id, 74525500d4bSJay Zhou pci_dev->id.device_id); 74625500d4bSJay Zhou 74725500d4bSJay Zhou /* pci device init */ 74825500d4bSJay Zhou if (vtpci_cryptodev_init(pci_dev, hw)) 74925500d4bSJay Zhou return -1; 75025500d4bSJay Zhou 75125500d4bSJay Zhou if (virtio_crypto_init_device(cryptodev, 75225500d4bSJay Zhou VIRTIO_CRYPTO_PMD_GUEST_FEATURES) < 0) 75325500d4bSJay Zhou return -1; 75425500d4bSJay Zhou 755d54c72ecSAkhil Goyal rte_cryptodev_pmd_probing_finish(cryptodev); 756d54c72ecSAkhil Goyal 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; 9532a440d6aSAkhil Goyal session = CRYPTODEV_GET_SYM_SESS_PRIV(sess); 954b7fa78c7SJay Zhou 955b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_INFO("vq->vq_desc_head_idx = %d, " 956b7fa78c7SJay Zhou "vq = %p", vq->vq_desc_head_idx, vq); 957b7fa78c7SJay Zhou 958b7fa78c7SJay Zhou if (vq->vq_free_cnt < needed) { 959b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 960b7fa78c7SJay Zhou "vq->vq_free_cnt = %d is less than %d, " 961b7fa78c7SJay Zhou "not enough", vq->vq_free_cnt, needed); 962b7fa78c7SJay Zhou return; 963b7fa78c7SJay Zhou } 964b7fa78c7SJay Zhou 965b7fa78c7SJay Zhou /* 966b7fa78c7SJay Zhou * malloc memory to store information of ctrl request op, 967b7fa78c7SJay Zhou * returned status and desc vring 968b7fa78c7SJay Zhou */ 969b7fa78c7SJay Zhou malloc_virt_addr = rte_malloc(NULL, len_op_ctrl_req + len_inhdr 970b7fa78c7SJay Zhou + NUM_ENTRY_SYM_CLEAR_SESSION 971b7fa78c7SJay Zhou * sizeof(struct vring_desc), RTE_CACHE_LINE_SIZE); 972b7fa78c7SJay Zhou if (malloc_virt_addr == NULL) { 973b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("not enough heap room"); 974b7fa78c7SJay Zhou return; 975b7fa78c7SJay Zhou } 976b7fa78c7SJay Zhou malloc_phys_addr = rte_malloc_virt2iova(malloc_virt_addr); 977b7fa78c7SJay Zhou 978b7fa78c7SJay Zhou /* assign ctrl request op part */ 979b7fa78c7SJay Zhou ctrl = (struct virtio_crypto_op_ctrl_req *)malloc_virt_addr; 980b7fa78c7SJay Zhou ctrl->header.opcode = VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION; 981b7fa78c7SJay Zhou /* default data virtqueue is 0 */ 982b7fa78c7SJay Zhou ctrl->header.queue_id = 0; 983b7fa78c7SJay Zhou ctrl->u.destroy_session.session_id = session->session_id; 984b7fa78c7SJay Zhou 985b7fa78c7SJay Zhou /* status part */ 986b7fa78c7SJay Zhou status = &(((struct virtio_crypto_inhdr *) 987b7fa78c7SJay Zhou ((uint8_t *)malloc_virt_addr + len_op_ctrl_req))->status); 988b7fa78c7SJay Zhou *status = VIRTIO_CRYPTO_ERR; 989b7fa78c7SJay Zhou 990b7fa78c7SJay Zhou /* indirect desc vring part */ 991b7fa78c7SJay Zhou desc = (struct vring_desc *)((uint8_t *)malloc_virt_addr 992b7fa78c7SJay Zhou + desc_offset); 993b7fa78c7SJay Zhou 994b7fa78c7SJay Zhou /* ctrl request part */ 995b7fa78c7SJay Zhou desc[0].addr = malloc_phys_addr; 996b7fa78c7SJay Zhou desc[0].len = len_op_ctrl_req; 997b7fa78c7SJay Zhou desc[0].flags = VRING_DESC_F_NEXT; 998b7fa78c7SJay Zhou desc[0].next = 1; 999b7fa78c7SJay Zhou 1000b7fa78c7SJay Zhou /* status part */ 1001b7fa78c7SJay Zhou desc[1].addr = malloc_phys_addr + len_op_ctrl_req; 1002b7fa78c7SJay Zhou desc[1].len = len_inhdr; 1003b7fa78c7SJay Zhou desc[1].flags = VRING_DESC_F_WRITE; 1004b7fa78c7SJay Zhou 1005b7fa78c7SJay Zhou /* use only a single desc entry */ 1006b7fa78c7SJay Zhou head = vq->vq_desc_head_idx; 1007b7fa78c7SJay Zhou vq->vq_ring.desc[head].flags = VRING_DESC_F_INDIRECT; 1008b7fa78c7SJay Zhou vq->vq_ring.desc[head].addr = malloc_phys_addr + desc_offset; 1009b7fa78c7SJay Zhou vq->vq_ring.desc[head].len 1010b7fa78c7SJay Zhou = NUM_ENTRY_SYM_CLEAR_SESSION 1011b7fa78c7SJay Zhou * sizeof(struct vring_desc); 1012b7fa78c7SJay Zhou vq->vq_free_cnt -= needed; 1013b7fa78c7SJay Zhou 1014b7fa78c7SJay Zhou vq->vq_desc_head_idx = vq->vq_ring.desc[head].next; 1015b7fa78c7SJay Zhou 1016b7fa78c7SJay Zhou vq_update_avail_ring(vq, head); 1017b7fa78c7SJay Zhou vq_update_avail_idx(vq); 1018b7fa78c7SJay Zhou 1019b7fa78c7SJay Zhou VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_queue_index = %d", 1020b7fa78c7SJay Zhou vq->vq_queue_index); 1021b7fa78c7SJay Zhou 1022b7fa78c7SJay Zhou virtqueue_notify(vq); 1023b7fa78c7SJay Zhou 1024b7fa78c7SJay Zhou rte_rmb(); 1025b7fa78c7SJay Zhou while (vq->vq_used_cons_idx == vq->vq_ring.used->idx) { 1026b7fa78c7SJay Zhou rte_rmb(); 1027b7fa78c7SJay Zhou usleep(100); 1028b7fa78c7SJay Zhou } 1029b7fa78c7SJay Zhou 1030b7fa78c7SJay Zhou while (vq->vq_used_cons_idx != vq->vq_ring.used->idx) { 1031b7fa78c7SJay Zhou uint32_t idx, desc_idx, used_idx; 1032b7fa78c7SJay Zhou struct vring_used_elem *uep; 1033b7fa78c7SJay Zhou 1034b7fa78c7SJay Zhou used_idx = (uint32_t)(vq->vq_used_cons_idx 1035b7fa78c7SJay Zhou & (vq->vq_nentries - 1)); 1036b7fa78c7SJay Zhou uep = &vq->vq_ring.used->ring[used_idx]; 1037b7fa78c7SJay Zhou idx = (uint32_t) uep->id; 1038b7fa78c7SJay Zhou desc_idx = idx; 1039b7fa78c7SJay Zhou while (vq->vq_ring.desc[desc_idx].flags 1040b7fa78c7SJay Zhou & VRING_DESC_F_NEXT) { 1041b7fa78c7SJay Zhou desc_idx = vq->vq_ring.desc[desc_idx].next; 1042b7fa78c7SJay Zhou vq->vq_free_cnt++; 1043b7fa78c7SJay Zhou } 1044b7fa78c7SJay Zhou 1045b7fa78c7SJay Zhou vq->vq_ring.desc[desc_idx].next = vq->vq_desc_head_idx; 1046b7fa78c7SJay Zhou vq->vq_desc_head_idx = idx; 1047b7fa78c7SJay Zhou vq->vq_used_cons_idx++; 1048b7fa78c7SJay Zhou vq->vq_free_cnt++; 1049b7fa78c7SJay Zhou } 1050b7fa78c7SJay Zhou 1051b7fa78c7SJay Zhou if (*status != VIRTIO_CRYPTO_OK) { 1052b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Close session failed " 1053b7fa78c7SJay Zhou "status=%"PRIu32", session_id=%"PRIu64"", 1054b7fa78c7SJay Zhou *status, session->session_id); 1055b7fa78c7SJay Zhou rte_free(malloc_virt_addr); 1056b7fa78c7SJay Zhou return; 1057b7fa78c7SJay Zhou } 1058b7fa78c7SJay Zhou 1059*1af8b0b2SDavid Marchand VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_free_cnt=%d", vq->vq_free_cnt); 1060*1af8b0b2SDavid Marchand VIRTIO_CRYPTO_INIT_LOG_DBG("vq->vq_desc_head_idx=%d", vq->vq_desc_head_idx); 1061b7fa78c7SJay Zhou 1062b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_INFO("Close session %"PRIu64" successfully ", 1063b7fa78c7SJay Zhou session->session_id); 1064b7fa78c7SJay Zhou 1065b7fa78c7SJay Zhou rte_free(malloc_virt_addr); 1066b7fa78c7SJay Zhou } 1067b7fa78c7SJay Zhou 1068b7fa78c7SJay Zhou static struct rte_crypto_cipher_xform * 1069b7fa78c7SJay Zhou virtio_crypto_get_cipher_xform(struct rte_crypto_sym_xform *xform) 1070b7fa78c7SJay Zhou { 1071b7fa78c7SJay Zhou do { 1072b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) 1073b7fa78c7SJay Zhou return &xform->cipher; 1074b7fa78c7SJay Zhou 1075b7fa78c7SJay Zhou xform = xform->next; 1076b7fa78c7SJay Zhou } while (xform); 1077b7fa78c7SJay Zhou 1078b7fa78c7SJay Zhou return NULL; 1079b7fa78c7SJay Zhou } 1080b7fa78c7SJay Zhou 1081b7fa78c7SJay Zhou static struct rte_crypto_auth_xform * 1082b7fa78c7SJay Zhou virtio_crypto_get_auth_xform(struct rte_crypto_sym_xform *xform) 1083b7fa78c7SJay Zhou { 1084b7fa78c7SJay Zhou do { 1085b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) 1086b7fa78c7SJay Zhou return &xform->auth; 1087b7fa78c7SJay Zhou 1088b7fa78c7SJay Zhou xform = xform->next; 1089b7fa78c7SJay Zhou } while (xform); 1090b7fa78c7SJay Zhou 1091b7fa78c7SJay Zhou return NULL; 1092b7fa78c7SJay Zhou } 1093b7fa78c7SJay Zhou 1094b7fa78c7SJay Zhou /** Get xform chain order */ 1095b7fa78c7SJay Zhou static int 1096b7fa78c7SJay Zhou virtio_crypto_get_chain_order(struct rte_crypto_sym_xform *xform) 1097b7fa78c7SJay Zhou { 1098b7fa78c7SJay Zhou if (xform == NULL) 1099b7fa78c7SJay Zhou return -1; 1100b7fa78c7SJay Zhou 1101b7fa78c7SJay Zhou /* Cipher Only */ 1102b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 1103b7fa78c7SJay Zhou xform->next == NULL) 1104b7fa78c7SJay Zhou return VIRTIO_CRYPTO_CMD_CIPHER; 1105b7fa78c7SJay Zhou 1106b7fa78c7SJay Zhou /* Authentication Only */ 1107b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 1108b7fa78c7SJay Zhou xform->next == NULL) 1109b7fa78c7SJay Zhou return VIRTIO_CRYPTO_CMD_AUTH; 1110b7fa78c7SJay Zhou 1111b7fa78c7SJay Zhou /* Authenticate then Cipher */ 1112b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 1113b7fa78c7SJay Zhou xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) 1114b7fa78c7SJay Zhou return VIRTIO_CRYPTO_CMD_HASH_CIPHER; 1115b7fa78c7SJay Zhou 1116b7fa78c7SJay Zhou /* Cipher then Authenticate */ 1117b7fa78c7SJay Zhou if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 1118b7fa78c7SJay Zhou xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) 1119b7fa78c7SJay Zhou return VIRTIO_CRYPTO_CMD_CIPHER_HASH; 1120b7fa78c7SJay Zhou 1121b7fa78c7SJay Zhou return -1; 1122b7fa78c7SJay Zhou } 1123b7fa78c7SJay Zhou 1124b7fa78c7SJay Zhou static int 1125b7fa78c7SJay Zhou virtio_crypto_sym_pad_cipher_param( 1126b7fa78c7SJay Zhou struct virtio_crypto_cipher_session_para *para, 1127b7fa78c7SJay Zhou struct rte_crypto_cipher_xform *cipher_xform) 1128b7fa78c7SJay Zhou { 1129b7fa78c7SJay Zhou switch (cipher_xform->algo) { 11305889e1ffSJay Zhou case RTE_CRYPTO_CIPHER_AES_CBC: 11315889e1ffSJay Zhou para->algo = VIRTIO_CRYPTO_CIPHER_AES_CBC; 11325889e1ffSJay Zhou break; 1133b7fa78c7SJay Zhou default: 1134b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Crypto: Unsupported " 1135b7fa78c7SJay Zhou "Cipher alg %u", cipher_xform->algo); 1136b7fa78c7SJay Zhou return -1; 1137b7fa78c7SJay Zhou } 1138b7fa78c7SJay Zhou 1139b7fa78c7SJay Zhou para->keylen = cipher_xform->key.length; 1140b7fa78c7SJay Zhou switch (cipher_xform->op) { 1141b7fa78c7SJay Zhou case RTE_CRYPTO_CIPHER_OP_ENCRYPT: 1142b7fa78c7SJay Zhou para->op = VIRTIO_CRYPTO_OP_ENCRYPT; 1143b7fa78c7SJay Zhou break; 1144b7fa78c7SJay Zhou case RTE_CRYPTO_CIPHER_OP_DECRYPT: 1145b7fa78c7SJay Zhou para->op = VIRTIO_CRYPTO_OP_DECRYPT; 1146b7fa78c7SJay Zhou break; 1147b7fa78c7SJay Zhou default: 1148b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Unsupported cipher operation " 1149b7fa78c7SJay Zhou "parameter"); 1150b7fa78c7SJay Zhou return -1; 1151b7fa78c7SJay Zhou } 1152b7fa78c7SJay Zhou 1153b7fa78c7SJay Zhou return 0; 1154b7fa78c7SJay Zhou } 1155b7fa78c7SJay Zhou 1156b7fa78c7SJay Zhou static int 1157b7fa78c7SJay Zhou virtio_crypto_sym_pad_auth_param( 1158b7fa78c7SJay Zhou struct virtio_crypto_op_ctrl_req *ctrl, 1159b7fa78c7SJay Zhou struct rte_crypto_auth_xform *auth_xform) 1160b7fa78c7SJay Zhou { 1161b7fa78c7SJay Zhou uint32_t *algo; 1162b7fa78c7SJay Zhou struct virtio_crypto_alg_chain_session_para *para = 1163b7fa78c7SJay Zhou &(ctrl->u.sym_create_session.u.chain.para); 1164b7fa78c7SJay Zhou 1165b7fa78c7SJay Zhou switch (ctrl->u.sym_create_session.u.chain.para.hash_mode) { 1166b7fa78c7SJay Zhou case VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN: 1167b7fa78c7SJay Zhou algo = &(para->u.hash_param.algo); 1168b7fa78c7SJay Zhou break; 1169b7fa78c7SJay Zhou case VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH: 1170b7fa78c7SJay Zhou algo = &(para->u.mac_param.algo); 1171b7fa78c7SJay Zhou break; 1172b7fa78c7SJay Zhou default: 1173b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Unsupported hash mode %u " 1174b7fa78c7SJay Zhou "specified", 1175b7fa78c7SJay Zhou ctrl->u.sym_create_session.u.chain.para.hash_mode); 1176b7fa78c7SJay Zhou return -1; 1177b7fa78c7SJay Zhou } 1178b7fa78c7SJay Zhou 1179b7fa78c7SJay Zhou switch (auth_xform->algo) { 11808144eadaSJay Zhou case RTE_CRYPTO_AUTH_SHA1_HMAC: 11818144eadaSJay Zhou *algo = VIRTIO_CRYPTO_MAC_HMAC_SHA1; 11828144eadaSJay Zhou break; 1183b7fa78c7SJay Zhou default: 1184b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1185b7fa78c7SJay Zhou "Crypto: Undefined Hash algo %u specified", 1186b7fa78c7SJay Zhou auth_xform->algo); 1187b7fa78c7SJay Zhou return -1; 1188b7fa78c7SJay Zhou } 1189b7fa78c7SJay Zhou 1190b7fa78c7SJay Zhou return 0; 1191b7fa78c7SJay Zhou } 1192b7fa78c7SJay Zhou 1193b7fa78c7SJay Zhou static int 1194b7fa78c7SJay Zhou virtio_crypto_sym_pad_op_ctrl_req( 1195b7fa78c7SJay Zhou struct virtio_crypto_op_ctrl_req *ctrl, 1196b7fa78c7SJay Zhou struct rte_crypto_sym_xform *xform, bool is_chainned, 1197186b14d6SFan Zhang uint8_t *cipher_key_data, uint8_t *auth_key_data, 1198b7fa78c7SJay Zhou struct virtio_crypto_session *session) 1199b7fa78c7SJay Zhou { 1200b7fa78c7SJay Zhou int ret; 1201b7fa78c7SJay Zhou struct rte_crypto_auth_xform *auth_xform = NULL; 1202b7fa78c7SJay Zhou struct rte_crypto_cipher_xform *cipher_xform = NULL; 1203b7fa78c7SJay Zhou 1204b7fa78c7SJay Zhou /* Get cipher xform from crypto xform chain */ 1205b7fa78c7SJay Zhou cipher_xform = virtio_crypto_get_cipher_xform(xform); 1206b7fa78c7SJay Zhou if (cipher_xform) { 1207186b14d6SFan Zhang if (cipher_xform->key.length > VIRTIO_CRYPTO_MAX_KEY_SIZE) { 1208186b14d6SFan Zhang VIRTIO_CRYPTO_SESSION_LOG_ERR( 1209186b14d6SFan Zhang "cipher key size cannot be longer than %u", 1210186b14d6SFan Zhang VIRTIO_CRYPTO_MAX_KEY_SIZE); 1211186b14d6SFan Zhang return -1; 1212186b14d6SFan Zhang } 1213b063e843SFan Zhang if (cipher_xform->iv.length > VIRTIO_CRYPTO_MAX_IV_SIZE) { 1214b063e843SFan Zhang VIRTIO_CRYPTO_SESSION_LOG_ERR( 1215b063e843SFan Zhang "cipher IV size cannot be longer than %u", 1216b063e843SFan Zhang VIRTIO_CRYPTO_MAX_IV_SIZE); 1217b063e843SFan Zhang return -1; 1218b063e843SFan Zhang } 1219b7fa78c7SJay Zhou if (is_chainned) 1220b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_cipher_param( 1221b7fa78c7SJay Zhou &ctrl->u.sym_create_session.u.chain.para 1222b7fa78c7SJay Zhou .cipher_param, cipher_xform); 1223b7fa78c7SJay Zhou else 1224b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_cipher_param( 1225b7fa78c7SJay Zhou &ctrl->u.sym_create_session.u.cipher.para, 1226b7fa78c7SJay Zhou cipher_xform); 1227b7fa78c7SJay Zhou 1228b7fa78c7SJay Zhou if (ret < 0) { 1229b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1230b7fa78c7SJay Zhou "pad cipher parameter failed"); 1231b7fa78c7SJay Zhou return -1; 1232b7fa78c7SJay Zhou } 1233b7fa78c7SJay Zhou 1234186b14d6SFan Zhang memcpy(cipher_key_data, cipher_xform->key.data, 1235186b14d6SFan Zhang cipher_xform->key.length); 1236b7fa78c7SJay Zhou 1237b7fa78c7SJay Zhou session->iv.offset = cipher_xform->iv.offset; 1238b7fa78c7SJay Zhou session->iv.length = cipher_xform->iv.length; 1239b7fa78c7SJay Zhou } 1240b7fa78c7SJay Zhou 1241b7fa78c7SJay Zhou /* Get auth xform from crypto xform chain */ 1242b7fa78c7SJay Zhou auth_xform = virtio_crypto_get_auth_xform(xform); 1243b7fa78c7SJay Zhou if (auth_xform) { 1244b7fa78c7SJay Zhou /* FIXME: support VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED */ 1245b7fa78c7SJay Zhou struct virtio_crypto_alg_chain_session_para *para = 1246b7fa78c7SJay Zhou &(ctrl->u.sym_create_session.u.chain.para); 1247b7fa78c7SJay Zhou if (auth_xform->key.length) { 1248186b14d6SFan Zhang if (auth_xform->key.length > 1249186b14d6SFan Zhang VIRTIO_CRYPTO_MAX_KEY_SIZE) { 1250186b14d6SFan Zhang VIRTIO_CRYPTO_SESSION_LOG_ERR( 1251186b14d6SFan Zhang "auth key size cannot be longer than %u", 1252186b14d6SFan Zhang VIRTIO_CRYPTO_MAX_KEY_SIZE); 1253186b14d6SFan Zhang return -1; 1254186b14d6SFan Zhang } 1255b7fa78c7SJay Zhou para->hash_mode = VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH; 1256b7fa78c7SJay Zhou para->u.mac_param.auth_key_len = 1257b7fa78c7SJay Zhou (uint32_t)auth_xform->key.length; 1258b7fa78c7SJay Zhou para->u.mac_param.hash_result_len = 1259b7fa78c7SJay Zhou auth_xform->digest_length; 1260186b14d6SFan Zhang memcpy(auth_key_data, auth_xform->key.data, 1261186b14d6SFan Zhang auth_xform->key.length); 1262b7fa78c7SJay Zhou } else { 1263b7fa78c7SJay Zhou para->hash_mode = VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN; 1264b7fa78c7SJay Zhou para->u.hash_param.hash_result_len = 1265b7fa78c7SJay Zhou auth_xform->digest_length; 1266b7fa78c7SJay Zhou } 1267b7fa78c7SJay Zhou 1268b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_auth_param(ctrl, auth_xform); 1269b7fa78c7SJay Zhou if (ret < 0) { 1270b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("pad auth parameter " 1271b7fa78c7SJay Zhou "failed"); 1272b7fa78c7SJay Zhou return -1; 1273b7fa78c7SJay Zhou } 1274b7fa78c7SJay Zhou } 1275b7fa78c7SJay Zhou 1276b7fa78c7SJay Zhou return 0; 1277b7fa78c7SJay Zhou } 1278b7fa78c7SJay Zhou 1279b7fa78c7SJay Zhou static int 1280b7fa78c7SJay Zhou virtio_crypto_check_sym_configure_session_paras( 1281b7fa78c7SJay Zhou struct rte_cryptodev *dev, 1282b7fa78c7SJay Zhou struct rte_crypto_sym_xform *xform, 1283bdce2564SAkhil Goyal struct rte_cryptodev_sym_session *sym_sess) 1284b7fa78c7SJay Zhou { 1285bdce2564SAkhil Goyal if (unlikely(xform == NULL) || unlikely(sym_sess == NULL)) { 1286b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("NULL pointer"); 1287b7fa78c7SJay Zhou return -1; 1288b7fa78c7SJay Zhou } 1289b7fa78c7SJay Zhou 1290b7fa78c7SJay Zhou if (virtio_crypto_check_sym_session_paras(dev) < 0) 1291b7fa78c7SJay Zhou return -1; 1292b7fa78c7SJay Zhou 1293b7fa78c7SJay Zhou return 0; 1294b7fa78c7SJay Zhou } 1295b7fa78c7SJay Zhou 1296b7fa78c7SJay Zhou static int 1297b7fa78c7SJay Zhou virtio_crypto_sym_configure_session( 1298b7fa78c7SJay Zhou struct rte_cryptodev *dev, 1299b7fa78c7SJay Zhou struct rte_crypto_sym_xform *xform, 1300bdce2564SAkhil Goyal struct rte_cryptodev_sym_session *sess) 1301b7fa78c7SJay Zhou { 1302b7fa78c7SJay Zhou int ret; 1303b7fa78c7SJay Zhou struct virtio_crypto_session *session; 1304b7fa78c7SJay Zhou struct virtio_crypto_op_ctrl_req *ctrl_req; 1305b7fa78c7SJay Zhou enum virtio_crypto_cmd_id cmd_id; 1306186b14d6SFan Zhang uint8_t cipher_key_data[VIRTIO_CRYPTO_MAX_KEY_SIZE] = {0}; 1307186b14d6SFan Zhang uint8_t auth_key_data[VIRTIO_CRYPTO_MAX_KEY_SIZE] = {0}; 1308b7fa78c7SJay Zhou struct virtio_crypto_hw *hw; 1309b7fa78c7SJay Zhou struct virtqueue *control_vq; 1310b7fa78c7SJay Zhou 1311b7fa78c7SJay Zhou PMD_INIT_FUNC_TRACE(); 1312b7fa78c7SJay Zhou 1313b7fa78c7SJay Zhou ret = virtio_crypto_check_sym_configure_session_paras(dev, xform, 1314bdce2564SAkhil Goyal sess); 1315b7fa78c7SJay Zhou if (ret < 0) { 1316b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR("Invalid parameters"); 1317b7fa78c7SJay Zhou return ret; 1318b7fa78c7SJay Zhou } 13192a440d6aSAkhil Goyal session = CRYPTODEV_GET_SYM_SESS_PRIV(sess); 1320b7fa78c7SJay Zhou memset(session, 0, sizeof(struct virtio_crypto_session)); 1321b7fa78c7SJay Zhou ctrl_req = &session->ctrl; 1322b7fa78c7SJay Zhou ctrl_req->header.opcode = VIRTIO_CRYPTO_CIPHER_CREATE_SESSION; 1323b7fa78c7SJay Zhou /* FIXME: support multiqueue */ 1324b7fa78c7SJay Zhou ctrl_req->header.queue_id = 0; 1325b7fa78c7SJay Zhou 1326b7fa78c7SJay Zhou hw = dev->data->dev_private; 1327b7fa78c7SJay Zhou control_vq = hw->cvq; 1328b7fa78c7SJay Zhou 1329b7fa78c7SJay Zhou cmd_id = virtio_crypto_get_chain_order(xform); 1330b7fa78c7SJay Zhou if (cmd_id == VIRTIO_CRYPTO_CMD_CIPHER_HASH) 1331b7fa78c7SJay Zhou ctrl_req->u.sym_create_session.u.chain.para.alg_chain_order 1332b7fa78c7SJay Zhou = VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH; 1333b7fa78c7SJay Zhou if (cmd_id == VIRTIO_CRYPTO_CMD_HASH_CIPHER) 1334b7fa78c7SJay Zhou ctrl_req->u.sym_create_session.u.chain.para.alg_chain_order 1335b7fa78c7SJay Zhou = VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER; 1336b7fa78c7SJay Zhou 1337b7fa78c7SJay Zhou switch (cmd_id) { 1338b7fa78c7SJay Zhou case VIRTIO_CRYPTO_CMD_CIPHER_HASH: 1339b7fa78c7SJay Zhou case VIRTIO_CRYPTO_CMD_HASH_CIPHER: 1340b7fa78c7SJay Zhou ctrl_req->u.sym_create_session.op_type 1341b7fa78c7SJay Zhou = VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING; 1342b7fa78c7SJay Zhou 1343b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl_req, 1344186b14d6SFan Zhang xform, true, cipher_key_data, auth_key_data, session); 1345b7fa78c7SJay Zhou if (ret < 0) { 1346b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1347b7fa78c7SJay Zhou "padding sym op ctrl req failed"); 1348b7fa78c7SJay Zhou goto error_out; 1349b7fa78c7SJay Zhou } 1350b7fa78c7SJay Zhou ret = virtio_crypto_send_command(control_vq, ctrl_req, 1351b7fa78c7SJay Zhou cipher_key_data, auth_key_data, session); 1352b7fa78c7SJay Zhou if (ret < 0) { 1353b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1354b7fa78c7SJay Zhou "create session failed: %d", ret); 1355b7fa78c7SJay Zhou goto error_out; 1356b7fa78c7SJay Zhou } 1357b7fa78c7SJay Zhou break; 1358b7fa78c7SJay Zhou case VIRTIO_CRYPTO_CMD_CIPHER: 1359b7fa78c7SJay Zhou ctrl_req->u.sym_create_session.op_type 1360b7fa78c7SJay Zhou = VIRTIO_CRYPTO_SYM_OP_CIPHER; 1361b7fa78c7SJay Zhou ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl_req, xform, 1362186b14d6SFan Zhang false, cipher_key_data, auth_key_data, session); 1363b7fa78c7SJay Zhou if (ret < 0) { 1364b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1365b7fa78c7SJay Zhou "padding sym op ctrl req failed"); 1366b7fa78c7SJay Zhou goto error_out; 1367b7fa78c7SJay Zhou } 1368b7fa78c7SJay Zhou ret = virtio_crypto_send_command(control_vq, ctrl_req, 1369b7fa78c7SJay Zhou cipher_key_data, NULL, session); 1370b7fa78c7SJay Zhou if (ret < 0) { 1371b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1372b7fa78c7SJay Zhou "create session failed: %d", ret); 1373b7fa78c7SJay Zhou goto error_out; 1374b7fa78c7SJay Zhou } 1375b7fa78c7SJay Zhou break; 1376b7fa78c7SJay Zhou default: 1377b7fa78c7SJay Zhou VIRTIO_CRYPTO_SESSION_LOG_ERR( 1378b7fa78c7SJay Zhou "Unsupported operation chain order parameter"); 1379b7fa78c7SJay Zhou goto error_out; 1380b7fa78c7SJay Zhou } 1381b7fa78c7SJay Zhou return 0; 1382b7fa78c7SJay Zhou 1383b7fa78c7SJay Zhou error_out: 1384b7fa78c7SJay Zhou return -1; 1385b7fa78c7SJay Zhou } 1386b7fa78c7SJay Zhou 13876f0175ffSJay Zhou static void 13886f0175ffSJay Zhou virtio_crypto_dev_info_get(struct rte_cryptodev *dev, 13896f0175ffSJay Zhou struct rte_cryptodev_info *info) 13906f0175ffSJay Zhou { 13916f0175ffSJay Zhou struct virtio_crypto_hw *hw = dev->data->dev_private; 13926f0175ffSJay Zhou 13936f0175ffSJay Zhou PMD_INIT_FUNC_TRACE(); 13946f0175ffSJay Zhou 13956f0175ffSJay Zhou if (info != NULL) { 13966f0175ffSJay Zhou info->driver_id = cryptodev_virtio_driver_id; 13976f0175ffSJay Zhou info->feature_flags = dev->feature_flags; 13986f0175ffSJay Zhou info->max_nb_queue_pairs = hw->max_dataqueues; 1399e1fc5b76SPablo de Lara /* No limit of number of sessions */ 1400e1fc5b76SPablo de Lara info->sym.max_nb_sessions = 0; 14015889e1ffSJay Zhou info->capabilities = hw->virtio_dev_capabilities; 14026f0175ffSJay Zhou } 14036f0175ffSJay Zhou } 14046f0175ffSJay Zhou 14056f0175ffSJay Zhou static int 14068769079aSJay Zhou crypto_virtio_pci_probe( 14078769079aSJay Zhou struct rte_pci_driver *pci_drv __rte_unused, 140825500d4bSJay Zhou struct rte_pci_device *pci_dev) 14098769079aSJay Zhou { 141025500d4bSJay Zhou struct rte_cryptodev_pmd_init_params init_params = { 141125500d4bSJay Zhou .name = "", 1412933f42eaSXiao Wang .socket_id = pci_dev->device.numa_node, 1413e1fc5b76SPablo de Lara .private_data_size = sizeof(struct virtio_crypto_hw) 141425500d4bSJay Zhou }; 141525500d4bSJay Zhou char name[RTE_CRYPTODEV_NAME_MAX_LEN]; 141625500d4bSJay Zhou 141725500d4bSJay Zhou VIRTIO_CRYPTO_DRV_LOG_DBG("Found Crypto device at %02x:%02x.%x", 141825500d4bSJay Zhou pci_dev->addr.bus, 141925500d4bSJay Zhou pci_dev->addr.devid, 142025500d4bSJay Zhou pci_dev->addr.function); 142125500d4bSJay Zhou 142225500d4bSJay Zhou rte_pci_device_name(&pci_dev->addr, name, sizeof(name)); 142325500d4bSJay Zhou 142425500d4bSJay Zhou return crypto_virtio_create(name, pci_dev, &init_params); 14258769079aSJay Zhou } 14268769079aSJay Zhou 14278769079aSJay Zhou static int 14288769079aSJay Zhou crypto_virtio_pci_remove( 14298769079aSJay Zhou struct rte_pci_device *pci_dev __rte_unused) 14308769079aSJay Zhou { 143125500d4bSJay Zhou struct rte_cryptodev *cryptodev; 143225500d4bSJay Zhou char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN]; 143325500d4bSJay Zhou 143425500d4bSJay Zhou if (pci_dev == NULL) 143525500d4bSJay Zhou return -EINVAL; 143625500d4bSJay Zhou 143725500d4bSJay Zhou rte_pci_device_name(&pci_dev->addr, cryptodev_name, 143825500d4bSJay Zhou sizeof(cryptodev_name)); 143925500d4bSJay Zhou 144025500d4bSJay Zhou cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name); 144125500d4bSJay Zhou if (cryptodev == NULL) 144225500d4bSJay Zhou return -ENODEV; 144325500d4bSJay Zhou 14446f0175ffSJay Zhou return virtio_crypto_dev_uninit(cryptodev); 14458769079aSJay Zhou } 14468769079aSJay Zhou 14478769079aSJay Zhou static struct rte_pci_driver rte_virtio_crypto_driver = { 144825500d4bSJay Zhou .id_table = pci_id_virtio_crypto_map, 144925500d4bSJay Zhou .drv_flags = 0, 14508769079aSJay Zhou .probe = crypto_virtio_pci_probe, 14518769079aSJay Zhou .remove = crypto_virtio_pci_remove 14528769079aSJay Zhou }; 14538769079aSJay Zhou 14548769079aSJay Zhou static struct cryptodev_driver virtio_crypto_drv; 14558769079aSJay Zhou 14568769079aSJay Zhou RTE_PMD_REGISTER_PCI(CRYPTODEV_NAME_VIRTIO_PMD, rte_virtio_crypto_driver); 14578769079aSJay Zhou RTE_PMD_REGISTER_CRYPTO_DRIVER(virtio_crypto_drv, 14588769079aSJay Zhou rte_virtio_crypto_driver.driver, 14598769079aSJay Zhou cryptodev_virtio_driver_id); 1460eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(virtio_crypto_logtype_init, init, NOTICE); 1461eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(virtio_crypto_logtype_session, session, NOTICE); 1462eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(virtio_crypto_logtype_rx, rx, NOTICE); 1463eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(virtio_crypto_logtype_tx, tx, NOTICE); 1464eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(virtio_crypto_logtype_driver, driver, NOTICE); 1465