xref: /dpdk/drivers/compress/zlib/zlib_pmd_ops.c (revision 0cc20d33ac0606887a6dcc78c3687ce3a33e636c)
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