18c515d96SZhangfei Gao /* SPDX-License-Identifier: BSD-3-Clause 28c515d96SZhangfei Gao * Copyright 2022-2023 Huawei Technologies Co.,Ltd. All rights reserved. 38c515d96SZhangfei Gao * Copyright 2022-2023 Linaro ltd. 48c515d96SZhangfei Gao */ 58c515d96SZhangfei Gao 68c515d96SZhangfei Gao #include <stdlib.h> 78c515d96SZhangfei Gao 88c515d96SZhangfei Gao #include <bus_vdev_driver.h> 98c515d96SZhangfei Gao #include <cryptodev_pmd.h> 108c515d96SZhangfei Gao #include <rte_bus_vdev.h> 118c515d96SZhangfei Gao 128c515d96SZhangfei Gao #include <uadk/wd_cipher.h> 138c515d96SZhangfei Gao #include <uadk/wd_digest.h> 148c515d96SZhangfei Gao #include <uadk/wd_sched.h> 158c515d96SZhangfei Gao 168c515d96SZhangfei Gao #include "uadk_crypto_pmd_private.h" 178c515d96SZhangfei Gao 188c515d96SZhangfei Gao static uint8_t uadk_cryptodev_driver_id; 198c515d96SZhangfei Gao 20*53ae1393SZhangfei Gao static const struct rte_cryptodev_capabilities uadk_crypto_v2_capabilities[] = { 21*53ae1393SZhangfei Gao /* End of capabilities */ 22*53ae1393SZhangfei Gao RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() 23*53ae1393SZhangfei Gao }; 24*53ae1393SZhangfei Gao 25*53ae1393SZhangfei Gao /* Configure device */ 26*53ae1393SZhangfei Gao static int 27*53ae1393SZhangfei Gao uadk_crypto_pmd_config(struct rte_cryptodev *dev __rte_unused, 28*53ae1393SZhangfei Gao struct rte_cryptodev_config *config __rte_unused) 29*53ae1393SZhangfei Gao { 30*53ae1393SZhangfei Gao return 0; 31*53ae1393SZhangfei Gao } 32*53ae1393SZhangfei Gao 33*53ae1393SZhangfei Gao /* Start device */ 34*53ae1393SZhangfei Gao static int 35*53ae1393SZhangfei Gao uadk_crypto_pmd_start(struct rte_cryptodev *dev __rte_unused) 36*53ae1393SZhangfei Gao { 37*53ae1393SZhangfei Gao return 0; 38*53ae1393SZhangfei Gao } 39*53ae1393SZhangfei Gao 40*53ae1393SZhangfei Gao /* Stop device */ 41*53ae1393SZhangfei Gao static void 42*53ae1393SZhangfei Gao uadk_crypto_pmd_stop(struct rte_cryptodev *dev __rte_unused) 43*53ae1393SZhangfei Gao { 44*53ae1393SZhangfei Gao } 45*53ae1393SZhangfei Gao 46*53ae1393SZhangfei Gao /* Close device */ 47*53ae1393SZhangfei Gao static int 48*53ae1393SZhangfei Gao uadk_crypto_pmd_close(struct rte_cryptodev *dev __rte_unused) 49*53ae1393SZhangfei Gao { 50*53ae1393SZhangfei Gao return 0; 51*53ae1393SZhangfei Gao } 52*53ae1393SZhangfei Gao 53*53ae1393SZhangfei Gao /* Get device statistics */ 54*53ae1393SZhangfei Gao static void 55*53ae1393SZhangfei Gao uadk_crypto_pmd_stats_get(struct rte_cryptodev *dev, 56*53ae1393SZhangfei Gao struct rte_cryptodev_stats *stats) 57*53ae1393SZhangfei Gao { 58*53ae1393SZhangfei Gao int qp_id; 59*53ae1393SZhangfei Gao 60*53ae1393SZhangfei Gao for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 61*53ae1393SZhangfei Gao struct uadk_qp *qp = dev->data->queue_pairs[qp_id]; 62*53ae1393SZhangfei Gao 63*53ae1393SZhangfei Gao stats->enqueued_count += qp->qp_stats.enqueued_count; 64*53ae1393SZhangfei Gao stats->dequeued_count += qp->qp_stats.dequeued_count; 65*53ae1393SZhangfei Gao stats->enqueue_err_count += qp->qp_stats.enqueue_err_count; 66*53ae1393SZhangfei Gao stats->dequeue_err_count += qp->qp_stats.dequeue_err_count; 67*53ae1393SZhangfei Gao } 68*53ae1393SZhangfei Gao } 69*53ae1393SZhangfei Gao 70*53ae1393SZhangfei Gao /* Reset device statistics */ 71*53ae1393SZhangfei Gao static void 72*53ae1393SZhangfei Gao uadk_crypto_pmd_stats_reset(struct rte_cryptodev *dev __rte_unused) 73*53ae1393SZhangfei Gao { 74*53ae1393SZhangfei Gao int qp_id; 75*53ae1393SZhangfei Gao 76*53ae1393SZhangfei Gao for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 77*53ae1393SZhangfei Gao struct uadk_qp *qp = dev->data->queue_pairs[qp_id]; 78*53ae1393SZhangfei Gao 79*53ae1393SZhangfei Gao memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 80*53ae1393SZhangfei Gao } 81*53ae1393SZhangfei Gao } 82*53ae1393SZhangfei Gao 83*53ae1393SZhangfei Gao /* Get device info */ 84*53ae1393SZhangfei Gao static void 85*53ae1393SZhangfei Gao uadk_crypto_pmd_info_get(struct rte_cryptodev *dev, 86*53ae1393SZhangfei Gao struct rte_cryptodev_info *dev_info) 87*53ae1393SZhangfei Gao { 88*53ae1393SZhangfei Gao struct uadk_crypto_priv *priv = dev->data->dev_private; 89*53ae1393SZhangfei Gao 90*53ae1393SZhangfei Gao if (dev_info != NULL) { 91*53ae1393SZhangfei Gao dev_info->driver_id = dev->driver_id; 92*53ae1393SZhangfei Gao dev_info->driver_name = dev->device->driver->name; 93*53ae1393SZhangfei Gao dev_info->max_nb_queue_pairs = 128; 94*53ae1393SZhangfei Gao /* No limit of number of sessions */ 95*53ae1393SZhangfei Gao dev_info->sym.max_nb_sessions = 0; 96*53ae1393SZhangfei Gao dev_info->feature_flags = dev->feature_flags; 97*53ae1393SZhangfei Gao 98*53ae1393SZhangfei Gao if (priv->version == UADK_CRYPTO_V2) 99*53ae1393SZhangfei Gao dev_info->capabilities = uadk_crypto_v2_capabilities; 100*53ae1393SZhangfei Gao } 101*53ae1393SZhangfei Gao } 102*53ae1393SZhangfei Gao 103*53ae1393SZhangfei Gao /* Release queue pair */ 104*53ae1393SZhangfei Gao static int 105*53ae1393SZhangfei Gao uadk_crypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id) 106*53ae1393SZhangfei Gao { 107*53ae1393SZhangfei Gao struct uadk_qp *qp = dev->data->queue_pairs[qp_id]; 108*53ae1393SZhangfei Gao 109*53ae1393SZhangfei Gao if (qp) { 110*53ae1393SZhangfei Gao rte_ring_free(qp->processed_pkts); 111*53ae1393SZhangfei Gao rte_free(qp); 112*53ae1393SZhangfei Gao dev->data->queue_pairs[qp_id] = NULL; 113*53ae1393SZhangfei Gao } 114*53ae1393SZhangfei Gao 115*53ae1393SZhangfei Gao return 0; 116*53ae1393SZhangfei Gao } 117*53ae1393SZhangfei Gao 118*53ae1393SZhangfei Gao /* set a unique name for the queue pair based on its name, dev_id and qp_id */ 119*53ae1393SZhangfei Gao static int 120*53ae1393SZhangfei Gao uadk_pmd_qp_set_unique_name(struct rte_cryptodev *dev, 121*53ae1393SZhangfei Gao struct uadk_qp *qp) 122*53ae1393SZhangfei Gao { 123*53ae1393SZhangfei Gao unsigned int n = snprintf(qp->name, sizeof(qp->name), 124*53ae1393SZhangfei Gao "uadk_crypto_pmd_%u_qp_%u", 125*53ae1393SZhangfei Gao dev->data->dev_id, qp->id); 126*53ae1393SZhangfei Gao 127*53ae1393SZhangfei Gao if (n >= sizeof(qp->name)) 128*53ae1393SZhangfei Gao return -EINVAL; 129*53ae1393SZhangfei Gao 130*53ae1393SZhangfei Gao return 0; 131*53ae1393SZhangfei Gao } 132*53ae1393SZhangfei Gao 133*53ae1393SZhangfei Gao /* Create a ring to place process packets on */ 134*53ae1393SZhangfei Gao static struct rte_ring * 135*53ae1393SZhangfei Gao uadk_pmd_qp_create_processed_pkts_ring(struct uadk_qp *qp, 136*53ae1393SZhangfei Gao unsigned int ring_size, int socket_id) 137*53ae1393SZhangfei Gao { 138*53ae1393SZhangfei Gao struct rte_ring *r = qp->processed_pkts; 139*53ae1393SZhangfei Gao 140*53ae1393SZhangfei Gao if (r) { 141*53ae1393SZhangfei Gao if (rte_ring_get_size(r) >= ring_size) { 142*53ae1393SZhangfei Gao UADK_LOG(INFO, "Reusing existing ring %s for processed packets", 143*53ae1393SZhangfei Gao qp->name); 144*53ae1393SZhangfei Gao return r; 145*53ae1393SZhangfei Gao } 146*53ae1393SZhangfei Gao 147*53ae1393SZhangfei Gao UADK_LOG(ERR, "Unable to reuse existing ring %s for processed packets", 148*53ae1393SZhangfei Gao qp->name); 149*53ae1393SZhangfei Gao return NULL; 150*53ae1393SZhangfei Gao } 151*53ae1393SZhangfei Gao 152*53ae1393SZhangfei Gao return rte_ring_create(qp->name, ring_size, socket_id, 153*53ae1393SZhangfei Gao RING_F_EXACT_SZ); 154*53ae1393SZhangfei Gao } 155*53ae1393SZhangfei Gao 156*53ae1393SZhangfei Gao static int 157*53ae1393SZhangfei Gao uadk_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id, 158*53ae1393SZhangfei Gao const struct rte_cryptodev_qp_conf *qp_conf, 159*53ae1393SZhangfei Gao int socket_id) 160*53ae1393SZhangfei Gao { 161*53ae1393SZhangfei Gao struct uadk_qp *qp; 162*53ae1393SZhangfei Gao 163*53ae1393SZhangfei Gao /* Free memory prior to re-allocation if needed. */ 164*53ae1393SZhangfei Gao if (dev->data->queue_pairs[qp_id] != NULL) 165*53ae1393SZhangfei Gao uadk_crypto_pmd_qp_release(dev, qp_id); 166*53ae1393SZhangfei Gao 167*53ae1393SZhangfei Gao /* Allocate the queue pair data structure. */ 168*53ae1393SZhangfei Gao qp = rte_zmalloc_socket("uadk PMD Queue Pair", sizeof(*qp), 169*53ae1393SZhangfei Gao RTE_CACHE_LINE_SIZE, socket_id); 170*53ae1393SZhangfei Gao if (qp == NULL) 171*53ae1393SZhangfei Gao return (-ENOMEM); 172*53ae1393SZhangfei Gao 173*53ae1393SZhangfei Gao qp->id = qp_id; 174*53ae1393SZhangfei Gao dev->data->queue_pairs[qp_id] = qp; 175*53ae1393SZhangfei Gao 176*53ae1393SZhangfei Gao if (uadk_pmd_qp_set_unique_name(dev, qp)) 177*53ae1393SZhangfei Gao goto qp_setup_cleanup; 178*53ae1393SZhangfei Gao 179*53ae1393SZhangfei Gao qp->processed_pkts = uadk_pmd_qp_create_processed_pkts_ring(qp, 180*53ae1393SZhangfei Gao qp_conf->nb_descriptors, socket_id); 181*53ae1393SZhangfei Gao if (qp->processed_pkts == NULL) 182*53ae1393SZhangfei Gao goto qp_setup_cleanup; 183*53ae1393SZhangfei Gao 184*53ae1393SZhangfei Gao memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 185*53ae1393SZhangfei Gao 186*53ae1393SZhangfei Gao return 0; 187*53ae1393SZhangfei Gao 188*53ae1393SZhangfei Gao qp_setup_cleanup: 189*53ae1393SZhangfei Gao if (qp) { 190*53ae1393SZhangfei Gao rte_free(qp); 191*53ae1393SZhangfei Gao qp = NULL; 192*53ae1393SZhangfei Gao } 193*53ae1393SZhangfei Gao return -EINVAL; 194*53ae1393SZhangfei Gao } 195*53ae1393SZhangfei Gao 1968c515d96SZhangfei Gao static struct rte_cryptodev_ops uadk_crypto_pmd_ops = { 197*53ae1393SZhangfei Gao .dev_configure = uadk_crypto_pmd_config, 198*53ae1393SZhangfei Gao .dev_start = uadk_crypto_pmd_start, 199*53ae1393SZhangfei Gao .dev_stop = uadk_crypto_pmd_stop, 200*53ae1393SZhangfei Gao .dev_close = uadk_crypto_pmd_close, 201*53ae1393SZhangfei Gao .stats_get = uadk_crypto_pmd_stats_get, 202*53ae1393SZhangfei Gao .stats_reset = uadk_crypto_pmd_stats_reset, 203*53ae1393SZhangfei Gao .dev_infos_get = uadk_crypto_pmd_info_get, 204*53ae1393SZhangfei Gao .queue_pair_setup = uadk_crypto_pmd_qp_setup, 205*53ae1393SZhangfei Gao .queue_pair_release = uadk_crypto_pmd_qp_release, 2068c515d96SZhangfei Gao .sym_session_get_size = NULL, 2078c515d96SZhangfei Gao .sym_session_configure = NULL, 2088c515d96SZhangfei Gao .sym_session_clear = NULL, 2098c515d96SZhangfei Gao }; 2108c515d96SZhangfei Gao 2118c515d96SZhangfei Gao static int 2128c515d96SZhangfei Gao uadk_cryptodev_probe(struct rte_vdev_device *vdev) 2138c515d96SZhangfei Gao { 2148c515d96SZhangfei Gao struct rte_cryptodev_pmd_init_params init_params = { 2158c515d96SZhangfei Gao .name = "", 2168c515d96SZhangfei Gao .private_data_size = sizeof(struct uadk_crypto_priv), 2178c515d96SZhangfei Gao .max_nb_queue_pairs = 2188c515d96SZhangfei Gao RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS, 2198c515d96SZhangfei Gao }; 2208c515d96SZhangfei Gao enum uadk_crypto_version version = UADK_CRYPTO_V2; 2218c515d96SZhangfei Gao struct uadk_crypto_priv *priv; 2228c515d96SZhangfei Gao struct rte_cryptodev *dev; 2238c515d96SZhangfei Gao struct uacce_dev *udev; 2248c515d96SZhangfei Gao const char *name; 2258c515d96SZhangfei Gao 2268c515d96SZhangfei Gao udev = wd_get_accel_dev("cipher"); 2278c515d96SZhangfei Gao if (!udev) 2288c515d96SZhangfei Gao return -ENODEV; 2298c515d96SZhangfei Gao 2308c515d96SZhangfei Gao if (!strcmp(udev->api, "hisi_qm_v2")) 2318c515d96SZhangfei Gao version = UADK_CRYPTO_V2; 2328c515d96SZhangfei Gao 2338c515d96SZhangfei Gao free(udev); 2348c515d96SZhangfei Gao 2358c515d96SZhangfei Gao name = rte_vdev_device_name(vdev); 2368c515d96SZhangfei Gao if (name == NULL) 2378c515d96SZhangfei Gao return -EINVAL; 2388c515d96SZhangfei Gao 2398c515d96SZhangfei Gao dev = rte_cryptodev_pmd_create(name, &vdev->device, &init_params); 2408c515d96SZhangfei Gao if (dev == NULL) { 2418c515d96SZhangfei Gao UADK_LOG(ERR, "driver %s: create failed", init_params.name); 2428c515d96SZhangfei Gao return -ENODEV; 2438c515d96SZhangfei Gao } 2448c515d96SZhangfei Gao 2458c515d96SZhangfei Gao dev->dev_ops = &uadk_crypto_pmd_ops; 2468c515d96SZhangfei Gao dev->driver_id = uadk_cryptodev_driver_id; 2478c515d96SZhangfei Gao dev->dequeue_burst = NULL; 2488c515d96SZhangfei Gao dev->enqueue_burst = NULL; 2498c515d96SZhangfei Gao dev->feature_flags = RTE_CRYPTODEV_FF_HW_ACCELERATED; 2508c515d96SZhangfei Gao priv = dev->data->dev_private; 2518c515d96SZhangfei Gao priv->version = version; 2528c515d96SZhangfei Gao 2538c515d96SZhangfei Gao rte_cryptodev_pmd_probing_finish(dev); 2548c515d96SZhangfei Gao 2558c515d96SZhangfei Gao return 0; 2568c515d96SZhangfei Gao } 2578c515d96SZhangfei Gao 2588c515d96SZhangfei Gao static int 2598c515d96SZhangfei Gao uadk_cryptodev_remove(struct rte_vdev_device *vdev) 2608c515d96SZhangfei Gao { 2618c515d96SZhangfei Gao struct rte_cryptodev *cryptodev; 2628c515d96SZhangfei Gao const char *name; 2638c515d96SZhangfei Gao 2648c515d96SZhangfei Gao name = rte_vdev_device_name(vdev); 2658c515d96SZhangfei Gao if (name == NULL) 2668c515d96SZhangfei Gao return -EINVAL; 2678c515d96SZhangfei Gao 2688c515d96SZhangfei Gao cryptodev = rte_cryptodev_pmd_get_named_dev(name); 2698c515d96SZhangfei Gao if (cryptodev == NULL) 2708c515d96SZhangfei Gao return -ENODEV; 2718c515d96SZhangfei Gao 2728c515d96SZhangfei Gao return rte_cryptodev_pmd_destroy(cryptodev); 2738c515d96SZhangfei Gao } 2748c515d96SZhangfei Gao 2758c515d96SZhangfei Gao static struct rte_vdev_driver uadk_crypto_pmd = { 2768c515d96SZhangfei Gao .probe = uadk_cryptodev_probe, 2778c515d96SZhangfei Gao .remove = uadk_cryptodev_remove, 2788c515d96SZhangfei Gao }; 2798c515d96SZhangfei Gao 2808c515d96SZhangfei Gao static struct cryptodev_driver uadk_crypto_drv; 2818c515d96SZhangfei Gao 2828c515d96SZhangfei Gao #define UADK_CRYPTO_DRIVER_NAME crypto_uadk 2838c515d96SZhangfei Gao RTE_PMD_REGISTER_VDEV(UADK_CRYPTO_DRIVER_NAME, uadk_crypto_pmd); 2848c515d96SZhangfei Gao RTE_PMD_REGISTER_CRYPTO_DRIVER(uadk_crypto_drv, uadk_crypto_pmd.driver, 2858c515d96SZhangfei Gao uadk_cryptodev_driver_id); 2868c515d96SZhangfei Gao RTE_LOG_REGISTER_DEFAULT(uadk_crypto_logtype, INFO); 287