127422fc3SAshish Gupta /* SPDX-License-Identifier: BSD-3-Clause 227422fc3SAshish Gupta * Copyright(c) 2018 Cavium Networks 327422fc3SAshish Gupta */ 427422fc3SAshish Gupta 527422fc3SAshish Gupta #include <string.h> 627422fc3SAshish Gupta 727422fc3SAshish Gupta #include <rte_common.h> 827422fc3SAshish Gupta #include <rte_malloc.h> 927422fc3SAshish Gupta 1027422fc3SAshish Gupta #include "zlib_pmd_private.h" 1127422fc3SAshish Gupta 1227422fc3SAshish Gupta static const struct rte_compressdev_capabilities zlib_pmd_capabilities[] = { 1327422fc3SAshish Gupta { /* Deflate */ 1427422fc3SAshish Gupta .algo = RTE_COMP_ALGO_DEFLATE, 1527422fc3SAshish Gupta .comp_feature_flags = (RTE_COMP_FF_NONCOMPRESSED_BLOCKS | 1627422fc3SAshish Gupta RTE_COMP_FF_HUFFMAN_FIXED | 1727422fc3SAshish Gupta RTE_COMP_FF_HUFFMAN_DYNAMIC), 1827422fc3SAshish Gupta .window_size = { 1927422fc3SAshish Gupta .min = 8, 2027422fc3SAshish Gupta .max = 15, 2127422fc3SAshish Gupta .increment = 1 2227422fc3SAshish Gupta }, 2327422fc3SAshish Gupta }, 2427422fc3SAshish Gupta 2527422fc3SAshish Gupta RTE_COMP_END_OF_CAPABILITIES_LIST() 2627422fc3SAshish Gupta 2727422fc3SAshish Gupta }; 2827422fc3SAshish Gupta 2927422fc3SAshish Gupta /** Configure device */ 3027422fc3SAshish Gupta static int 3127422fc3SAshish Gupta zlib_pmd_config(struct rte_compressdev *dev, 3227422fc3SAshish Gupta struct rte_compressdev_config *config) 3327422fc3SAshish Gupta { 3427422fc3SAshish Gupta struct rte_mempool *mp; 3527422fc3SAshish Gupta char mp_name[RTE_MEMPOOL_NAMESIZE]; 3627422fc3SAshish Gupta struct zlib_private *internals = dev->data->dev_private; 3727422fc3SAshish Gupta 3827422fc3SAshish Gupta snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, 3927422fc3SAshish Gupta "stream_mp_%u", dev->data->dev_id); 4027422fc3SAshish Gupta mp = internals->mp; 4127422fc3SAshish Gupta if (mp == NULL) { 4227422fc3SAshish Gupta mp = rte_mempool_create(mp_name, 4327422fc3SAshish Gupta config->max_nb_priv_xforms + 4427422fc3SAshish Gupta config->max_nb_streams, 4527422fc3SAshish Gupta sizeof(struct zlib_priv_xform), 4627422fc3SAshish Gupta 0, 0, NULL, NULL, NULL, 4727422fc3SAshish Gupta NULL, config->socket_id, 4827422fc3SAshish Gupta 0); 4927422fc3SAshish Gupta if (mp == NULL) { 5027422fc3SAshish Gupta ZLIB_PMD_ERR("Cannot create private xform pool on " 5127422fc3SAshish Gupta "socket %d\n", config->socket_id); 5227422fc3SAshish Gupta return -ENOMEM; 5327422fc3SAshish Gupta } 5427422fc3SAshish Gupta internals->mp = mp; 5527422fc3SAshish Gupta } 5627422fc3SAshish Gupta return 0; 5727422fc3SAshish Gupta } 5827422fc3SAshish Gupta 5927422fc3SAshish Gupta /** Start device */ 6027422fc3SAshish Gupta static int 6127422fc3SAshish Gupta zlib_pmd_start(__rte_unused struct rte_compressdev *dev) 6227422fc3SAshish Gupta { 6327422fc3SAshish Gupta return 0; 6427422fc3SAshish Gupta } 6527422fc3SAshish Gupta 6627422fc3SAshish Gupta /** Stop device */ 6727422fc3SAshish Gupta static void 6827422fc3SAshish Gupta zlib_pmd_stop(__rte_unused struct rte_compressdev *dev) 6927422fc3SAshish Gupta { 7027422fc3SAshish Gupta } 7127422fc3SAshish Gupta 7227422fc3SAshish Gupta /** Close device */ 7327422fc3SAshish Gupta static int 7427422fc3SAshish Gupta zlib_pmd_close(struct rte_compressdev *dev) 7527422fc3SAshish Gupta { 7627422fc3SAshish Gupta struct zlib_private *internals = dev->data->dev_private; 7727422fc3SAshish Gupta rte_mempool_free(internals->mp); 7827422fc3SAshish Gupta internals->mp = NULL; 7927422fc3SAshish Gupta return 0; 8027422fc3SAshish Gupta } 8127422fc3SAshish Gupta 8227422fc3SAshish Gupta /** Get device statistics */ 8327422fc3SAshish Gupta static void 8427422fc3SAshish Gupta zlib_pmd_stats_get(struct rte_compressdev *dev, 8527422fc3SAshish Gupta struct rte_compressdev_stats *stats) 8627422fc3SAshish Gupta { 8727422fc3SAshish Gupta int qp_id; 8827422fc3SAshish Gupta 8927422fc3SAshish Gupta for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 9027422fc3SAshish Gupta struct zlib_qp *qp = dev->data->queue_pairs[qp_id]; 9127422fc3SAshish Gupta 9227422fc3SAshish Gupta stats->enqueued_count += qp->qp_stats.enqueued_count; 9327422fc3SAshish Gupta stats->dequeued_count += qp->qp_stats.dequeued_count; 9427422fc3SAshish Gupta 9527422fc3SAshish Gupta stats->enqueue_err_count += qp->qp_stats.enqueue_err_count; 9627422fc3SAshish Gupta stats->dequeue_err_count += qp->qp_stats.dequeue_err_count; 9727422fc3SAshish Gupta } 9827422fc3SAshish Gupta } 9927422fc3SAshish Gupta 10027422fc3SAshish Gupta /** Reset device statistics */ 10127422fc3SAshish Gupta static void 10227422fc3SAshish Gupta zlib_pmd_stats_reset(struct rte_compressdev *dev) 10327422fc3SAshish Gupta { 10427422fc3SAshish Gupta int qp_id; 10527422fc3SAshish Gupta 10627422fc3SAshish Gupta for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { 10727422fc3SAshish Gupta struct zlib_qp *qp = dev->data->queue_pairs[qp_id]; 10827422fc3SAshish Gupta 10927422fc3SAshish Gupta memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 11027422fc3SAshish Gupta } 11127422fc3SAshish Gupta } 11227422fc3SAshish Gupta 11327422fc3SAshish Gupta /** Get device info */ 11427422fc3SAshish Gupta static void 11527422fc3SAshish Gupta zlib_pmd_info_get(struct rte_compressdev *dev, 11627422fc3SAshish Gupta struct rte_compressdev_info *dev_info) 11727422fc3SAshish Gupta { 11827422fc3SAshish Gupta if (dev_info != NULL) { 11927422fc3SAshish Gupta dev_info->driver_name = dev->device->name; 12027422fc3SAshish Gupta dev_info->feature_flags = dev->feature_flags; 12127422fc3SAshish Gupta dev_info->capabilities = zlib_pmd_capabilities; 12227422fc3SAshish Gupta } 12327422fc3SAshish Gupta } 12427422fc3SAshish Gupta 12527422fc3SAshish Gupta /** Release queue pair */ 12627422fc3SAshish Gupta static int 12727422fc3SAshish Gupta zlib_pmd_qp_release(struct rte_compressdev *dev, uint16_t qp_id) 12827422fc3SAshish Gupta { 12927422fc3SAshish Gupta struct zlib_qp *qp = dev->data->queue_pairs[qp_id]; 13027422fc3SAshish Gupta 13127422fc3SAshish Gupta if (qp != NULL) { 13227422fc3SAshish Gupta rte_ring_free(qp->processed_pkts); 13327422fc3SAshish Gupta rte_free(qp); 13427422fc3SAshish Gupta dev->data->queue_pairs[qp_id] = NULL; 13527422fc3SAshish Gupta } 13627422fc3SAshish Gupta return 0; 13727422fc3SAshish Gupta } 13827422fc3SAshish Gupta 13927422fc3SAshish Gupta /** set a unique name for the queue pair based on its name, dev_id and qp_id */ 14027422fc3SAshish Gupta static int 14127422fc3SAshish Gupta zlib_pmd_qp_set_unique_name(struct rte_compressdev *dev, 14227422fc3SAshish Gupta struct zlib_qp *qp) 14327422fc3SAshish Gupta { 14427422fc3SAshish Gupta unsigned int n = snprintf(qp->name, sizeof(qp->name), 14527422fc3SAshish Gupta "zlib_pmd_%u_qp_%u", 14627422fc3SAshish Gupta dev->data->dev_id, qp->id); 14727422fc3SAshish Gupta 14827422fc3SAshish Gupta if (n >= sizeof(qp->name)) 14927422fc3SAshish Gupta return -1; 15027422fc3SAshish Gupta 15127422fc3SAshish Gupta return 0; 15227422fc3SAshish Gupta } 15327422fc3SAshish Gupta 15427422fc3SAshish Gupta /** Create a ring to place process packets on */ 15527422fc3SAshish Gupta static struct rte_ring * 15627422fc3SAshish Gupta zlib_pmd_qp_create_processed_pkts_ring(struct zlib_qp *qp, 15727422fc3SAshish Gupta unsigned int ring_size, int socket_id) 15827422fc3SAshish Gupta { 15927422fc3SAshish Gupta struct rte_ring *r = qp->processed_pkts; 16027422fc3SAshish Gupta 16127422fc3SAshish Gupta if (r) { 16227422fc3SAshish Gupta if (rte_ring_get_size(r) >= ring_size) { 16327422fc3SAshish Gupta ZLIB_PMD_INFO("Reusing existing ring %s for processed" 16427422fc3SAshish Gupta " packets", qp->name); 16527422fc3SAshish Gupta return r; 16627422fc3SAshish Gupta } 16727422fc3SAshish Gupta 16827422fc3SAshish Gupta ZLIB_PMD_ERR("Unable to reuse existing ring %s for processed" 16927422fc3SAshish Gupta " packets", qp->name); 17027422fc3SAshish Gupta return NULL; 17127422fc3SAshish Gupta } 17227422fc3SAshish Gupta 17327422fc3SAshish Gupta return rte_ring_create(qp->name, ring_size, socket_id, 17427422fc3SAshish Gupta RING_F_EXACT_SZ); 17527422fc3SAshish Gupta } 17627422fc3SAshish Gupta 17727422fc3SAshish Gupta /** Setup a queue pair */ 17827422fc3SAshish Gupta static int 17927422fc3SAshish Gupta zlib_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id, 18027422fc3SAshish Gupta uint32_t max_inflight_ops, int socket_id) 18127422fc3SAshish Gupta { 18227422fc3SAshish Gupta struct zlib_qp *qp = NULL; 18327422fc3SAshish Gupta 18427422fc3SAshish Gupta /* Free memory prior to re-allocation if needed. */ 18527422fc3SAshish Gupta if (dev->data->queue_pairs[qp_id] != NULL) 18627422fc3SAshish Gupta zlib_pmd_qp_release(dev, qp_id); 18727422fc3SAshish Gupta 18827422fc3SAshish Gupta /* Allocate the queue pair data structure. */ 18927422fc3SAshish Gupta qp = rte_zmalloc_socket("ZLIB PMD Queue Pair", sizeof(*qp), 19027422fc3SAshish Gupta RTE_CACHE_LINE_SIZE, socket_id); 19127422fc3SAshish Gupta if (qp == NULL) 19227422fc3SAshish Gupta return (-ENOMEM); 19327422fc3SAshish Gupta 19427422fc3SAshish Gupta qp->id = qp_id; 19527422fc3SAshish Gupta dev->data->queue_pairs[qp_id] = qp; 19627422fc3SAshish Gupta 19727422fc3SAshish Gupta if (zlib_pmd_qp_set_unique_name(dev, qp)) 19827422fc3SAshish Gupta goto qp_setup_cleanup; 19927422fc3SAshish Gupta 20027422fc3SAshish Gupta qp->processed_pkts = zlib_pmd_qp_create_processed_pkts_ring(qp, 20127422fc3SAshish Gupta max_inflight_ops, socket_id); 20227422fc3SAshish Gupta if (qp->processed_pkts == NULL) 20327422fc3SAshish Gupta goto qp_setup_cleanup; 20427422fc3SAshish Gupta 20527422fc3SAshish Gupta memset(&qp->qp_stats, 0, sizeof(qp->qp_stats)); 20627422fc3SAshish Gupta return 0; 20727422fc3SAshish Gupta 20827422fc3SAshish Gupta qp_setup_cleanup: 20927422fc3SAshish Gupta if (qp) { 21027422fc3SAshish Gupta rte_free(qp); 21127422fc3SAshish Gupta qp = NULL; 21227422fc3SAshish Gupta } 21327422fc3SAshish Gupta return -1; 21427422fc3SAshish Gupta } 21527422fc3SAshish Gupta 216*0cc20d33SSunila Sahu /** Configure stream */ 217*0cc20d33SSunila Sahu static int 218*0cc20d33SSunila Sahu zlib_pmd_stream_create(struct rte_compressdev *dev, 219*0cc20d33SSunila Sahu const struct rte_comp_xform *xform, 220*0cc20d33SSunila Sahu void **zstream) 221*0cc20d33SSunila Sahu { 222*0cc20d33SSunila Sahu int ret = 0; 223*0cc20d33SSunila Sahu struct zlib_stream *stream; 224*0cc20d33SSunila Sahu struct zlib_private *internals = dev->data->dev_private; 225*0cc20d33SSunila Sahu 226*0cc20d33SSunila Sahu if (xform == NULL) { 227*0cc20d33SSunila Sahu ZLIB_PMD_ERR("invalid xform struct"); 228*0cc20d33SSunila Sahu return -EINVAL; 229*0cc20d33SSunila Sahu } 230*0cc20d33SSunila Sahu 231*0cc20d33SSunila Sahu if (rte_mempool_get(internals->mp, zstream)) { 232*0cc20d33SSunila Sahu ZLIB_PMD_ERR("Couldn't get object from session mempool"); 233*0cc20d33SSunila Sahu return -ENOMEM; 234*0cc20d33SSunila Sahu } 235*0cc20d33SSunila Sahu stream = *((struct zlib_stream **)zstream); 236*0cc20d33SSunila Sahu 237*0cc20d33SSunila Sahu ret = zlib_set_stream_parameters(xform, stream); 238*0cc20d33SSunila Sahu 239*0cc20d33SSunila Sahu if (ret < 0) { 240*0cc20d33SSunila Sahu ZLIB_PMD_ERR("failed configure session parameters"); 241*0cc20d33SSunila Sahu 242*0cc20d33SSunila Sahu memset(stream, 0, sizeof(struct zlib_stream)); 243*0cc20d33SSunila Sahu /* Return session to mempool */ 244*0cc20d33SSunila Sahu rte_mempool_put(internals->mp, stream); 245*0cc20d33SSunila Sahu return ret; 246*0cc20d33SSunila Sahu } 247*0cc20d33SSunila Sahu 248*0cc20d33SSunila Sahu return 0; 249*0cc20d33SSunila Sahu } 250*0cc20d33SSunila Sahu 251*0cc20d33SSunila Sahu /** Configure private xform */ 252*0cc20d33SSunila Sahu static int 253*0cc20d33SSunila Sahu zlib_pmd_private_xform_create(struct rte_compressdev *dev, 254*0cc20d33SSunila Sahu const struct rte_comp_xform *xform, 255*0cc20d33SSunila Sahu void **private_xform) 256*0cc20d33SSunila Sahu { 257*0cc20d33SSunila Sahu return zlib_pmd_stream_create(dev, xform, private_xform); 258*0cc20d33SSunila Sahu } 259*0cc20d33SSunila Sahu 260*0cc20d33SSunila Sahu /** Clear the memory of stream so it doesn't leave key material behind */ 261*0cc20d33SSunila Sahu static int 262*0cc20d33SSunila Sahu zlib_pmd_stream_free(__rte_unused struct rte_compressdev *dev, 263*0cc20d33SSunila Sahu void *zstream) 264*0cc20d33SSunila Sahu { 265*0cc20d33SSunila Sahu struct zlib_stream *stream = (struct zlib_stream *)zstream; 266*0cc20d33SSunila Sahu if (!stream) 267*0cc20d33SSunila Sahu return -EINVAL; 268*0cc20d33SSunila Sahu 269*0cc20d33SSunila Sahu stream->free(&stream->strm); 270*0cc20d33SSunila Sahu /* Zero out the whole structure */ 271*0cc20d33SSunila Sahu memset(stream, 0, sizeof(struct zlib_stream)); 272*0cc20d33SSunila Sahu struct rte_mempool *mp = rte_mempool_from_obj(stream); 273*0cc20d33SSunila Sahu rte_mempool_put(mp, stream); 274*0cc20d33SSunila Sahu 275*0cc20d33SSunila Sahu return 0; 276*0cc20d33SSunila Sahu } 277*0cc20d33SSunila Sahu 278*0cc20d33SSunila Sahu /** Clear the memory of stream so it doesn't leave key material behind */ 279*0cc20d33SSunila Sahu static int 280*0cc20d33SSunila Sahu zlib_pmd_private_xform_free(struct rte_compressdev *dev, 281*0cc20d33SSunila Sahu void *private_xform) 282*0cc20d33SSunila Sahu { 283*0cc20d33SSunila Sahu return zlib_pmd_stream_free(dev, private_xform); 284*0cc20d33SSunila Sahu } 285*0cc20d33SSunila Sahu 28627422fc3SAshish Gupta struct rte_compressdev_ops zlib_pmd_ops = { 28727422fc3SAshish Gupta .dev_configure = zlib_pmd_config, 28827422fc3SAshish Gupta .dev_start = zlib_pmd_start, 28927422fc3SAshish Gupta .dev_stop = zlib_pmd_stop, 29027422fc3SAshish Gupta .dev_close = zlib_pmd_close, 29127422fc3SAshish Gupta 29227422fc3SAshish Gupta .stats_get = zlib_pmd_stats_get, 29327422fc3SAshish Gupta .stats_reset = zlib_pmd_stats_reset, 29427422fc3SAshish Gupta 29527422fc3SAshish Gupta .dev_infos_get = zlib_pmd_info_get, 29627422fc3SAshish Gupta 29727422fc3SAshish Gupta .queue_pair_setup = zlib_pmd_qp_setup, 29827422fc3SAshish Gupta .queue_pair_release = zlib_pmd_qp_release, 29927422fc3SAshish Gupta 300*0cc20d33SSunila Sahu .private_xform_create = zlib_pmd_private_xform_create, 301*0cc20d33SSunila Sahu .private_xform_free = zlib_pmd_private_xform_free, 30227422fc3SAshish Gupta 30327422fc3SAshish Gupta .stream_create = NULL, 30427422fc3SAshish Gupta .stream_free = NULL 30527422fc3SAshish Gupta }; 30627422fc3SAshish Gupta 30727422fc3SAshish Gupta struct rte_compressdev_ops *rte_zlib_pmd_ops = &zlib_pmd_ops; 308