xref: /dpdk/drivers/compress/zlib/zlib_pmd_ops.c (revision f665790a5dbad7b645ff46f31d65e977324e7bfc)
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 
71acb7f54SDavid Marchand #include <dev_driver.h>
827422fc3SAshish Gupta #include <rte_common.h>
927422fc3SAshish Gupta #include <rte_malloc.h>
1027422fc3SAshish Gupta 
1127422fc3SAshish Gupta #include "zlib_pmd_private.h"
1227422fc3SAshish Gupta 
1327422fc3SAshish Gupta static const struct rte_compressdev_capabilities zlib_pmd_capabilities[] = {
1427422fc3SAshish Gupta 	{   /* Deflate */
1527422fc3SAshish Gupta 		.algo = RTE_COMP_ALGO_DEFLATE,
1627422fc3SAshish Gupta 		.comp_feature_flags = (RTE_COMP_FF_NONCOMPRESSED_BLOCKS |
1727422fc3SAshish Gupta 					RTE_COMP_FF_HUFFMAN_FIXED |
1827422fc3SAshish Gupta 					RTE_COMP_FF_HUFFMAN_DYNAMIC),
1927422fc3SAshish Gupta 		.window_size = {
2027422fc3SAshish Gupta 			.min = 8,
2127422fc3SAshish Gupta 			.max = 15,
2227422fc3SAshish Gupta 			.increment = 1
2327422fc3SAshish Gupta 		},
2427422fc3SAshish Gupta 	},
2527422fc3SAshish Gupta 
2627422fc3SAshish Gupta 	RTE_COMP_END_OF_CAPABILITIES_LIST()
2727422fc3SAshish Gupta 
2827422fc3SAshish Gupta };
2927422fc3SAshish Gupta 
3027422fc3SAshish Gupta /** Configure device */
3127422fc3SAshish Gupta static int
3227422fc3SAshish Gupta zlib_pmd_config(struct rte_compressdev *dev,
3327422fc3SAshish Gupta 		struct rte_compressdev_config *config)
3427422fc3SAshish Gupta {
3527422fc3SAshish Gupta 	struct rte_mempool *mp;
3627422fc3SAshish Gupta 	char mp_name[RTE_MEMPOOL_NAMESIZE];
3727422fc3SAshish Gupta 	struct zlib_private *internals = dev->data->dev_private;
3827422fc3SAshish Gupta 
3927422fc3SAshish Gupta 	snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
4027422fc3SAshish Gupta 			"stream_mp_%u", dev->data->dev_id);
4127422fc3SAshish Gupta 	mp = internals->mp;
4227422fc3SAshish Gupta 	if (mp == NULL) {
4327422fc3SAshish Gupta 		mp = rte_mempool_create(mp_name,
4427422fc3SAshish Gupta 				config->max_nb_priv_xforms +
4527422fc3SAshish Gupta 				config->max_nb_streams,
4627422fc3SAshish Gupta 				sizeof(struct zlib_priv_xform),
4727422fc3SAshish Gupta 				0, 0, NULL, NULL, NULL,
4827422fc3SAshish Gupta 				NULL, config->socket_id,
4927422fc3SAshish Gupta 				0);
5027422fc3SAshish Gupta 		if (mp == NULL) {
51*f665790aSDavid Marchand 			ZLIB_PMD_ERR("Cannot create private xform pool on socket %d",
52*f665790aSDavid Marchand 				config->socket_id);
5327422fc3SAshish Gupta 			return -ENOMEM;
5427422fc3SAshish Gupta 		}
5527422fc3SAshish Gupta 		internals->mp = mp;
5627422fc3SAshish Gupta 	}
5727422fc3SAshish Gupta 	return 0;
5827422fc3SAshish Gupta }
5927422fc3SAshish Gupta 
6027422fc3SAshish Gupta /** Start device */
6127422fc3SAshish Gupta static int
6227422fc3SAshish Gupta zlib_pmd_start(__rte_unused struct rte_compressdev *dev)
6327422fc3SAshish Gupta {
6427422fc3SAshish Gupta 	return 0;
6527422fc3SAshish Gupta }
6627422fc3SAshish Gupta 
6727422fc3SAshish Gupta /** Stop device */
6827422fc3SAshish Gupta static void
6927422fc3SAshish Gupta zlib_pmd_stop(__rte_unused struct rte_compressdev *dev)
7027422fc3SAshish Gupta {
7127422fc3SAshish Gupta }
7227422fc3SAshish Gupta 
7327422fc3SAshish Gupta /** Close device */
7427422fc3SAshish Gupta static int
7527422fc3SAshish Gupta zlib_pmd_close(struct rte_compressdev *dev)
7627422fc3SAshish Gupta {
7727422fc3SAshish Gupta 	struct zlib_private *internals = dev->data->dev_private;
7827422fc3SAshish Gupta 	rte_mempool_free(internals->mp);
7927422fc3SAshish Gupta 	internals->mp = NULL;
8027422fc3SAshish Gupta 	return 0;
8127422fc3SAshish Gupta }
8227422fc3SAshish Gupta 
8327422fc3SAshish Gupta /** Get device statistics */
8427422fc3SAshish Gupta static void
8527422fc3SAshish Gupta zlib_pmd_stats_get(struct rte_compressdev *dev,
8627422fc3SAshish Gupta 		struct rte_compressdev_stats *stats)
8727422fc3SAshish Gupta {
8827422fc3SAshish Gupta 	int qp_id;
8927422fc3SAshish Gupta 
9027422fc3SAshish Gupta 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
9127422fc3SAshish Gupta 		struct zlib_qp *qp = dev->data->queue_pairs[qp_id];
9227422fc3SAshish Gupta 
9327422fc3SAshish Gupta 		stats->enqueued_count += qp->qp_stats.enqueued_count;
9427422fc3SAshish Gupta 		stats->dequeued_count += qp->qp_stats.dequeued_count;
9527422fc3SAshish Gupta 
9627422fc3SAshish Gupta 		stats->enqueue_err_count += qp->qp_stats.enqueue_err_count;
9727422fc3SAshish Gupta 		stats->dequeue_err_count += qp->qp_stats.dequeue_err_count;
9827422fc3SAshish Gupta 	}
9927422fc3SAshish Gupta }
10027422fc3SAshish Gupta 
10127422fc3SAshish Gupta /** Reset device statistics */
10227422fc3SAshish Gupta static void
10327422fc3SAshish Gupta zlib_pmd_stats_reset(struct rte_compressdev *dev)
10427422fc3SAshish Gupta {
10527422fc3SAshish Gupta 	int qp_id;
10627422fc3SAshish Gupta 
10727422fc3SAshish Gupta 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
10827422fc3SAshish Gupta 		struct zlib_qp *qp = dev->data->queue_pairs[qp_id];
10927422fc3SAshish Gupta 
11027422fc3SAshish Gupta 		memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
11127422fc3SAshish Gupta 	}
11227422fc3SAshish Gupta }
11327422fc3SAshish Gupta 
11427422fc3SAshish Gupta /** Get device info */
11527422fc3SAshish Gupta static void
11627422fc3SAshish Gupta zlib_pmd_info_get(struct rte_compressdev *dev,
11727422fc3SAshish Gupta 		struct rte_compressdev_info *dev_info)
11827422fc3SAshish Gupta {
11927422fc3SAshish Gupta 	if (dev_info != NULL) {
12027422fc3SAshish Gupta 		dev_info->driver_name = dev->device->name;
12127422fc3SAshish Gupta 		dev_info->feature_flags = dev->feature_flags;
12227422fc3SAshish Gupta 		dev_info->capabilities = zlib_pmd_capabilities;
12327422fc3SAshish Gupta 	}
12427422fc3SAshish Gupta }
12527422fc3SAshish Gupta 
12627422fc3SAshish Gupta /** Release queue pair */
12727422fc3SAshish Gupta static int
12827422fc3SAshish Gupta zlib_pmd_qp_release(struct rte_compressdev *dev, uint16_t qp_id)
12927422fc3SAshish Gupta {
13027422fc3SAshish Gupta 	struct zlib_qp *qp = dev->data->queue_pairs[qp_id];
13127422fc3SAshish Gupta 
13227422fc3SAshish Gupta 	if (qp != NULL) {
13327422fc3SAshish Gupta 		rte_ring_free(qp->processed_pkts);
13427422fc3SAshish Gupta 		rte_free(qp);
13527422fc3SAshish Gupta 		dev->data->queue_pairs[qp_id] = NULL;
13627422fc3SAshish Gupta 	}
13727422fc3SAshish Gupta 	return 0;
13827422fc3SAshish Gupta }
13927422fc3SAshish Gupta 
14027422fc3SAshish Gupta /** set a unique name for the queue pair based on its name, dev_id and qp_id */
14127422fc3SAshish Gupta static int
14227422fc3SAshish Gupta zlib_pmd_qp_set_unique_name(struct rte_compressdev *dev,
14327422fc3SAshish Gupta 		struct zlib_qp *qp)
14427422fc3SAshish Gupta {
14527422fc3SAshish Gupta 	unsigned int n = snprintf(qp->name, sizeof(qp->name),
14627422fc3SAshish Gupta 				"zlib_pmd_%u_qp_%u",
14727422fc3SAshish Gupta 				dev->data->dev_id, qp->id);
14827422fc3SAshish Gupta 
14927422fc3SAshish Gupta 	if (n >= sizeof(qp->name))
15027422fc3SAshish Gupta 		return -1;
15127422fc3SAshish Gupta 
15227422fc3SAshish Gupta 	return 0;
15327422fc3SAshish Gupta }
15427422fc3SAshish Gupta 
15527422fc3SAshish Gupta /** Create a ring to place process packets on */
15627422fc3SAshish Gupta static struct rte_ring *
15727422fc3SAshish Gupta zlib_pmd_qp_create_processed_pkts_ring(struct zlib_qp *qp,
15827422fc3SAshish Gupta 		unsigned int ring_size, int socket_id)
15927422fc3SAshish Gupta {
16027422fc3SAshish Gupta 	struct rte_ring *r = qp->processed_pkts;
16127422fc3SAshish Gupta 
16227422fc3SAshish Gupta 	if (r) {
16327422fc3SAshish Gupta 		if (rte_ring_get_size(r) >= ring_size) {
16427422fc3SAshish Gupta 			ZLIB_PMD_INFO("Reusing existing ring %s for processed"
16527422fc3SAshish Gupta 					" packets", qp->name);
16627422fc3SAshish Gupta 			return r;
16727422fc3SAshish Gupta 		}
16827422fc3SAshish Gupta 
16927422fc3SAshish Gupta 		ZLIB_PMD_ERR("Unable to reuse existing ring %s for processed"
17027422fc3SAshish Gupta 				" packets", qp->name);
17127422fc3SAshish Gupta 		return NULL;
17227422fc3SAshish Gupta 	}
17327422fc3SAshish Gupta 
17427422fc3SAshish Gupta 	return rte_ring_create(qp->name, ring_size, socket_id,
17527422fc3SAshish Gupta 						RING_F_EXACT_SZ);
17627422fc3SAshish Gupta }
17727422fc3SAshish Gupta 
17827422fc3SAshish Gupta /** Setup a queue pair */
17927422fc3SAshish Gupta static int
18027422fc3SAshish Gupta zlib_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
18127422fc3SAshish Gupta 		uint32_t max_inflight_ops, int socket_id)
18227422fc3SAshish Gupta {
18327422fc3SAshish Gupta 	struct zlib_qp *qp = NULL;
18427422fc3SAshish Gupta 
18527422fc3SAshish Gupta 	/* Free memory prior to re-allocation if needed. */
18627422fc3SAshish Gupta 	if (dev->data->queue_pairs[qp_id] != NULL)
18727422fc3SAshish Gupta 		zlib_pmd_qp_release(dev, qp_id);
18827422fc3SAshish Gupta 
18927422fc3SAshish Gupta 	/* Allocate the queue pair data structure. */
19027422fc3SAshish Gupta 	qp = rte_zmalloc_socket("ZLIB PMD Queue Pair", sizeof(*qp),
19127422fc3SAshish Gupta 					RTE_CACHE_LINE_SIZE, socket_id);
19227422fc3SAshish Gupta 	if (qp == NULL)
19327422fc3SAshish Gupta 		return (-ENOMEM);
19427422fc3SAshish Gupta 
19527422fc3SAshish Gupta 	qp->id = qp_id;
19627422fc3SAshish Gupta 	dev->data->queue_pairs[qp_id] = qp;
19727422fc3SAshish Gupta 
19827422fc3SAshish Gupta 	if (zlib_pmd_qp_set_unique_name(dev, qp))
19927422fc3SAshish Gupta 		goto qp_setup_cleanup;
20027422fc3SAshish Gupta 
20127422fc3SAshish Gupta 	qp->processed_pkts = zlib_pmd_qp_create_processed_pkts_ring(qp,
20227422fc3SAshish Gupta 			max_inflight_ops, socket_id);
20327422fc3SAshish Gupta 	if (qp->processed_pkts == NULL)
20427422fc3SAshish Gupta 		goto qp_setup_cleanup;
20527422fc3SAshish Gupta 
20627422fc3SAshish Gupta 	memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
20727422fc3SAshish Gupta 	return 0;
20827422fc3SAshish Gupta 
20927422fc3SAshish Gupta qp_setup_cleanup:
21027422fc3SAshish Gupta 	if (qp) {
21127422fc3SAshish Gupta 		rte_free(qp);
21227422fc3SAshish Gupta 		qp = NULL;
21327422fc3SAshish Gupta 	}
21427422fc3SAshish Gupta 	return -1;
21527422fc3SAshish Gupta }
21627422fc3SAshish Gupta 
2170cc20d33SSunila Sahu /** Configure stream */
2180cc20d33SSunila Sahu static int
2190cc20d33SSunila Sahu zlib_pmd_stream_create(struct rte_compressdev *dev,
2200cc20d33SSunila Sahu 		const struct rte_comp_xform *xform,
2210cc20d33SSunila Sahu 		void **zstream)
2220cc20d33SSunila Sahu {
2230cc20d33SSunila Sahu 	int ret = 0;
2240cc20d33SSunila Sahu 	struct zlib_stream *stream;
2250cc20d33SSunila Sahu 	struct zlib_private *internals = dev->data->dev_private;
2260cc20d33SSunila Sahu 
2270cc20d33SSunila Sahu 	if (xform == NULL) {
2280cc20d33SSunila Sahu 		ZLIB_PMD_ERR("invalid xform struct");
2290cc20d33SSunila Sahu 		return -EINVAL;
2300cc20d33SSunila Sahu 	}
2310cc20d33SSunila Sahu 
2320cc20d33SSunila Sahu 	if (rte_mempool_get(internals->mp, zstream)) {
2330cc20d33SSunila Sahu 		ZLIB_PMD_ERR("Couldn't get object from session mempool");
2340cc20d33SSunila Sahu 		return -ENOMEM;
2350cc20d33SSunila Sahu 	}
2360cc20d33SSunila Sahu 	stream = *((struct zlib_stream **)zstream);
2370cc20d33SSunila Sahu 
2380cc20d33SSunila Sahu 	ret = zlib_set_stream_parameters(xform, stream);
2390cc20d33SSunila Sahu 
2400cc20d33SSunila Sahu 	if (ret < 0) {
2410cc20d33SSunila Sahu 		ZLIB_PMD_ERR("failed configure session parameters");
2420cc20d33SSunila Sahu 
2430cc20d33SSunila Sahu 		memset(stream, 0, sizeof(struct zlib_stream));
2440cc20d33SSunila Sahu 		/* Return session to mempool */
2450cc20d33SSunila Sahu 		rte_mempool_put(internals->mp, stream);
2460cc20d33SSunila Sahu 		return ret;
2470cc20d33SSunila Sahu 	}
2480cc20d33SSunila Sahu 
2490cc20d33SSunila Sahu 	return 0;
2500cc20d33SSunila Sahu }
2510cc20d33SSunila Sahu 
2520cc20d33SSunila Sahu /** Configure private xform */
2530cc20d33SSunila Sahu static int
2540cc20d33SSunila Sahu zlib_pmd_private_xform_create(struct rte_compressdev *dev,
2550cc20d33SSunila Sahu 		const struct rte_comp_xform *xform,
2560cc20d33SSunila Sahu 		void **private_xform)
2570cc20d33SSunila Sahu {
2580cc20d33SSunila Sahu 	return zlib_pmd_stream_create(dev, xform, private_xform);
2590cc20d33SSunila Sahu }
2600cc20d33SSunila Sahu 
2610cc20d33SSunila Sahu /** Clear the memory of stream so it doesn't leave key material behind */
2620cc20d33SSunila Sahu static int
2630cc20d33SSunila Sahu zlib_pmd_stream_free(__rte_unused struct rte_compressdev *dev,
2640cc20d33SSunila Sahu 		void *zstream)
2650cc20d33SSunila Sahu {
2660cc20d33SSunila Sahu 	struct zlib_stream *stream = (struct zlib_stream *)zstream;
2670cc20d33SSunila Sahu 	if (!stream)
2680cc20d33SSunila Sahu 		return -EINVAL;
2690cc20d33SSunila Sahu 
2700cc20d33SSunila Sahu 	stream->free(&stream->strm);
2710cc20d33SSunila Sahu 	/* Zero out the whole structure */
2720cc20d33SSunila Sahu 	memset(stream, 0, sizeof(struct zlib_stream));
2730cc20d33SSunila Sahu 	struct rte_mempool *mp = rte_mempool_from_obj(stream);
2740cc20d33SSunila Sahu 	rte_mempool_put(mp, stream);
2750cc20d33SSunila Sahu 
2760cc20d33SSunila Sahu 	return 0;
2770cc20d33SSunila Sahu }
2780cc20d33SSunila Sahu 
2790cc20d33SSunila Sahu /** Clear the memory of stream so it doesn't leave key material behind */
2800cc20d33SSunila Sahu static int
2810cc20d33SSunila Sahu zlib_pmd_private_xform_free(struct rte_compressdev *dev,
2820cc20d33SSunila Sahu 		void *private_xform)
2830cc20d33SSunila Sahu {
2840cc20d33SSunila Sahu 	return zlib_pmd_stream_free(dev, private_xform);
2850cc20d33SSunila Sahu }
2860cc20d33SSunila Sahu 
28727422fc3SAshish Gupta struct rte_compressdev_ops zlib_pmd_ops = {
28827422fc3SAshish Gupta 		.dev_configure		= zlib_pmd_config,
28927422fc3SAshish Gupta 		.dev_start		= zlib_pmd_start,
29027422fc3SAshish Gupta 		.dev_stop		= zlib_pmd_stop,
29127422fc3SAshish Gupta 		.dev_close		= zlib_pmd_close,
29227422fc3SAshish Gupta 
29327422fc3SAshish Gupta 		.stats_get		= zlib_pmd_stats_get,
29427422fc3SAshish Gupta 		.stats_reset		= zlib_pmd_stats_reset,
29527422fc3SAshish Gupta 
29627422fc3SAshish Gupta 		.dev_infos_get		= zlib_pmd_info_get,
29727422fc3SAshish Gupta 
29827422fc3SAshish Gupta 		.queue_pair_setup	= zlib_pmd_qp_setup,
29927422fc3SAshish Gupta 		.queue_pair_release	= zlib_pmd_qp_release,
30027422fc3SAshish Gupta 
3010cc20d33SSunila Sahu 		.private_xform_create	= zlib_pmd_private_xform_create,
3020cc20d33SSunila Sahu 		.private_xform_free	= zlib_pmd_private_xform_free,
30327422fc3SAshish Gupta 
30427422fc3SAshish Gupta 		.stream_create	= NULL,
30527422fc3SAshish Gupta 		.stream_free	= NULL
30627422fc3SAshish Gupta };
30727422fc3SAshish Gupta 
30827422fc3SAshish Gupta struct rte_compressdev_ops *rte_zlib_pmd_ops = &zlib_pmd_ops;
309