xref: /dpdk/drivers/compress/zlib/zlib_pmd.c (revision c7b436ec95fd98913a572c438517c7fd7bbbc4de)
10c4e4c16SAshish Gupta /* SPDX-License-Identifier: BSD-3-Clause
20c4e4c16SAshish Gupta  * Copyright(c) 2018 Cavium Networks
30c4e4c16SAshish Gupta  */
40c4e4c16SAshish Gupta 
50c4e4c16SAshish Gupta #include <rte_bus_vdev.h>
60c4e4c16SAshish Gupta #include <rte_common.h>
70c4e4c16SAshish Gupta 
80c4e4c16SAshish Gupta #include "zlib_pmd_private.h"
90c4e4c16SAshish Gupta 
10*c7b436ecSSunila Sahu /** Compute next mbuf in the list, assign data buffer and length,
11*c7b436ecSSunila Sahu  *  returns 0 if mbuf is NULL
12*c7b436ecSSunila Sahu  */
13*c7b436ecSSunila Sahu #define COMPUTE_BUF(mbuf, data, len)		\
14*c7b436ecSSunila Sahu 		((mbuf = mbuf->next) ?		\
15*c7b436ecSSunila Sahu 		(data = rte_pktmbuf_mtod(mbuf, uint8_t *)),	\
16*c7b436ecSSunila Sahu 		(len = rte_pktmbuf_data_len(mbuf)) : 0)
17*c7b436ecSSunila Sahu 
18*c7b436ecSSunila Sahu static void
19*c7b436ecSSunila Sahu process_zlib_deflate(struct rte_comp_op *op, z_stream *strm)
20*c7b436ecSSunila Sahu {
21*c7b436ecSSunila Sahu 	int ret, flush, fin_flush;
22*c7b436ecSSunila Sahu 	struct rte_mbuf *mbuf_src = op->m_src;
23*c7b436ecSSunila Sahu 	struct rte_mbuf *mbuf_dst = op->m_dst;
24*c7b436ecSSunila Sahu 
25*c7b436ecSSunila Sahu 	switch (op->flush_flag) {
26*c7b436ecSSunila Sahu 	case RTE_COMP_FLUSH_FULL:
27*c7b436ecSSunila Sahu 	case RTE_COMP_FLUSH_FINAL:
28*c7b436ecSSunila Sahu 		fin_flush = Z_FINISH;
29*c7b436ecSSunila Sahu 		break;
30*c7b436ecSSunila Sahu 	default:
31*c7b436ecSSunila Sahu 		op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
32*c7b436ecSSunila Sahu 		ZLIB_PMD_ERR("Invalid flush value\n");
33*c7b436ecSSunila Sahu 	}
34*c7b436ecSSunila Sahu 
35*c7b436ecSSunila Sahu 	if (unlikely(!strm)) {
36*c7b436ecSSunila Sahu 		op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
37*c7b436ecSSunila Sahu 		ZLIB_PMD_ERR("Invalid z_stream\n");
38*c7b436ecSSunila Sahu 		return;
39*c7b436ecSSunila Sahu 	}
40*c7b436ecSSunila Sahu 	/* Update z_stream with the inputs provided by application */
41*c7b436ecSSunila Sahu 	strm->next_in = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
42*c7b436ecSSunila Sahu 			op->src.offset);
43*c7b436ecSSunila Sahu 
44*c7b436ecSSunila Sahu 	strm->avail_in = rte_pktmbuf_data_len(mbuf_src) - op->src.offset;
45*c7b436ecSSunila Sahu 
46*c7b436ecSSunila Sahu 	strm->next_out = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
47*c7b436ecSSunila Sahu 			op->dst.offset);
48*c7b436ecSSunila Sahu 
49*c7b436ecSSunila Sahu 	strm->avail_out = rte_pktmbuf_data_len(mbuf_dst) - op->dst.offset;
50*c7b436ecSSunila Sahu 
51*c7b436ecSSunila Sahu 	/* Set flush value to NO_FLUSH unless it is last mbuf */
52*c7b436ecSSunila Sahu 	flush = Z_NO_FLUSH;
53*c7b436ecSSunila Sahu 	/* Initialize status to SUCCESS */
54*c7b436ecSSunila Sahu 	op->status = RTE_COMP_OP_STATUS_SUCCESS;
55*c7b436ecSSunila Sahu 
56*c7b436ecSSunila Sahu 	do {
57*c7b436ecSSunila Sahu 		/* Set flush value to Z_FINISH for last block */
58*c7b436ecSSunila Sahu 		if ((op->src.length - strm->total_in) <= strm->avail_in) {
59*c7b436ecSSunila Sahu 			strm->avail_in = (op->src.length - strm->total_in);
60*c7b436ecSSunila Sahu 			flush = fin_flush;
61*c7b436ecSSunila Sahu 		}
62*c7b436ecSSunila Sahu 		do {
63*c7b436ecSSunila Sahu 			ret = deflate(strm, flush);
64*c7b436ecSSunila Sahu 			if (unlikely(ret == Z_STREAM_ERROR)) {
65*c7b436ecSSunila Sahu 				/* error return, do not process further */
66*c7b436ecSSunila Sahu 				op->status =  RTE_COMP_OP_STATUS_ERROR;
67*c7b436ecSSunila Sahu 				goto def_end;
68*c7b436ecSSunila Sahu 			}
69*c7b436ecSSunila Sahu 			/* Break if Z_STREAM_END is encountered */
70*c7b436ecSSunila Sahu 			if (ret == Z_STREAM_END)
71*c7b436ecSSunila Sahu 				goto def_end;
72*c7b436ecSSunila Sahu 
73*c7b436ecSSunila Sahu 		/* Keep looping until input mbuf is consumed.
74*c7b436ecSSunila Sahu 		 * Exit if destination mbuf gets exhausted.
75*c7b436ecSSunila Sahu 		 */
76*c7b436ecSSunila Sahu 		} while ((strm->avail_out == 0) &&
77*c7b436ecSSunila Sahu 			COMPUTE_BUF(mbuf_dst, strm->next_out, strm->avail_out));
78*c7b436ecSSunila Sahu 
79*c7b436ecSSunila Sahu 		if (!strm->avail_out) {
80*c7b436ecSSunila Sahu 			/* there is no space for compressed output */
81*c7b436ecSSunila Sahu 			op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
82*c7b436ecSSunila Sahu 			break;
83*c7b436ecSSunila Sahu 		}
84*c7b436ecSSunila Sahu 
85*c7b436ecSSunila Sahu 	/* Update source buffer to next mbuf
86*c7b436ecSSunila Sahu 	 * Exit if input buffers are fully consumed
87*c7b436ecSSunila Sahu 	 */
88*c7b436ecSSunila Sahu 	} while (COMPUTE_BUF(mbuf_src, strm->next_in, strm->avail_in));
89*c7b436ecSSunila Sahu 
90*c7b436ecSSunila Sahu def_end:
91*c7b436ecSSunila Sahu 	/* Update op stats */
92*c7b436ecSSunila Sahu 	switch (op->status) {
93*c7b436ecSSunila Sahu 	case RTE_COMP_OP_STATUS_SUCCESS:
94*c7b436ecSSunila Sahu 		op->consumed += strm->total_in;
95*c7b436ecSSunila Sahu 	/* Fall-through */
96*c7b436ecSSunila Sahu 	case RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED:
97*c7b436ecSSunila Sahu 		op->produced += strm->total_out;
98*c7b436ecSSunila Sahu 		break;
99*c7b436ecSSunila Sahu 	default:
100*c7b436ecSSunila Sahu 		ZLIB_PMD_ERR("stats not updated for status:%d\n",
101*c7b436ecSSunila Sahu 				op->status);
102*c7b436ecSSunila Sahu 	}
103*c7b436ecSSunila Sahu 
104*c7b436ecSSunila Sahu 	deflateReset(strm);
105*c7b436ecSSunila Sahu }
106*c7b436ecSSunila Sahu 
107*c7b436ecSSunila Sahu static void
108*c7b436ecSSunila Sahu process_zlib_inflate(struct rte_comp_op *op, z_stream *strm)
109*c7b436ecSSunila Sahu {
110*c7b436ecSSunila Sahu 	int ret, flush;
111*c7b436ecSSunila Sahu 	struct rte_mbuf *mbuf_src = op->m_src;
112*c7b436ecSSunila Sahu 	struct rte_mbuf *mbuf_dst = op->m_dst;
113*c7b436ecSSunila Sahu 
114*c7b436ecSSunila Sahu 	if (unlikely(!strm)) {
115*c7b436ecSSunila Sahu 		op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
116*c7b436ecSSunila Sahu 		ZLIB_PMD_ERR("Invalid z_stream\n");
117*c7b436ecSSunila Sahu 		return;
118*c7b436ecSSunila Sahu 	}
119*c7b436ecSSunila Sahu 	strm->next_in = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
120*c7b436ecSSunila Sahu 			op->src.offset);
121*c7b436ecSSunila Sahu 
122*c7b436ecSSunila Sahu 	strm->avail_in = rte_pktmbuf_data_len(mbuf_src) - op->src.offset;
123*c7b436ecSSunila Sahu 
124*c7b436ecSSunila Sahu 	strm->next_out = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
125*c7b436ecSSunila Sahu 			op->dst.offset);
126*c7b436ecSSunila Sahu 
127*c7b436ecSSunila Sahu 	strm->avail_out = rte_pktmbuf_data_len(mbuf_dst) - op->dst.offset;
128*c7b436ecSSunila Sahu 
129*c7b436ecSSunila Sahu 	/** Ignoring flush value provided from application for decompression */
130*c7b436ecSSunila Sahu 	flush = Z_NO_FLUSH;
131*c7b436ecSSunila Sahu 	/* initialize status to SUCCESS */
132*c7b436ecSSunila Sahu 	op->status = RTE_COMP_OP_STATUS_SUCCESS;
133*c7b436ecSSunila Sahu 
134*c7b436ecSSunila Sahu 	do {
135*c7b436ecSSunila Sahu 		do {
136*c7b436ecSSunila Sahu 			ret = inflate(strm, flush);
137*c7b436ecSSunila Sahu 
138*c7b436ecSSunila Sahu 			switch (ret) {
139*c7b436ecSSunila Sahu 			/* Fall-through */
140*c7b436ecSSunila Sahu 			case Z_NEED_DICT:
141*c7b436ecSSunila Sahu 				ret = Z_DATA_ERROR;
142*c7b436ecSSunila Sahu 			/* Fall-through */
143*c7b436ecSSunila Sahu 			case Z_DATA_ERROR:
144*c7b436ecSSunila Sahu 			/* Fall-through */
145*c7b436ecSSunila Sahu 			case Z_MEM_ERROR:
146*c7b436ecSSunila Sahu 			/* Fall-through */
147*c7b436ecSSunila Sahu 			case Z_STREAM_ERROR:
148*c7b436ecSSunila Sahu 				op->status = RTE_COMP_OP_STATUS_ERROR;
149*c7b436ecSSunila Sahu 			/* Fall-through */
150*c7b436ecSSunila Sahu 			case Z_STREAM_END:
151*c7b436ecSSunila Sahu 				/* no further computation needed if
152*c7b436ecSSunila Sahu 				 * Z_STREAM_END is encountered
153*c7b436ecSSunila Sahu 				 */
154*c7b436ecSSunila Sahu 				goto inf_end;
155*c7b436ecSSunila Sahu 			default:
156*c7b436ecSSunila Sahu 				/* success */
157*c7b436ecSSunila Sahu 				break;
158*c7b436ecSSunila Sahu 
159*c7b436ecSSunila Sahu 			}
160*c7b436ecSSunila Sahu 		/* Keep looping until input mbuf is consumed.
161*c7b436ecSSunila Sahu 		 * Exit if destination mbuf gets exhausted.
162*c7b436ecSSunila Sahu 		 */
163*c7b436ecSSunila Sahu 		} while ((strm->avail_out == 0) &&
164*c7b436ecSSunila Sahu 			COMPUTE_BUF(mbuf_dst, strm->next_out, strm->avail_out));
165*c7b436ecSSunila Sahu 
166*c7b436ecSSunila Sahu 		if (!strm->avail_out) {
167*c7b436ecSSunila Sahu 			/* there is no more space for decompressed output */
168*c7b436ecSSunila Sahu 			op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
169*c7b436ecSSunila Sahu 			break;
170*c7b436ecSSunila Sahu 		}
171*c7b436ecSSunila Sahu 	/* Read next input buffer to be processed, exit if compressed
172*c7b436ecSSunila Sahu 	 * blocks are fully read
173*c7b436ecSSunila Sahu 	 */
174*c7b436ecSSunila Sahu 	} while (COMPUTE_BUF(mbuf_src, strm->next_in, strm->avail_in));
175*c7b436ecSSunila Sahu 
176*c7b436ecSSunila Sahu inf_end:
177*c7b436ecSSunila Sahu 	/* Update op stats */
178*c7b436ecSSunila Sahu 	switch (op->status) {
179*c7b436ecSSunila Sahu 	case RTE_COMP_OP_STATUS_SUCCESS:
180*c7b436ecSSunila Sahu 		op->consumed += strm->total_in;
181*c7b436ecSSunila Sahu 	/* Fall-through */
182*c7b436ecSSunila Sahu 	case RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED:
183*c7b436ecSSunila Sahu 		op->produced += strm->total_out;
184*c7b436ecSSunila Sahu 		break;
185*c7b436ecSSunila Sahu 	default:
186*c7b436ecSSunila Sahu 		ZLIB_PMD_ERR("stats not produced for status:%d\n",
187*c7b436ecSSunila Sahu 				op->status);
188*c7b436ecSSunila Sahu 	}
189*c7b436ecSSunila Sahu 
190*c7b436ecSSunila Sahu 	inflateReset(strm);
191*c7b436ecSSunila Sahu }
192*c7b436ecSSunila Sahu 
193*c7b436ecSSunila Sahu /** Process comp operation for mbuf */
194*c7b436ecSSunila Sahu static inline int
195*c7b436ecSSunila Sahu process_zlib_op(struct zlib_qp *qp, struct rte_comp_op *op)
196*c7b436ecSSunila Sahu {
197*c7b436ecSSunila Sahu 	struct zlib_stream *stream;
198*c7b436ecSSunila Sahu 	struct zlib_priv_xform *private_xform;
199*c7b436ecSSunila Sahu 
200*c7b436ecSSunila Sahu 	if ((op->op_type == RTE_COMP_OP_STATEFUL) ||
201*c7b436ecSSunila Sahu 			(op->src.offset > rte_pktmbuf_data_len(op->m_src)) ||
202*c7b436ecSSunila Sahu 			(op->dst.offset > rte_pktmbuf_data_len(op->m_dst))) {
203*c7b436ecSSunila Sahu 		op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
204*c7b436ecSSunila Sahu 		ZLIB_PMD_ERR("Invalid source or destination buffers or "
205*c7b436ecSSunila Sahu 			     "invalid Operation requested\n");
206*c7b436ecSSunila Sahu 	} else {
207*c7b436ecSSunila Sahu 		private_xform = (struct zlib_priv_xform *)op->private_xform;
208*c7b436ecSSunila Sahu 		stream = &private_xform->stream;
209*c7b436ecSSunila Sahu 		stream->comp(op, &stream->strm);
210*c7b436ecSSunila Sahu 	}
211*c7b436ecSSunila Sahu 	/* whatever is out of op, put it into completion queue with
212*c7b436ecSSunila Sahu 	 * its status
213*c7b436ecSSunila Sahu 	 */
214*c7b436ecSSunila Sahu 	return rte_ring_enqueue(qp->processed_pkts, (void *)op);
215*c7b436ecSSunila Sahu }
216*c7b436ecSSunila Sahu 
217*c7b436ecSSunila Sahu /** Parse comp xform and set private xform/Stream parameters */
2180cc20d33SSunila Sahu int
2190cc20d33SSunila Sahu zlib_set_stream_parameters(const struct rte_comp_xform *xform,
2200cc20d33SSunila Sahu 		struct zlib_stream *stream)
2210cc20d33SSunila Sahu {
2220cc20d33SSunila Sahu 	int strategy, level, wbits;
2230cc20d33SSunila Sahu 	z_stream *strm = &stream->strm;
2240cc20d33SSunila Sahu 
2250cc20d33SSunila Sahu 	/* allocate deflate state */
2260cc20d33SSunila Sahu 	strm->zalloc = Z_NULL;
2270cc20d33SSunila Sahu 	strm->zfree = Z_NULL;
2280cc20d33SSunila Sahu 	strm->opaque = Z_NULL;
2290cc20d33SSunila Sahu 
2300cc20d33SSunila Sahu 	switch (xform->type) {
2310cc20d33SSunila Sahu 	case RTE_COMP_COMPRESS:
232*c7b436ecSSunila Sahu 		stream->comp = process_zlib_deflate;
233*c7b436ecSSunila Sahu 		stream->free = deflateEnd;
2340cc20d33SSunila Sahu 		/** Compression window bits */
2350cc20d33SSunila Sahu 		switch (xform->compress.algo) {
2360cc20d33SSunila Sahu 		case RTE_COMP_ALGO_DEFLATE:
2370cc20d33SSunila Sahu 			wbits = -(xform->compress.window_size);
2380cc20d33SSunila Sahu 			break;
2390cc20d33SSunila Sahu 		default:
2400cc20d33SSunila Sahu 			ZLIB_PMD_ERR("Compression algorithm not supported\n");
2410cc20d33SSunila Sahu 			return -1;
2420cc20d33SSunila Sahu 		}
2430cc20d33SSunila Sahu 		/** Compression Level */
2440cc20d33SSunila Sahu 		switch (xform->compress.level) {
2450cc20d33SSunila Sahu 		case RTE_COMP_LEVEL_PMD_DEFAULT:
2460cc20d33SSunila Sahu 			level = Z_DEFAULT_COMPRESSION;
2470cc20d33SSunila Sahu 			break;
2480cc20d33SSunila Sahu 		case RTE_COMP_LEVEL_NONE:
2490cc20d33SSunila Sahu 			level = Z_NO_COMPRESSION;
2500cc20d33SSunila Sahu 			break;
2510cc20d33SSunila Sahu 		case RTE_COMP_LEVEL_MIN:
2520cc20d33SSunila Sahu 			level = Z_BEST_SPEED;
2530cc20d33SSunila Sahu 			break;
2540cc20d33SSunila Sahu 		case RTE_COMP_LEVEL_MAX:
2550cc20d33SSunila Sahu 			level = Z_BEST_COMPRESSION;
2560cc20d33SSunila Sahu 			break;
2570cc20d33SSunila Sahu 		default:
2580cc20d33SSunila Sahu 			level = xform->compress.level;
2590cc20d33SSunila Sahu 			if (level < RTE_COMP_LEVEL_MIN ||
2600cc20d33SSunila Sahu 					level > RTE_COMP_LEVEL_MAX) {
2610cc20d33SSunila Sahu 				ZLIB_PMD_ERR("Compression level %d "
2620cc20d33SSunila Sahu 						"not supported\n",
2630cc20d33SSunila Sahu 						level);
2640cc20d33SSunila Sahu 				return -1;
2650cc20d33SSunila Sahu 			}
2660cc20d33SSunila Sahu 			break;
2670cc20d33SSunila Sahu 		}
2680cc20d33SSunila Sahu 		/** Compression strategy */
2690cc20d33SSunila Sahu 		switch (xform->compress.deflate.huffman) {
2700cc20d33SSunila Sahu 		case RTE_COMP_HUFFMAN_DEFAULT:
2710cc20d33SSunila Sahu 			strategy = Z_DEFAULT_STRATEGY;
2720cc20d33SSunila Sahu 			break;
2730cc20d33SSunila Sahu 		case RTE_COMP_HUFFMAN_FIXED:
2740cc20d33SSunila Sahu 			strategy = Z_FIXED;
2750cc20d33SSunila Sahu 			break;
2760cc20d33SSunila Sahu 		case RTE_COMP_HUFFMAN_DYNAMIC:
2770cc20d33SSunila Sahu 			strategy = Z_DEFAULT_STRATEGY;
2780cc20d33SSunila Sahu 			break;
2790cc20d33SSunila Sahu 		default:
2800cc20d33SSunila Sahu 			ZLIB_PMD_ERR("Compression strategy not supported\n");
2810cc20d33SSunila Sahu 			return -1;
2820cc20d33SSunila Sahu 		}
2830cc20d33SSunila Sahu 		if (deflateInit2(strm, level,
2840cc20d33SSunila Sahu 					Z_DEFLATED, wbits,
2850cc20d33SSunila Sahu 					DEF_MEM_LEVEL, strategy) != Z_OK) {
2860cc20d33SSunila Sahu 			ZLIB_PMD_ERR("Deflate init failed\n");
2870cc20d33SSunila Sahu 			return -1;
2880cc20d33SSunila Sahu 		}
2890cc20d33SSunila Sahu 		break;
2900cc20d33SSunila Sahu 
2910cc20d33SSunila Sahu 	case RTE_COMP_DECOMPRESS:
292*c7b436ecSSunila Sahu 		stream->comp = process_zlib_inflate;
293*c7b436ecSSunila Sahu 		stream->free = inflateEnd;
2940cc20d33SSunila Sahu 		/** window bits */
2950cc20d33SSunila Sahu 		switch (xform->decompress.algo) {
2960cc20d33SSunila Sahu 		case RTE_COMP_ALGO_DEFLATE:
2970cc20d33SSunila Sahu 			wbits = -(xform->decompress.window_size);
2980cc20d33SSunila Sahu 			break;
2990cc20d33SSunila Sahu 		default:
3000cc20d33SSunila Sahu 			ZLIB_PMD_ERR("Compression algorithm not supported\n");
3010cc20d33SSunila Sahu 			return -1;
3020cc20d33SSunila Sahu 		}
3030cc20d33SSunila Sahu 
3040cc20d33SSunila Sahu 		if (inflateInit2(strm, wbits) != Z_OK) {
3050cc20d33SSunila Sahu 			ZLIB_PMD_ERR("Inflate init failed\n");
3060cc20d33SSunila Sahu 			return -1;
3070cc20d33SSunila Sahu 		}
3080cc20d33SSunila Sahu 		break;
3090cc20d33SSunila Sahu 	default:
3100cc20d33SSunila Sahu 		return -1;
3110cc20d33SSunila Sahu 	}
3120cc20d33SSunila Sahu 	return 0;
3130cc20d33SSunila Sahu }
3140cc20d33SSunila Sahu 
315*c7b436ecSSunila Sahu static uint16_t
316*c7b436ecSSunila Sahu zlib_pmd_enqueue_burst(void *queue_pair,
317*c7b436ecSSunila Sahu 			struct rte_comp_op **ops, uint16_t nb_ops)
318*c7b436ecSSunila Sahu {
319*c7b436ecSSunila Sahu 	struct zlib_qp *qp = queue_pair;
320*c7b436ecSSunila Sahu 	int ret;
321*c7b436ecSSunila Sahu 	uint16_t i;
322*c7b436ecSSunila Sahu 	uint16_t enqd = 0;
323*c7b436ecSSunila Sahu 	for (i = 0; i < nb_ops; i++) {
324*c7b436ecSSunila Sahu 		ret = process_zlib_op(qp, ops[i]);
325*c7b436ecSSunila Sahu 		if (unlikely(ret < 0)) {
326*c7b436ecSSunila Sahu 			/* increment count if failed to push to completion
327*c7b436ecSSunila Sahu 			 * queue
328*c7b436ecSSunila Sahu 			 */
329*c7b436ecSSunila Sahu 			qp->qp_stats.enqueue_err_count++;
330*c7b436ecSSunila Sahu 		} else {
331*c7b436ecSSunila Sahu 			qp->qp_stats.enqueued_count++;
332*c7b436ecSSunila Sahu 			enqd++;
333*c7b436ecSSunila Sahu 		}
334*c7b436ecSSunila Sahu 	}
335*c7b436ecSSunila Sahu 	return enqd;
336*c7b436ecSSunila Sahu }
337*c7b436ecSSunila Sahu 
338*c7b436ecSSunila Sahu static uint16_t
339*c7b436ecSSunila Sahu zlib_pmd_dequeue_burst(void *queue_pair,
340*c7b436ecSSunila Sahu 			struct rte_comp_op **ops, uint16_t nb_ops)
341*c7b436ecSSunila Sahu {
342*c7b436ecSSunila Sahu 	struct zlib_qp *qp = queue_pair;
343*c7b436ecSSunila Sahu 
344*c7b436ecSSunila Sahu 	unsigned int nb_dequeued = 0;
345*c7b436ecSSunila Sahu 
346*c7b436ecSSunila Sahu 	nb_dequeued = rte_ring_dequeue_burst(qp->processed_pkts,
347*c7b436ecSSunila Sahu 			(void **)ops, nb_ops, NULL);
348*c7b436ecSSunila Sahu 	qp->qp_stats.dequeued_count += nb_dequeued;
349*c7b436ecSSunila Sahu 
350*c7b436ecSSunila Sahu 	return nb_dequeued;
351*c7b436ecSSunila Sahu }
352*c7b436ecSSunila Sahu 
3530c4e4c16SAshish Gupta static int
3540c4e4c16SAshish Gupta zlib_create(const char *name,
3550c4e4c16SAshish Gupta 		struct rte_vdev_device *vdev,
3560c4e4c16SAshish Gupta 		struct rte_compressdev_pmd_init_params *init_params)
3570c4e4c16SAshish Gupta {
3580c4e4c16SAshish Gupta 	struct rte_compressdev *dev;
3590c4e4c16SAshish Gupta 
3600c4e4c16SAshish Gupta 	dev = rte_compressdev_pmd_create(name, &vdev->device,
3610c4e4c16SAshish Gupta 			sizeof(struct zlib_private), init_params);
3620c4e4c16SAshish Gupta 	if (dev == NULL) {
3630c4e4c16SAshish Gupta 		ZLIB_PMD_ERR("driver %s: create failed", init_params->name);
3640c4e4c16SAshish Gupta 		return -ENODEV;
3650c4e4c16SAshish Gupta 	}
3660c4e4c16SAshish Gupta 
36727422fc3SAshish Gupta 	dev->dev_ops = rte_zlib_pmd_ops;
36827422fc3SAshish Gupta 
369*c7b436ecSSunila Sahu 	/* register rx/tx burst functions for data path */
370*c7b436ecSSunila Sahu 	dev->dequeue_burst = zlib_pmd_dequeue_burst;
371*c7b436ecSSunila Sahu 	dev->enqueue_burst = zlib_pmd_enqueue_burst;
372*c7b436ecSSunila Sahu 
3730c4e4c16SAshish Gupta 	return 0;
3740c4e4c16SAshish Gupta }
3750c4e4c16SAshish Gupta 
3760c4e4c16SAshish Gupta static int
3770c4e4c16SAshish Gupta zlib_probe(struct rte_vdev_device *vdev)
3780c4e4c16SAshish Gupta {
3790c4e4c16SAshish Gupta 	struct rte_compressdev_pmd_init_params init_params = {
3800c4e4c16SAshish Gupta 		"",
3810c4e4c16SAshish Gupta 		rte_socket_id()
3820c4e4c16SAshish Gupta 	};
3830c4e4c16SAshish Gupta 	const char *name;
3840c4e4c16SAshish Gupta 	const char *input_args;
3850c4e4c16SAshish Gupta 	int retval;
3860c4e4c16SAshish Gupta 
3870c4e4c16SAshish Gupta 	name = rte_vdev_device_name(vdev);
3880c4e4c16SAshish Gupta 
3890c4e4c16SAshish Gupta 	if (name == NULL)
3900c4e4c16SAshish Gupta 		return -EINVAL;
3910c4e4c16SAshish Gupta 
3920c4e4c16SAshish Gupta 	input_args = rte_vdev_device_args(vdev);
3930c4e4c16SAshish Gupta 
3940c4e4c16SAshish Gupta 	retval = rte_compressdev_pmd_parse_input_args(&init_params, input_args);
3950c4e4c16SAshish Gupta 	if (retval < 0) {
3960c4e4c16SAshish Gupta 		ZLIB_PMD_LOG(ERR,
3970c4e4c16SAshish Gupta 			"Failed to parse initialisation arguments[%s]\n",
3980c4e4c16SAshish Gupta 			input_args);
3990c4e4c16SAshish Gupta 		return -EINVAL;
4000c4e4c16SAshish Gupta 	}
4010c4e4c16SAshish Gupta 
4020c4e4c16SAshish Gupta 	return zlib_create(name, vdev, &init_params);
4030c4e4c16SAshish Gupta }
4040c4e4c16SAshish Gupta 
4050c4e4c16SAshish Gupta static int
4060c4e4c16SAshish Gupta zlib_remove(struct rte_vdev_device *vdev)
4070c4e4c16SAshish Gupta {
4080c4e4c16SAshish Gupta 	struct rte_compressdev *compressdev;
4090c4e4c16SAshish Gupta 	const char *name;
4100c4e4c16SAshish Gupta 
4110c4e4c16SAshish Gupta 	name = rte_vdev_device_name(vdev);
4120c4e4c16SAshish Gupta 	if (name == NULL)
4130c4e4c16SAshish Gupta 		return -EINVAL;
4140c4e4c16SAshish Gupta 
4150c4e4c16SAshish Gupta 	compressdev = rte_compressdev_pmd_get_named_dev(name);
4160c4e4c16SAshish Gupta 	if (compressdev == NULL)
4170c4e4c16SAshish Gupta 		return -ENODEV;
4180c4e4c16SAshish Gupta 
4190c4e4c16SAshish Gupta 	return rte_compressdev_pmd_destroy(compressdev);
4200c4e4c16SAshish Gupta }
4210c4e4c16SAshish Gupta 
4220c4e4c16SAshish Gupta static struct rte_vdev_driver zlib_pmd_drv = {
4230c4e4c16SAshish Gupta 	.probe = zlib_probe,
4240c4e4c16SAshish Gupta 	.remove = zlib_remove
4250c4e4c16SAshish Gupta };
4260c4e4c16SAshish Gupta 
4270c4e4c16SAshish Gupta RTE_PMD_REGISTER_VDEV(COMPRESSDEV_NAME_ZLIB_PMD, zlib_pmd_drv);
4280c4e4c16SAshish Gupta RTE_INIT(zlib_init_log);
4290c4e4c16SAshish Gupta 
4300c4e4c16SAshish Gupta static void
4310c4e4c16SAshish Gupta zlib_init_log(void)
4320c4e4c16SAshish Gupta {
4330c4e4c16SAshish Gupta 	zlib_logtype_driver = rte_log_register("pmd.compress.zlib");
4340c4e4c16SAshish Gupta 	if (zlib_logtype_driver >= 0)
4350c4e4c16SAshish Gupta 		rte_log_set_level(zlib_logtype_driver, RTE_LOG_INFO);
4360c4e4c16SAshish Gupta }
437