1b4ce3594SNagadheeraj Rottela /* SPDX-License-Identifier: BSD-3-Clause 2b4ce3594SNagadheeraj Rottela * Copyright(C) 2024 Marvell. 3b4ce3594SNagadheeraj Rottela */ 4b4ce3594SNagadheeraj Rottela 5b4ce3594SNagadheeraj Rottela #include <rte_compressdev_pmd.h> 6b4ce3594SNagadheeraj Rottela #include <rte_comp.h> 7b4ce3594SNagadheeraj Rottela #include <rte_errno.h> 8ef80e265SNagadheeraj Rottela #include <rte_malloc.h> 9b4ce3594SNagadheeraj Rottela 10b4ce3594SNagadheeraj Rottela #include "nitrox_comp.h" 11b4ce3594SNagadheeraj Rottela #include "nitrox_device.h" 12b4ce3594SNagadheeraj Rottela #include "nitrox_logs.h" 13b4ce3594SNagadheeraj Rottela #include "nitrox_comp_reqmgr.h" 14ef80e265SNagadheeraj Rottela #include "nitrox_qp.h" 15b4ce3594SNagadheeraj Rottela 16b4ce3594SNagadheeraj Rottela static const char nitrox_comp_drv_name[] = RTE_STR(COMPRESSDEV_NAME_NITROX_PMD); 17b4ce3594SNagadheeraj Rottela static const struct rte_driver nitrox_rte_comp_drv = { 18b4ce3594SNagadheeraj Rottela .name = nitrox_comp_drv_name, 19b4ce3594SNagadheeraj Rottela .alias = nitrox_comp_drv_name 20b4ce3594SNagadheeraj Rottela }; 21b4ce3594SNagadheeraj Rottela 22ef80e265SNagadheeraj Rottela static int nitrox_comp_queue_pair_release(struct rte_compressdev *dev, 23ef80e265SNagadheeraj Rottela uint16_t qp_id); 24ef80e265SNagadheeraj Rottela 25b4ce3594SNagadheeraj Rottela static const struct rte_compressdev_capabilities 26b4ce3594SNagadheeraj Rottela nitrox_comp_pmd_capabilities[] = { 27b4ce3594SNagadheeraj Rottela { .algo = RTE_COMP_ALGO_DEFLATE, 28b4ce3594SNagadheeraj Rottela .comp_feature_flags = RTE_COMP_FF_HUFFMAN_FIXED | 29b4ce3594SNagadheeraj Rottela RTE_COMP_FF_HUFFMAN_DYNAMIC | 30b4ce3594SNagadheeraj Rottela RTE_COMP_FF_CRC32_CHECKSUM | 31b4ce3594SNagadheeraj Rottela RTE_COMP_FF_ADLER32_CHECKSUM | 32b4ce3594SNagadheeraj Rottela RTE_COMP_FF_SHAREABLE_PRIV_XFORM | 33b4ce3594SNagadheeraj Rottela RTE_COMP_FF_OOP_SGL_IN_SGL_OUT | 34b4ce3594SNagadheeraj Rottela RTE_COMP_FF_OOP_SGL_IN_LB_OUT | 356ea6bcddSNagadheeraj Rottela RTE_COMP_FF_OOP_LB_IN_SGL_OUT | 366ea6bcddSNagadheeraj Rottela RTE_COMP_FF_STATEFUL_COMPRESSION | 376ea6bcddSNagadheeraj Rottela RTE_COMP_FF_STATEFUL_DECOMPRESSION, 38b4ce3594SNagadheeraj Rottela .window_size = { 39b4ce3594SNagadheeraj Rottela .min = NITROX_COMP_WINDOW_SIZE_MIN, 40b4ce3594SNagadheeraj Rottela .max = NITROX_COMP_WINDOW_SIZE_MAX, 41b4ce3594SNagadheeraj Rottela .increment = 1 42b4ce3594SNagadheeraj Rottela }, 43b4ce3594SNagadheeraj Rottela }, 44b4ce3594SNagadheeraj Rottela RTE_COMP_END_OF_CAPABILITIES_LIST() 45b4ce3594SNagadheeraj Rottela }; 46b4ce3594SNagadheeraj Rottela 47b4ce3594SNagadheeraj Rottela static int nitrox_comp_dev_configure(struct rte_compressdev *dev, 48b4ce3594SNagadheeraj Rottela struct rte_compressdev_config *config) 49b4ce3594SNagadheeraj Rottela { 50b4ce3594SNagadheeraj Rottela struct nitrox_comp_device *comp_dev = dev->data->dev_private; 51b4ce3594SNagadheeraj Rottela struct nitrox_device *ndev = comp_dev->ndev; 52b4ce3594SNagadheeraj Rottela uint32_t xform_cnt; 53b4ce3594SNagadheeraj Rottela char name[RTE_MEMPOOL_NAMESIZE]; 54b4ce3594SNagadheeraj Rottela 55b4ce3594SNagadheeraj Rottela if (config->nb_queue_pairs > ndev->nr_queues) { 56*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Invalid queue pairs, max supported %d", 57b4ce3594SNagadheeraj Rottela ndev->nr_queues); 58b4ce3594SNagadheeraj Rottela return -EINVAL; 59b4ce3594SNagadheeraj Rottela } 60b4ce3594SNagadheeraj Rottela 61b4ce3594SNagadheeraj Rottela xform_cnt = config->max_nb_priv_xforms + config->max_nb_streams; 62b4ce3594SNagadheeraj Rottela if (unlikely(xform_cnt == 0)) { 63*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Invalid configuration with 0 xforms"); 64b4ce3594SNagadheeraj Rottela return -EINVAL; 65b4ce3594SNagadheeraj Rottela } 66b4ce3594SNagadheeraj Rottela 67b4ce3594SNagadheeraj Rottela snprintf(name, sizeof(name), "%s_xform", dev->data->name); 68b4ce3594SNagadheeraj Rottela comp_dev->xform_pool = rte_mempool_create(name, 69b4ce3594SNagadheeraj Rottela xform_cnt, sizeof(struct nitrox_comp_xform), 70b4ce3594SNagadheeraj Rottela 0, 0, NULL, NULL, NULL, NULL, 71b4ce3594SNagadheeraj Rottela config->socket_id, 0); 72b4ce3594SNagadheeraj Rottela if (comp_dev->xform_pool == NULL) { 73*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Failed to create xform pool, err %d", 74b4ce3594SNagadheeraj Rottela rte_errno); 75b4ce3594SNagadheeraj Rottela return -rte_errno; 76b4ce3594SNagadheeraj Rottela } 77b4ce3594SNagadheeraj Rottela 78b4ce3594SNagadheeraj Rottela return 0; 79b4ce3594SNagadheeraj Rottela } 80b4ce3594SNagadheeraj Rottela 81b4ce3594SNagadheeraj Rottela static int nitrox_comp_dev_start(struct rte_compressdev *dev) 82b4ce3594SNagadheeraj Rottela { 83b4ce3594SNagadheeraj Rottela RTE_SET_USED(dev); 84b4ce3594SNagadheeraj Rottela return 0; 85b4ce3594SNagadheeraj Rottela } 86b4ce3594SNagadheeraj Rottela 87b4ce3594SNagadheeraj Rottela static void nitrox_comp_dev_stop(struct rte_compressdev *dev) 88b4ce3594SNagadheeraj Rottela { 89b4ce3594SNagadheeraj Rottela RTE_SET_USED(dev); 90b4ce3594SNagadheeraj Rottela } 91b4ce3594SNagadheeraj Rottela 92b4ce3594SNagadheeraj Rottela static int nitrox_comp_dev_close(struct rte_compressdev *dev) 93b4ce3594SNagadheeraj Rottela { 94ef80e265SNagadheeraj Rottela int i, ret; 95b4ce3594SNagadheeraj Rottela struct nitrox_comp_device *comp_dev = dev->data->dev_private; 96b4ce3594SNagadheeraj Rottela 97ef80e265SNagadheeraj Rottela for (i = 0; i < dev->data->nb_queue_pairs; i++) { 98ef80e265SNagadheeraj Rottela ret = nitrox_comp_queue_pair_release(dev, i); 99ef80e265SNagadheeraj Rottela if (ret) 100ef80e265SNagadheeraj Rottela return ret; 101ef80e265SNagadheeraj Rottela } 102ef80e265SNagadheeraj Rottela 103b4ce3594SNagadheeraj Rottela rte_mempool_free(comp_dev->xform_pool); 104b4ce3594SNagadheeraj Rottela comp_dev->xform_pool = NULL; 105b4ce3594SNagadheeraj Rottela return 0; 106b4ce3594SNagadheeraj Rottela } 107b4ce3594SNagadheeraj Rottela 108b4ce3594SNagadheeraj Rottela static void nitrox_comp_stats_get(struct rte_compressdev *dev, 109b4ce3594SNagadheeraj Rottela struct rte_compressdev_stats *stats) 110b4ce3594SNagadheeraj Rottela { 111ef80e265SNagadheeraj Rottela int qp_id; 112ef80e265SNagadheeraj Rottela 113ef80e265SNagadheeraj Rottela for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 114ef80e265SNagadheeraj Rottela struct nitrox_qp *qp = dev->data->queue_pairs[qp_id]; 115ef80e265SNagadheeraj Rottela 116ef80e265SNagadheeraj Rottela if (!qp) 117ef80e265SNagadheeraj Rottela continue; 118ef80e265SNagadheeraj Rottela 119ef80e265SNagadheeraj Rottela stats->enqueued_count += qp->stats.enqueued_count; 120ef80e265SNagadheeraj Rottela stats->dequeued_count += qp->stats.dequeued_count; 121ef80e265SNagadheeraj Rottela stats->enqueue_err_count += qp->stats.enqueue_err_count; 122ef80e265SNagadheeraj Rottela stats->dequeue_err_count += qp->stats.dequeue_err_count; 123ef80e265SNagadheeraj Rottela } 124b4ce3594SNagadheeraj Rottela } 125b4ce3594SNagadheeraj Rottela 126b4ce3594SNagadheeraj Rottela static void nitrox_comp_stats_reset(struct rte_compressdev *dev) 127b4ce3594SNagadheeraj Rottela { 128ef80e265SNagadheeraj Rottela int qp_id; 129ef80e265SNagadheeraj Rottela 130ef80e265SNagadheeraj Rottela for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 131ef80e265SNagadheeraj Rottela struct nitrox_qp *qp = dev->data->queue_pairs[qp_id]; 132ef80e265SNagadheeraj Rottela 133ef80e265SNagadheeraj Rottela if (!qp) 134ef80e265SNagadheeraj Rottela continue; 135ef80e265SNagadheeraj Rottela 136ef80e265SNagadheeraj Rottela memset(&qp->stats, 0, sizeof(qp->stats)); 137ef80e265SNagadheeraj Rottela } 138b4ce3594SNagadheeraj Rottela } 139b4ce3594SNagadheeraj Rottela 140b4ce3594SNagadheeraj Rottela static void nitrox_comp_dev_info_get(struct rte_compressdev *dev, 141b4ce3594SNagadheeraj Rottela struct rte_compressdev_info *info) 142b4ce3594SNagadheeraj Rottela { 143b4ce3594SNagadheeraj Rottela struct nitrox_comp_device *comp_dev = dev->data->dev_private; 144b4ce3594SNagadheeraj Rottela struct nitrox_device *ndev = comp_dev->ndev; 145b4ce3594SNagadheeraj Rottela 146b4ce3594SNagadheeraj Rottela if (!info) 147b4ce3594SNagadheeraj Rottela return; 148b4ce3594SNagadheeraj Rottela 149b4ce3594SNagadheeraj Rottela info->max_nb_queue_pairs = ndev->nr_queues; 150b4ce3594SNagadheeraj Rottela info->feature_flags = dev->feature_flags; 151b4ce3594SNagadheeraj Rottela info->capabilities = nitrox_comp_pmd_capabilities; 152b4ce3594SNagadheeraj Rottela } 153b4ce3594SNagadheeraj Rottela 154b4ce3594SNagadheeraj Rottela static int nitrox_comp_queue_pair_setup(struct rte_compressdev *dev, 155b4ce3594SNagadheeraj Rottela uint16_t qp_id, 156b4ce3594SNagadheeraj Rottela uint32_t max_inflight_ops, int socket_id) 157b4ce3594SNagadheeraj Rottela { 158ef80e265SNagadheeraj Rottela struct nitrox_comp_device *comp_dev = dev->data->dev_private; 159ef80e265SNagadheeraj Rottela struct nitrox_device *ndev = comp_dev->ndev; 160ef80e265SNagadheeraj Rottela struct nitrox_qp *qp = NULL; 161ef80e265SNagadheeraj Rottela int err; 162ef80e265SNagadheeraj Rottela 163*e99981afSDavid Marchand NITROX_LOG_LINE(DEBUG, "queue %d", qp_id); 164ef80e265SNagadheeraj Rottela if (qp_id >= ndev->nr_queues) { 165*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "queue %u invalid, max queues supported %d", 166ef80e265SNagadheeraj Rottela qp_id, ndev->nr_queues); 167ef80e265SNagadheeraj Rottela return -EINVAL; 168ef80e265SNagadheeraj Rottela } 169ef80e265SNagadheeraj Rottela 170ef80e265SNagadheeraj Rottela if (dev->data->queue_pairs[qp_id]) { 171ef80e265SNagadheeraj Rottela err = nitrox_comp_queue_pair_release(dev, qp_id); 172ef80e265SNagadheeraj Rottela if (err) 173ef80e265SNagadheeraj Rottela return err; 174ef80e265SNagadheeraj Rottela } 175ef80e265SNagadheeraj Rottela 176ef80e265SNagadheeraj Rottela qp = rte_zmalloc_socket("nitrox PMD qp", sizeof(*qp), 177ef80e265SNagadheeraj Rottela RTE_CACHE_LINE_SIZE, 178ef80e265SNagadheeraj Rottela socket_id); 179ef80e265SNagadheeraj Rottela if (!qp) { 180*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Failed to allocate nitrox qp"); 181ef80e265SNagadheeraj Rottela return -ENOMEM; 182ef80e265SNagadheeraj Rottela } 183ef80e265SNagadheeraj Rottela 184ef80e265SNagadheeraj Rottela qp->type = NITROX_QUEUE_ZIP; 185ef80e265SNagadheeraj Rottela qp->qno = qp_id; 186ef80e265SNagadheeraj Rottela err = nitrox_qp_setup(qp, ndev->bar_addr, dev->data->name, 187ef80e265SNagadheeraj Rottela max_inflight_ops, ZIP_INSTR_SIZE, 188ef80e265SNagadheeraj Rottela socket_id); 189ef80e265SNagadheeraj Rottela if (unlikely(err)) 190ef80e265SNagadheeraj Rottela goto qp_setup_err; 191ef80e265SNagadheeraj Rottela 192f008628aSNagadheeraj Rottela qp->sr_mp = nitrox_comp_req_pool_create(dev, qp->count, qp_id, 193f008628aSNagadheeraj Rottela socket_id); 194f008628aSNagadheeraj Rottela if (unlikely(!qp->sr_mp)) 195f008628aSNagadheeraj Rottela goto req_pool_err; 196f008628aSNagadheeraj Rottela 197ef80e265SNagadheeraj Rottela dev->data->queue_pairs[qp_id] = qp; 198*e99981afSDavid Marchand NITROX_LOG_LINE(DEBUG, "queue %d setup done", qp_id); 199ef80e265SNagadheeraj Rottela return 0; 200ef80e265SNagadheeraj Rottela 201f008628aSNagadheeraj Rottela req_pool_err: 202f008628aSNagadheeraj Rottela nitrox_qp_release(qp, ndev->bar_addr); 203ef80e265SNagadheeraj Rottela qp_setup_err: 204ef80e265SNagadheeraj Rottela rte_free(qp); 205ef80e265SNagadheeraj Rottela return err; 206b4ce3594SNagadheeraj Rottela } 207b4ce3594SNagadheeraj Rottela 208b4ce3594SNagadheeraj Rottela static int nitrox_comp_queue_pair_release(struct rte_compressdev *dev, 209b4ce3594SNagadheeraj Rottela uint16_t qp_id) 210b4ce3594SNagadheeraj Rottela { 211ef80e265SNagadheeraj Rottela struct nitrox_comp_device *comp_dev = dev->data->dev_private; 212ef80e265SNagadheeraj Rottela struct nitrox_device *ndev = comp_dev->ndev; 213ef80e265SNagadheeraj Rottela struct nitrox_qp *qp; 214ef80e265SNagadheeraj Rottela int err; 215ef80e265SNagadheeraj Rottela 216*e99981afSDavid Marchand NITROX_LOG_LINE(DEBUG, "queue %d", qp_id); 217ef80e265SNagadheeraj Rottela if (qp_id >= ndev->nr_queues) { 218*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "queue %u invalid, max queues supported %d", 219ef80e265SNagadheeraj Rottela qp_id, ndev->nr_queues); 220ef80e265SNagadheeraj Rottela return -EINVAL; 221ef80e265SNagadheeraj Rottela } 222ef80e265SNagadheeraj Rottela 223ef80e265SNagadheeraj Rottela qp = dev->data->queue_pairs[qp_id]; 224ef80e265SNagadheeraj Rottela if (!qp) { 225*e99981afSDavid Marchand NITROX_LOG_LINE(DEBUG, "queue %u already freed", qp_id); 226b4ce3594SNagadheeraj Rottela return 0; 227b4ce3594SNagadheeraj Rottela } 228b4ce3594SNagadheeraj Rottela 229ef80e265SNagadheeraj Rottela if (!nitrox_qp_is_empty(qp)) { 230*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "queue %d not empty", qp_id); 231ef80e265SNagadheeraj Rottela return -EAGAIN; 232ef80e265SNagadheeraj Rottela } 233ef80e265SNagadheeraj Rottela 234ef80e265SNagadheeraj Rottela dev->data->queue_pairs[qp_id] = NULL; 235ef80e265SNagadheeraj Rottela err = nitrox_qp_release(qp, ndev->bar_addr); 236f008628aSNagadheeraj Rottela nitrox_comp_req_pool_free(qp->sr_mp); 237ef80e265SNagadheeraj Rottela rte_free(qp); 238*e99981afSDavid Marchand NITROX_LOG_LINE(DEBUG, "queue %d release done", qp_id); 239ef80e265SNagadheeraj Rottela return err; 240ef80e265SNagadheeraj Rottela } 241ef80e265SNagadheeraj Rottela 242b4ce3594SNagadheeraj Rottela static int nitrox_comp_private_xform_create(struct rte_compressdev *dev, 243b4ce3594SNagadheeraj Rottela const struct rte_comp_xform *xform, 244b4ce3594SNagadheeraj Rottela void **private_xform) 245b4ce3594SNagadheeraj Rottela { 246b4ce3594SNagadheeraj Rottela struct nitrox_comp_device *comp_dev = dev->data->dev_private; 247b4ce3594SNagadheeraj Rottela struct nitrox_comp_xform *nxform; 248b4ce3594SNagadheeraj Rottela enum rte_comp_checksum_type chksum_type; 249b4ce3594SNagadheeraj Rottela int ret; 250b4ce3594SNagadheeraj Rottela 251b4ce3594SNagadheeraj Rottela if (unlikely(comp_dev->xform_pool == NULL)) { 252*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "private xform pool not yet created"); 253b4ce3594SNagadheeraj Rottela return -EINVAL; 254b4ce3594SNagadheeraj Rottela } 255b4ce3594SNagadheeraj Rottela 256b4ce3594SNagadheeraj Rottela if (rte_mempool_get(comp_dev->xform_pool, private_xform)) { 257*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Failed to get from private xform pool"); 258b4ce3594SNagadheeraj Rottela return -ENOMEM; 259b4ce3594SNagadheeraj Rottela } 260b4ce3594SNagadheeraj Rottela 261b4ce3594SNagadheeraj Rottela nxform = (struct nitrox_comp_xform *)*private_xform; 262b4ce3594SNagadheeraj Rottela memset(nxform, 0, sizeof(*nxform)); 263b4ce3594SNagadheeraj Rottela if (xform->type == RTE_COMP_COMPRESS) { 264b4ce3594SNagadheeraj Rottela enum rte_comp_huffman algo; 265b4ce3594SNagadheeraj Rottela int level; 266b4ce3594SNagadheeraj Rottela 267b4ce3594SNagadheeraj Rottela nxform->op = NITROX_COMP_OP_COMPRESS; 268b4ce3594SNagadheeraj Rottela if (xform->compress.algo != RTE_COMP_ALGO_DEFLATE) { 269*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Only deflate is supported"); 270b4ce3594SNagadheeraj Rottela ret = -ENOTSUP; 271b4ce3594SNagadheeraj Rottela goto err_exit; 272b4ce3594SNagadheeraj Rottela } 273b4ce3594SNagadheeraj Rottela 274b4ce3594SNagadheeraj Rottela algo = xform->compress.deflate.huffman; 275b4ce3594SNagadheeraj Rottela if (algo == RTE_COMP_HUFFMAN_DEFAULT) 276b4ce3594SNagadheeraj Rottela nxform->algo = NITROX_COMP_ALGO_DEFLATE_DEFAULT; 277b4ce3594SNagadheeraj Rottela else if (algo == RTE_COMP_HUFFMAN_FIXED) 278b4ce3594SNagadheeraj Rottela nxform->algo = NITROX_COMP_ALGO_DEFLATE_FIXEDHUFF; 279b4ce3594SNagadheeraj Rottela else if (algo == RTE_COMP_HUFFMAN_DYNAMIC) 280b4ce3594SNagadheeraj Rottela nxform->algo = NITROX_COMP_ALGO_DEFLATE_DYNHUFF; 281b4ce3594SNagadheeraj Rottela else { 282*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Invalid deflate algorithm %d", algo); 283b4ce3594SNagadheeraj Rottela ret = -EINVAL; 284b4ce3594SNagadheeraj Rottela goto err_exit; 285b4ce3594SNagadheeraj Rottela } 286b4ce3594SNagadheeraj Rottela 287b4ce3594SNagadheeraj Rottela level = xform->compress.level; 288b4ce3594SNagadheeraj Rottela if (level == RTE_COMP_LEVEL_PMD_DEFAULT) { 289b4ce3594SNagadheeraj Rottela nxform->level = NITROX_COMP_LEVEL_MEDIUM; 290b4ce3594SNagadheeraj Rottela } else if (level >= NITROX_COMP_LEVEL_LOWEST_START && 291b4ce3594SNagadheeraj Rottela level <= NITROX_COMP_LEVEL_LOWEST_END) { 292b4ce3594SNagadheeraj Rottela nxform->level = NITROX_COMP_LEVEL_LOWEST; 293b4ce3594SNagadheeraj Rottela } else if (level >= NITROX_COMP_LEVEL_LOWER_START && 294b4ce3594SNagadheeraj Rottela level <= NITROX_COMP_LEVEL_LOWER_END) { 295b4ce3594SNagadheeraj Rottela nxform->level = NITROX_COMP_LEVEL_LOWER; 296b4ce3594SNagadheeraj Rottela } else if (level >= NITROX_COMP_LEVEL_MEDIUM_START && 297b4ce3594SNagadheeraj Rottela level <= NITROX_COMP_LEVEL_MEDIUM_END) { 298b4ce3594SNagadheeraj Rottela nxform->level = NITROX_COMP_LEVEL_MEDIUM; 299b4ce3594SNagadheeraj Rottela } else if (level >= NITROX_COMP_LEVEL_BEST_START && 300b4ce3594SNagadheeraj Rottela level <= NITROX_COMP_LEVEL_BEST_END) { 301b4ce3594SNagadheeraj Rottela nxform->level = NITROX_COMP_LEVEL_BEST; 302b4ce3594SNagadheeraj Rottela } else { 303*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Unsupported compression level %d", 304b4ce3594SNagadheeraj Rottela xform->compress.level); 305b4ce3594SNagadheeraj Rottela ret = -ENOTSUP; 306b4ce3594SNagadheeraj Rottela goto err_exit; 307b4ce3594SNagadheeraj Rottela } 308b4ce3594SNagadheeraj Rottela 309b4ce3594SNagadheeraj Rottela chksum_type = xform->compress.chksum; 310b4ce3594SNagadheeraj Rottela } else if (xform->type == RTE_COMP_DECOMPRESS) { 311b4ce3594SNagadheeraj Rottela nxform->op = NITROX_COMP_OP_DECOMPRESS; 312b4ce3594SNagadheeraj Rottela if (xform->decompress.algo != RTE_COMP_ALGO_DEFLATE) { 313*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Only deflate is supported"); 314b4ce3594SNagadheeraj Rottela ret = -ENOTSUP; 315b4ce3594SNagadheeraj Rottela goto err_exit; 316b4ce3594SNagadheeraj Rottela } 317b4ce3594SNagadheeraj Rottela 318b4ce3594SNagadheeraj Rottela nxform->algo = NITROX_COMP_ALGO_DEFLATE_DEFAULT; 319b4ce3594SNagadheeraj Rottela nxform->level = NITROX_COMP_LEVEL_BEST; 320b4ce3594SNagadheeraj Rottela chksum_type = xform->decompress.chksum; 321b4ce3594SNagadheeraj Rottela } else { 322b4ce3594SNagadheeraj Rottela ret = -EINVAL; 323b4ce3594SNagadheeraj Rottela goto err_exit; 324b4ce3594SNagadheeraj Rottela } 325b4ce3594SNagadheeraj Rottela 326b4ce3594SNagadheeraj Rottela if (chksum_type == RTE_COMP_CHECKSUM_NONE) 327b4ce3594SNagadheeraj Rottela nxform->chksum_type = NITROX_CHKSUM_TYPE_NONE; 328b4ce3594SNagadheeraj Rottela else if (chksum_type == RTE_COMP_CHECKSUM_CRC32) 329b4ce3594SNagadheeraj Rottela nxform->chksum_type = NITROX_CHKSUM_TYPE_CRC32; 330b4ce3594SNagadheeraj Rottela else if (chksum_type == RTE_COMP_CHECKSUM_ADLER32) 331b4ce3594SNagadheeraj Rottela nxform->chksum_type = NITROX_CHKSUM_TYPE_ADLER32; 332b4ce3594SNagadheeraj Rottela else { 333*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Unsupported checksum type %d", 334b4ce3594SNagadheeraj Rottela chksum_type); 335b4ce3594SNagadheeraj Rottela ret = -ENOTSUP; 336b4ce3594SNagadheeraj Rottela goto err_exit; 337b4ce3594SNagadheeraj Rottela } 338b4ce3594SNagadheeraj Rottela 3396ea6bcddSNagadheeraj Rottela nxform->context = NULL; 3406ea6bcddSNagadheeraj Rottela nxform->history_window = NULL; 3416ea6bcddSNagadheeraj Rottela nxform->window_size = 0; 3426ea6bcddSNagadheeraj Rottela nxform->hlen = 0; 3436ea6bcddSNagadheeraj Rottela nxform->exn = 0; 3446ea6bcddSNagadheeraj Rottela nxform->exbits = 0; 3456ea6bcddSNagadheeraj Rottela nxform->bf = true; 346b4ce3594SNagadheeraj Rottela return 0; 347b4ce3594SNagadheeraj Rottela err_exit: 348b4ce3594SNagadheeraj Rottela memset(nxform, 0, sizeof(*nxform)); 349b4ce3594SNagadheeraj Rottela rte_mempool_put(comp_dev->xform_pool, nxform); 350b4ce3594SNagadheeraj Rottela return ret; 351b4ce3594SNagadheeraj Rottela } 352b4ce3594SNagadheeraj Rottela 353b4ce3594SNagadheeraj Rottela static int nitrox_comp_private_xform_free(struct rte_compressdev *dev, 354b4ce3594SNagadheeraj Rottela void *private_xform) 355b4ce3594SNagadheeraj Rottela { 356b4ce3594SNagadheeraj Rottela struct nitrox_comp_xform *nxform = private_xform; 357b4ce3594SNagadheeraj Rottela struct rte_mempool *mp = rte_mempool_from_obj(nxform); 358b4ce3594SNagadheeraj Rottela 359b4ce3594SNagadheeraj Rottela RTE_SET_USED(dev); 360b4ce3594SNagadheeraj Rottela if (unlikely(nxform == NULL)) 361b4ce3594SNagadheeraj Rottela return -EINVAL; 362b4ce3594SNagadheeraj Rottela 363b4ce3594SNagadheeraj Rottela memset(nxform, 0, sizeof(*nxform)); 364b4ce3594SNagadheeraj Rottela mp = rte_mempool_from_obj(nxform); 365b4ce3594SNagadheeraj Rottela rte_mempool_put(mp, nxform); 366b4ce3594SNagadheeraj Rottela return 0; 367b4ce3594SNagadheeraj Rottela } 368b4ce3594SNagadheeraj Rottela 3696ea6bcddSNagadheeraj Rottela static int nitrox_comp_stream_free(struct rte_compressdev *dev, void *stream) 3706ea6bcddSNagadheeraj Rottela { 3716ea6bcddSNagadheeraj Rottela struct nitrox_comp_xform *nxform = stream; 3726ea6bcddSNagadheeraj Rottela 3736ea6bcddSNagadheeraj Rottela if (unlikely(nxform == NULL)) 3746ea6bcddSNagadheeraj Rottela return -EINVAL; 3756ea6bcddSNagadheeraj Rottela 3766ea6bcddSNagadheeraj Rottela rte_free(nxform->history_window); 3776ea6bcddSNagadheeraj Rottela nxform->history_window = NULL; 3786ea6bcddSNagadheeraj Rottela rte_free(nxform->context); 3796ea6bcddSNagadheeraj Rottela nxform->context = NULL; 3806ea6bcddSNagadheeraj Rottela return nitrox_comp_private_xform_free(dev, stream); 3816ea6bcddSNagadheeraj Rottela } 3826ea6bcddSNagadheeraj Rottela 3836ea6bcddSNagadheeraj Rottela static int nitrox_comp_stream_create(struct rte_compressdev *dev, 3846ea6bcddSNagadheeraj Rottela const struct rte_comp_xform *xform, void **stream) 3856ea6bcddSNagadheeraj Rottela { 3866ea6bcddSNagadheeraj Rottela int err; 3876ea6bcddSNagadheeraj Rottela struct nitrox_comp_xform *nxform; 3886ea6bcddSNagadheeraj Rottela struct nitrox_comp_device *comp_dev = dev->data->dev_private; 3896ea6bcddSNagadheeraj Rottela 3906ea6bcddSNagadheeraj Rottela err = nitrox_comp_private_xform_create(dev, xform, stream); 3916ea6bcddSNagadheeraj Rottela if (unlikely(err)) 3926ea6bcddSNagadheeraj Rottela return err; 3936ea6bcddSNagadheeraj Rottela 3946ea6bcddSNagadheeraj Rottela nxform = *stream; 3956ea6bcddSNagadheeraj Rottela if (xform->type == RTE_COMP_COMPRESS) { 3966ea6bcddSNagadheeraj Rottela uint8_t window_size = xform->compress.window_size; 3976ea6bcddSNagadheeraj Rottela 3986ea6bcddSNagadheeraj Rottela if (unlikely(window_size < NITROX_COMP_WINDOW_SIZE_MIN || 3996ea6bcddSNagadheeraj Rottela window_size > NITROX_COMP_WINDOW_SIZE_MAX)) { 400*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Invalid window size %d", 4016ea6bcddSNagadheeraj Rottela window_size); 4026ea6bcddSNagadheeraj Rottela return -EINVAL; 4036ea6bcddSNagadheeraj Rottela } 4046ea6bcddSNagadheeraj Rottela 4056ea6bcddSNagadheeraj Rottela if (window_size == NITROX_COMP_WINDOW_SIZE_MAX) 4066ea6bcddSNagadheeraj Rottela nxform->window_size = NITROX_CONSTANTS_MAX_SEARCH_DEPTH; 4076ea6bcddSNagadheeraj Rottela else 4086ea6bcddSNagadheeraj Rottela nxform->window_size = RTE_BIT32(window_size); 4096ea6bcddSNagadheeraj Rottela } else { 4106ea6bcddSNagadheeraj Rottela nxform->window_size = NITROX_DEFAULT_DEFLATE_SEARCH_DEPTH; 4116ea6bcddSNagadheeraj Rottela } 4126ea6bcddSNagadheeraj Rottela 4136ea6bcddSNagadheeraj Rottela nxform->history_window = rte_zmalloc_socket(NULL, nxform->window_size, 4146ea6bcddSNagadheeraj Rottela 8, comp_dev->xform_pool->socket_id); 4156ea6bcddSNagadheeraj Rottela if (unlikely(nxform->history_window == NULL)) { 4166ea6bcddSNagadheeraj Rottela err = -ENOMEM; 4176ea6bcddSNagadheeraj Rottela goto err_exit; 4186ea6bcddSNagadheeraj Rottela } 4196ea6bcddSNagadheeraj Rottela 4206ea6bcddSNagadheeraj Rottela if (xform->type == RTE_COMP_COMPRESS) 4216ea6bcddSNagadheeraj Rottela return 0; 4226ea6bcddSNagadheeraj Rottela 4236ea6bcddSNagadheeraj Rottela nxform->context = rte_zmalloc_socket(NULL, 4246ea6bcddSNagadheeraj Rottela NITROX_DECOMP_CTX_SIZE, 8, 4256ea6bcddSNagadheeraj Rottela comp_dev->xform_pool->socket_id); 4266ea6bcddSNagadheeraj Rottela if (unlikely(nxform->context == NULL)) { 4276ea6bcddSNagadheeraj Rottela err = -ENOMEM; 4286ea6bcddSNagadheeraj Rottela goto err_exit; 4296ea6bcddSNagadheeraj Rottela } 4306ea6bcddSNagadheeraj Rottela 4316ea6bcddSNagadheeraj Rottela return 0; 4326ea6bcddSNagadheeraj Rottela err_exit: 4336ea6bcddSNagadheeraj Rottela nitrox_comp_stream_free(dev, *stream); 4346ea6bcddSNagadheeraj Rottela return err; 4356ea6bcddSNagadheeraj Rottela } 4366ea6bcddSNagadheeraj Rottela 437f008628aSNagadheeraj Rottela static int nitrox_enq_single_op(struct nitrox_qp *qp, struct rte_comp_op *op) 438b4ce3594SNagadheeraj Rottela { 439f008628aSNagadheeraj Rottela struct nitrox_softreq *sr; 440f008628aSNagadheeraj Rottela int err; 441f008628aSNagadheeraj Rottela 442f008628aSNagadheeraj Rottela if (unlikely(rte_mempool_get(qp->sr_mp, (void **)&sr))) 443f008628aSNagadheeraj Rottela return -ENOMEM; 444f008628aSNagadheeraj Rottela 445f008628aSNagadheeraj Rottela err = nitrox_process_comp_req(op, sr); 446f008628aSNagadheeraj Rottela if (unlikely(err)) { 447f008628aSNagadheeraj Rottela rte_mempool_put(qp->sr_mp, sr); 448f008628aSNagadheeraj Rottela return err; 449f008628aSNagadheeraj Rottela } 450f008628aSNagadheeraj Rottela 4516ea6bcddSNagadheeraj Rottela if (op->status == RTE_COMP_OP_STATUS_SUCCESS) 4526ea6bcddSNagadheeraj Rottela err = nitrox_qp_enqueue_sr(qp, sr); 4536ea6bcddSNagadheeraj Rottela else 454f008628aSNagadheeraj Rottela nitrox_qp_enqueue(qp, nitrox_comp_instr_addr(sr), sr); 4556ea6bcddSNagadheeraj Rottela 4566ea6bcddSNagadheeraj Rottela return err; 457b4ce3594SNagadheeraj Rottela } 458b4ce3594SNagadheeraj Rottela 459f008628aSNagadheeraj Rottela static uint16_t nitrox_comp_dev_enq_burst(void *queue_pair, 460b4ce3594SNagadheeraj Rottela struct rte_comp_op **ops, 461b4ce3594SNagadheeraj Rottela uint16_t nb_ops) 462b4ce3594SNagadheeraj Rottela { 463f008628aSNagadheeraj Rottela struct nitrox_qp *qp = queue_pair; 464f008628aSNagadheeraj Rottela uint16_t free_slots = 0; 465f008628aSNagadheeraj Rottela uint16_t cnt = 0; 4666ea6bcddSNagadheeraj Rottela uint16_t dbcnt = 0; 467f008628aSNagadheeraj Rottela bool err = false; 468f008628aSNagadheeraj Rottela 469f008628aSNagadheeraj Rottela free_slots = nitrox_qp_free_count(qp); 470f008628aSNagadheeraj Rottela if (nb_ops > free_slots) 471f008628aSNagadheeraj Rottela nb_ops = free_slots; 472f008628aSNagadheeraj Rottela 473f008628aSNagadheeraj Rottela for (cnt = 0; cnt < nb_ops; cnt++) { 474f008628aSNagadheeraj Rottela if (unlikely(nitrox_enq_single_op(qp, ops[cnt]))) { 475f008628aSNagadheeraj Rottela err = true; 476f008628aSNagadheeraj Rottela break; 477f008628aSNagadheeraj Rottela } 4786ea6bcddSNagadheeraj Rottela 4796ea6bcddSNagadheeraj Rottela if (ops[cnt]->status != RTE_COMP_OP_STATUS_SUCCESS) 4806ea6bcddSNagadheeraj Rottela dbcnt++; 481f008628aSNagadheeraj Rottela } 482f008628aSNagadheeraj Rottela 4836ea6bcddSNagadheeraj Rottela nitrox_ring_dbell(qp, dbcnt); 484f008628aSNagadheeraj Rottela qp->stats.enqueued_count += cnt; 485f008628aSNagadheeraj Rottela if (unlikely(err)) 486f008628aSNagadheeraj Rottela qp->stats.enqueue_err_count++; 487f008628aSNagadheeraj Rottela 488f008628aSNagadheeraj Rottela return cnt; 489f008628aSNagadheeraj Rottela } 490f008628aSNagadheeraj Rottela 491f008628aSNagadheeraj Rottela static int nitrox_deq_single_op(struct nitrox_qp *qp, 492f008628aSNagadheeraj Rottela struct rte_comp_op **op_ptr) 493f008628aSNagadheeraj Rottela { 494f008628aSNagadheeraj Rottela struct nitrox_softreq *sr; 495f008628aSNagadheeraj Rottela int err; 496f008628aSNagadheeraj Rottela 497f008628aSNagadheeraj Rottela sr = nitrox_qp_get_softreq(qp); 498f008628aSNagadheeraj Rottela err = nitrox_check_comp_req(sr, op_ptr); 499f008628aSNagadheeraj Rottela if (err == -EAGAIN) 500f008628aSNagadheeraj Rottela return err; 501f008628aSNagadheeraj Rottela 502f008628aSNagadheeraj Rottela nitrox_qp_dequeue(qp); 503f008628aSNagadheeraj Rottela rte_mempool_put(qp->sr_mp, sr); 504f008628aSNagadheeraj Rottela if (err == 0) 505f008628aSNagadheeraj Rottela qp->stats.dequeued_count++; 506f008628aSNagadheeraj Rottela else 507f008628aSNagadheeraj Rottela qp->stats.dequeue_err_count++; 508f008628aSNagadheeraj Rottela 509b4ce3594SNagadheeraj Rottela return 0; 510b4ce3594SNagadheeraj Rottela } 511b4ce3594SNagadheeraj Rottela 512f008628aSNagadheeraj Rottela static uint16_t nitrox_comp_dev_deq_burst(void *queue_pair, 513f008628aSNagadheeraj Rottela struct rte_comp_op **ops, 514f008628aSNagadheeraj Rottela uint16_t nb_ops) 515f008628aSNagadheeraj Rottela { 516f008628aSNagadheeraj Rottela struct nitrox_qp *qp = queue_pair; 517f008628aSNagadheeraj Rottela uint16_t filled_slots = nitrox_qp_used_count(qp); 518f008628aSNagadheeraj Rottela int cnt = 0; 519f008628aSNagadheeraj Rottela 520f008628aSNagadheeraj Rottela if (nb_ops > filled_slots) 521f008628aSNagadheeraj Rottela nb_ops = filled_slots; 522f008628aSNagadheeraj Rottela 523f008628aSNagadheeraj Rottela for (cnt = 0; cnt < nb_ops; cnt++) 524f008628aSNagadheeraj Rottela if (nitrox_deq_single_op(qp, &ops[cnt])) 525f008628aSNagadheeraj Rottela break; 526f008628aSNagadheeraj Rottela 527f008628aSNagadheeraj Rottela return cnt; 528f008628aSNagadheeraj Rottela } 529f008628aSNagadheeraj Rottela 530b4ce3594SNagadheeraj Rottela static struct rte_compressdev_ops nitrox_compressdev_ops = { 531b4ce3594SNagadheeraj Rottela .dev_configure = nitrox_comp_dev_configure, 532b4ce3594SNagadheeraj Rottela .dev_start = nitrox_comp_dev_start, 533b4ce3594SNagadheeraj Rottela .dev_stop = nitrox_comp_dev_stop, 534b4ce3594SNagadheeraj Rottela .dev_close = nitrox_comp_dev_close, 535b4ce3594SNagadheeraj Rottela 536b4ce3594SNagadheeraj Rottela .stats_get = nitrox_comp_stats_get, 537b4ce3594SNagadheeraj Rottela .stats_reset = nitrox_comp_stats_reset, 538b4ce3594SNagadheeraj Rottela 539b4ce3594SNagadheeraj Rottela .dev_infos_get = nitrox_comp_dev_info_get, 540b4ce3594SNagadheeraj Rottela 541b4ce3594SNagadheeraj Rottela .queue_pair_setup = nitrox_comp_queue_pair_setup, 542b4ce3594SNagadheeraj Rottela .queue_pair_release = nitrox_comp_queue_pair_release, 543b4ce3594SNagadheeraj Rottela 544b4ce3594SNagadheeraj Rottela .private_xform_create = nitrox_comp_private_xform_create, 545b4ce3594SNagadheeraj Rottela .private_xform_free = nitrox_comp_private_xform_free, 5466ea6bcddSNagadheeraj Rottela .stream_create = nitrox_comp_stream_create, 5476ea6bcddSNagadheeraj Rottela .stream_free = nitrox_comp_stream_free, 548b4ce3594SNagadheeraj Rottela }; 549b4ce3594SNagadheeraj Rottela 550b4ce3594SNagadheeraj Rottela int 551b4ce3594SNagadheeraj Rottela nitrox_comp_pmd_create(struct nitrox_device *ndev) 552b4ce3594SNagadheeraj Rottela { 553b4ce3594SNagadheeraj Rottela char name[RTE_COMPRESSDEV_NAME_MAX_LEN]; 554b4ce3594SNagadheeraj Rottela struct rte_compressdev_pmd_init_params init_params = { 555b4ce3594SNagadheeraj Rottela .name = "", 556b4ce3594SNagadheeraj Rottela .socket_id = ndev->pdev->device.numa_node, 557b4ce3594SNagadheeraj Rottela }; 558b4ce3594SNagadheeraj Rottela struct rte_compressdev *cdev; 559b4ce3594SNagadheeraj Rottela 560b4ce3594SNagadheeraj Rottela rte_pci_device_name(&ndev->pdev->addr, name, sizeof(name)); 561b4ce3594SNagadheeraj Rottela snprintf(name + strlen(name), 562b4ce3594SNagadheeraj Rottela RTE_COMPRESSDEV_NAME_MAX_LEN - strlen(name), 563b4ce3594SNagadheeraj Rottela "_n5comp"); 564b4ce3594SNagadheeraj Rottela ndev->rte_comp_dev.driver = &nitrox_rte_comp_drv; 565b4ce3594SNagadheeraj Rottela ndev->rte_comp_dev.numa_node = ndev->pdev->device.numa_node; 566b4ce3594SNagadheeraj Rottela ndev->rte_comp_dev.devargs = NULL; 567b4ce3594SNagadheeraj Rottela cdev = rte_compressdev_pmd_create(name, 568b4ce3594SNagadheeraj Rottela &ndev->rte_comp_dev, 569b4ce3594SNagadheeraj Rottela sizeof(struct nitrox_comp_device), 570b4ce3594SNagadheeraj Rottela &init_params); 571b4ce3594SNagadheeraj Rottela if (!cdev) { 572*e99981afSDavid Marchand NITROX_LOG_LINE(ERR, "Cryptodev '%s' creation failed", name); 573b4ce3594SNagadheeraj Rottela return -ENODEV; 574b4ce3594SNagadheeraj Rottela } 575b4ce3594SNagadheeraj Rottela 576b4ce3594SNagadheeraj Rottela cdev->dev_ops = &nitrox_compressdev_ops; 577b4ce3594SNagadheeraj Rottela cdev->enqueue_burst = nitrox_comp_dev_enq_burst; 578b4ce3594SNagadheeraj Rottela cdev->dequeue_burst = nitrox_comp_dev_deq_burst; 579b4ce3594SNagadheeraj Rottela cdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED; 580b4ce3594SNagadheeraj Rottela 581b4ce3594SNagadheeraj Rottela ndev->comp_dev = cdev->data->dev_private; 582b4ce3594SNagadheeraj Rottela ndev->comp_dev->cdev = cdev; 583b4ce3594SNagadheeraj Rottela ndev->comp_dev->ndev = ndev; 584b4ce3594SNagadheeraj Rottela ndev->comp_dev->xform_pool = NULL; 585*e99981afSDavid Marchand NITROX_LOG_LINE(DEBUG, "Created compressdev '%s', dev_id %d", 586b4ce3594SNagadheeraj Rottela cdev->data->name, cdev->data->dev_id); 587b4ce3594SNagadheeraj Rottela return 0; 588b4ce3594SNagadheeraj Rottela } 589b4ce3594SNagadheeraj Rottela 590b4ce3594SNagadheeraj Rottela int 591b4ce3594SNagadheeraj Rottela nitrox_comp_pmd_destroy(struct nitrox_device *ndev) 592b4ce3594SNagadheeraj Rottela { 593b4ce3594SNagadheeraj Rottela int err; 594b4ce3594SNagadheeraj Rottela 595b4ce3594SNagadheeraj Rottela if (ndev->comp_dev == NULL) 596b4ce3594SNagadheeraj Rottela return 0; 597b4ce3594SNagadheeraj Rottela 598b4ce3594SNagadheeraj Rottela err = rte_compressdev_pmd_destroy(ndev->comp_dev->cdev); 599b4ce3594SNagadheeraj Rottela if (err) 600b4ce3594SNagadheeraj Rottela return err; 601b4ce3594SNagadheeraj Rottela 602b4ce3594SNagadheeraj Rottela ndev->comp_dev = NULL; 603b4ce3594SNagadheeraj Rottela return 0; 604b4ce3594SNagadheeraj Rottela } 605