xref: /dpdk/drivers/compress/octeontx/otx_zip_pmd.c (revision 938f3f5f9048a6f7e48ad4d120ec60d7d37ac4d2)
143e610bbSSunila Sahu /* SPDX-License-Identifier: BSD-3-Clause
243e610bbSSunila Sahu  * Copyright(c) 2018 Cavium, Inc
343e610bbSSunila Sahu  */
443e610bbSSunila Sahu 
543e610bbSSunila Sahu #include <string.h>
643e610bbSSunila Sahu 
743e610bbSSunila Sahu #include <rte_byteorder.h>
843e610bbSSunila Sahu #include <rte_common.h>
943e610bbSSunila Sahu #include <rte_cpuflags.h>
1043e610bbSSunila Sahu #include <rte_malloc.h>
1143e610bbSSunila Sahu 
1243e610bbSSunila Sahu #include "otx_zip.h"
1343e610bbSSunila Sahu 
14c378f084SAshish Gupta static const struct rte_compressdev_capabilities
15c378f084SAshish Gupta 				octtx_zip_pmd_capabilities[] = {
16c378f084SAshish Gupta 	{	.algo = RTE_COMP_ALGO_DEFLATE,
17c378f084SAshish Gupta 		/* Deflate */
18c378f084SAshish Gupta 		.comp_feature_flags =	RTE_COMP_FF_HUFFMAN_FIXED |
19c378f084SAshish Gupta 					RTE_COMP_FF_HUFFMAN_DYNAMIC,
20c378f084SAshish Gupta 		/* Non sharable Priv XFORM and Stateless */
21c378f084SAshish Gupta 		.window_size = {
22c378f084SAshish Gupta 				.min = 1,
23c378f084SAshish Gupta 				.max = 14,
24c378f084SAshish Gupta 				.increment = 1
25c378f084SAshish Gupta 				/* size supported 2^1 to 2^14 */
26c378f084SAshish Gupta 		},
27c378f084SAshish Gupta 	},
28c378f084SAshish Gupta 	RTE_COMP_END_OF_CAPABILITIES_LIST()
29c378f084SAshish Gupta };
3043e610bbSSunila Sahu 
3152048f8fSAshish Gupta /*
3252048f8fSAshish Gupta  * Reset session to default state for next set of stateless operation
3352048f8fSAshish Gupta  */
3452048f8fSAshish Gupta static inline void
35*938f3f5fSMahipal Challa reset_stream(union zip_inst_s *inst)
3652048f8fSAshish Gupta {
3752048f8fSAshish Gupta 	inst->s.bf = 1;
3852048f8fSAshish Gupta 	inst->s.ef = 0;
3952048f8fSAshish Gupta }
4052048f8fSAshish Gupta 
4152048f8fSAshish Gupta int
4252048f8fSAshish Gupta zip_process_op(struct rte_comp_op *op,
4352048f8fSAshish Gupta 		struct zipvf_qp *qp,
44*938f3f5fSMahipal Challa 		struct zip_stream *zstrm, int num)
4552048f8fSAshish Gupta {
46*938f3f5fSMahipal Challa 	union zip_inst_s *inst = zstrm->inst[num];
4752048f8fSAshish Gupta 	volatile union zip_zres_s *zresult = NULL;
4852048f8fSAshish Gupta 
4952048f8fSAshish Gupta 	if ((op->m_src->nb_segs > 1) || (op->m_dst->nb_segs > 1) ||
5052048f8fSAshish Gupta 			(op->src.offset > rte_pktmbuf_pkt_len(op->m_src)) ||
5152048f8fSAshish Gupta 			(op->dst.offset > rte_pktmbuf_pkt_len(op->m_dst))) {
5252048f8fSAshish Gupta 		op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
5352048f8fSAshish Gupta 		ZIP_PMD_ERR("Segmented packet is not supported\n");
5452048f8fSAshish Gupta 		return 0;
5552048f8fSAshish Gupta 	}
5652048f8fSAshish Gupta 
57*938f3f5fSMahipal Challa 	zipvf_prepare_cmd_stateless(op, inst);
5852048f8fSAshish Gupta 
59*938f3f5fSMahipal Challa 	zresult = (union zip_zres_s *)zstrm->bufs[RES_BUF + num];
6052048f8fSAshish Gupta 	zresult->s.compcode = 0;
6152048f8fSAshish Gupta 
6252048f8fSAshish Gupta #ifdef ZIP_DBG
6352048f8fSAshish Gupta 	zip_dump_instruction(inst);
6452048f8fSAshish Gupta #endif
6552048f8fSAshish Gupta 
6652048f8fSAshish Gupta 	/* Submit zip command */
6752048f8fSAshish Gupta 	zipvf_push_command(qp, (void *)inst);
6852048f8fSAshish Gupta 
6952048f8fSAshish Gupta 	return 0;
7052048f8fSAshish Gupta }
7152048f8fSAshish Gupta 
72b43ebc65SAshish Gupta /** Parse xform parameters and setup a stream */
73b43ebc65SAshish Gupta static int
74b43ebc65SAshish Gupta zip_set_stream_parameters(struct rte_compressdev *dev,
75b43ebc65SAshish Gupta 			const struct rte_comp_xform *xform,
76b43ebc65SAshish Gupta 			struct zip_stream *z_stream)
77b43ebc65SAshish Gupta {
78b43ebc65SAshish Gupta 	struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private;
79*938f3f5fSMahipal Challa 	union zip_inst_s *inst;
80b43ebc65SAshish Gupta 	void *res;
81*938f3f5fSMahipal Challa 	int ret, i;
82b43ebc65SAshish Gupta 
83b43ebc65SAshish Gupta 	/* Allocate resources required by a stream */
84b43ebc65SAshish Gupta 	ret = rte_mempool_get_bulk(vf->zip_mp,
85*938f3f5fSMahipal Challa 			z_stream->bufs, (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE));
86b43ebc65SAshish Gupta 	if (ret < 0)
87b43ebc65SAshish Gupta 		return -1;
88b43ebc65SAshish Gupta 
89*938f3f5fSMahipal Challa 	for (i = 0; i < ZIP_BURST_SIZE; i++) {
90b43ebc65SAshish Gupta 		/* get one command buffer from pool and set up */
91*938f3f5fSMahipal Challa 		inst = (union zip_inst_s *)z_stream->bufs[(CMD_BUF * ZIP_BURST_SIZE) + i];
92*938f3f5fSMahipal Challa 		res = z_stream->bufs[(RES_BUF * ZIP_BURST_SIZE) + i];
93b43ebc65SAshish Gupta 		memset(inst->u, 0, sizeof(inst->u));
94b43ebc65SAshish Gupta 
95b43ebc65SAshish Gupta 		/* set bf for only first ops of stream */
96b43ebc65SAshish Gupta 		inst->s.bf = 1;
97b43ebc65SAshish Gupta 
98b43ebc65SAshish Gupta 		if (xform->type == RTE_COMP_COMPRESS) {
99b43ebc65SAshish Gupta 			inst->s.op = ZIP_OP_E_COMP;
100b43ebc65SAshish Gupta 
101b43ebc65SAshish Gupta 			switch (xform->compress.deflate.huffman) {
102b43ebc65SAshish Gupta 			case RTE_COMP_HUFFMAN_DEFAULT:
103b43ebc65SAshish Gupta 				inst->s.cc = ZIP_CC_DEFAULT;
104b43ebc65SAshish Gupta 				break;
105b43ebc65SAshish Gupta 			case RTE_COMP_HUFFMAN_FIXED:
106b43ebc65SAshish Gupta 				inst->s.cc = ZIP_CC_FIXED_HUFF;
107b43ebc65SAshish Gupta 				break;
108b43ebc65SAshish Gupta 			case RTE_COMP_HUFFMAN_DYNAMIC:
109b43ebc65SAshish Gupta 				inst->s.cc = ZIP_CC_DYN_HUFF;
110b43ebc65SAshish Gupta 				break;
111b43ebc65SAshish Gupta 			default:
112b43ebc65SAshish Gupta 				ret = -1;
113b43ebc65SAshish Gupta 				goto err;
114b43ebc65SAshish Gupta 			}
115b43ebc65SAshish Gupta 
116b43ebc65SAshish Gupta 			switch (xform->compress.level) {
117b43ebc65SAshish Gupta 			case RTE_COMP_LEVEL_MIN:
118b43ebc65SAshish Gupta 				inst->s.ss = ZIP_COMP_E_LEVEL_MIN;
119b43ebc65SAshish Gupta 				break;
120b43ebc65SAshish Gupta 			case RTE_COMP_LEVEL_MAX:
121b43ebc65SAshish Gupta 				inst->s.ss = ZIP_COMP_E_LEVEL_MAX;
122b43ebc65SAshish Gupta 				break;
123b43ebc65SAshish Gupta 			case RTE_COMP_LEVEL_NONE:
124b43ebc65SAshish Gupta 				ZIP_PMD_ERR("Compression level not supported");
125b43ebc65SAshish Gupta 				ret = -1;
126b43ebc65SAshish Gupta 				goto err;
127b43ebc65SAshish Gupta 			default:
128b43ebc65SAshish Gupta 				/* for any value between min and max , choose
129b43ebc65SAshish Gupta 				 * PMD default.
130b43ebc65SAshish Gupta 				 */
131b43ebc65SAshish Gupta 				inst->s.ss = ZIP_COMP_E_LEVEL_MED; /** PMD default **/
132b43ebc65SAshish Gupta 				break;
133b43ebc65SAshish Gupta 			}
134b43ebc65SAshish Gupta 		} else if (xform->type == RTE_COMP_DECOMPRESS) {
135b43ebc65SAshish Gupta 			inst->s.op = ZIP_OP_E_DECOMP;
136b43ebc65SAshish Gupta 			/* from HRM,
137b43ebc65SAshish Gupta 			 * For DEFLATE decompression, [CC] must be 0x0.
138b43ebc65SAshish Gupta 			 * For decompression, [SS] must be 0x0
139b43ebc65SAshish Gupta 			 */
140b43ebc65SAshish Gupta 			inst->s.cc = 0;
141b43ebc65SAshish Gupta 			/* Speed bit should not be set for decompression */
142b43ebc65SAshish Gupta 			inst->s.ss = 0;
143b43ebc65SAshish Gupta 			/* decompression context is supported only for STATEFUL
144b43ebc65SAshish Gupta 			 * operations. Currently we support STATELESS ONLY so
145b43ebc65SAshish Gupta 			 * skip setting of ctx pointer
146b43ebc65SAshish Gupta 			 */
147b43ebc65SAshish Gupta 
148b43ebc65SAshish Gupta 		} else {
149b43ebc65SAshish Gupta 			ZIP_PMD_ERR("\nxform type not supported");
150b43ebc65SAshish Gupta 			ret = -1;
151b43ebc65SAshish Gupta 			goto err;
152b43ebc65SAshish Gupta 		}
153b43ebc65SAshish Gupta 
154b43ebc65SAshish Gupta 		inst->s.res_ptr_addr.s.addr = rte_mempool_virt2iova(res);
155b43ebc65SAshish Gupta 		inst->s.res_ptr_ctl.s.length = 0;
156b43ebc65SAshish Gupta 
157*938f3f5fSMahipal Challa 		z_stream->inst[i] = inst;
158*938f3f5fSMahipal Challa 	}
159*938f3f5fSMahipal Challa 
16052048f8fSAshish Gupta 	z_stream->func = zip_process_op;
161b43ebc65SAshish Gupta 
162b43ebc65SAshish Gupta 	return 0;
163b43ebc65SAshish Gupta 
164b43ebc65SAshish Gupta err:
165b43ebc65SAshish Gupta 	rte_mempool_put_bulk(vf->zip_mp,
166b43ebc65SAshish Gupta 			     (void *)&(z_stream->bufs[0]),
167*938f3f5fSMahipal Challa 			     (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE));
168b43ebc65SAshish Gupta 
169b43ebc65SAshish Gupta 	return ret;
170b43ebc65SAshish Gupta }
171b43ebc65SAshish Gupta 
172c378f084SAshish Gupta /** Configure device */
173c378f084SAshish Gupta static int
174c378f084SAshish Gupta zip_pmd_config(struct rte_compressdev *dev,
175c378f084SAshish Gupta 		struct rte_compressdev_config *config)
176c378f084SAshish Gupta {
177c378f084SAshish Gupta 	int nb_streams;
178c378f084SAshish Gupta 	char res_pool[RTE_MEMZONE_NAMESIZE];
179c378f084SAshish Gupta 	struct zip_vf *vf;
180c378f084SAshish Gupta 	struct rte_mempool *zip_buf_mp;
181c378f084SAshish Gupta 
182c378f084SAshish Gupta 	if (!config || !dev)
183c378f084SAshish Gupta 		return -EIO;
184c378f084SAshish Gupta 
185c378f084SAshish Gupta 	vf = (struct zip_vf *)(dev->data->dev_private);
186c378f084SAshish Gupta 
187c378f084SAshish Gupta 	/* create pool with maximum numbers of resources
188c378f084SAshish Gupta 	 * required by streams
189c378f084SAshish Gupta 	 */
190c378f084SAshish Gupta 
191c378f084SAshish Gupta 	/* use common pool for non-shareable priv_xform and stream */
192c378f084SAshish Gupta 	nb_streams = config->max_nb_priv_xforms + config->max_nb_streams;
193c378f084SAshish Gupta 
194c378f084SAshish Gupta 	snprintf(res_pool, RTE_MEMZONE_NAMESIZE, "octtx_zip_res_pool%u",
195c378f084SAshish Gupta 		 dev->data->dev_id);
196c378f084SAshish Gupta 
197c378f084SAshish Gupta 	/** TBD Should we use the per core object cache for stream resources */
198c378f084SAshish Gupta 	zip_buf_mp = rte_mempool_create(
199c378f084SAshish Gupta 			res_pool,
200*938f3f5fSMahipal Challa 			(nb_streams * MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE),
201c378f084SAshish Gupta 			ZIP_BUF_SIZE,
202c378f084SAshish Gupta 			0,
203c378f084SAshish Gupta 			0,
204c378f084SAshish Gupta 			NULL,
205c378f084SAshish Gupta 			NULL,
206c378f084SAshish Gupta 			NULL,
207c378f084SAshish Gupta 			NULL,
208c378f084SAshish Gupta 			SOCKET_ID_ANY,
209c378f084SAshish Gupta 			0);
210c378f084SAshish Gupta 
211c378f084SAshish Gupta 	if (zip_buf_mp == NULL) {
212c378f084SAshish Gupta 		ZIP_PMD_ERR(
213c378f084SAshish Gupta 			"Failed to create buf mempool octtx_zip_res_pool%u",
214c378f084SAshish Gupta 			dev->data->dev_id);
215c378f084SAshish Gupta 		return -1;
216c378f084SAshish Gupta 	}
217c378f084SAshish Gupta 
218c378f084SAshish Gupta 	vf->zip_mp = zip_buf_mp;
219c378f084SAshish Gupta 
220c378f084SAshish Gupta 	return 0;
221c378f084SAshish Gupta }
222c378f084SAshish Gupta 
223c378f084SAshish Gupta /** Start device */
224c378f084SAshish Gupta static int
225c378f084SAshish Gupta zip_pmd_start(__rte_unused struct rte_compressdev *dev)
226c378f084SAshish Gupta {
227c378f084SAshish Gupta 	return 0;
228c378f084SAshish Gupta }
229c378f084SAshish Gupta 
230c378f084SAshish Gupta /** Stop device */
231c378f084SAshish Gupta static void
232c378f084SAshish Gupta zip_pmd_stop(__rte_unused struct rte_compressdev *dev)
233c378f084SAshish Gupta {
234c378f084SAshish Gupta 
235c378f084SAshish Gupta }
236c378f084SAshish Gupta 
237c378f084SAshish Gupta /** Close device */
238c378f084SAshish Gupta static int
239c378f084SAshish Gupta zip_pmd_close(struct rte_compressdev *dev)
240c378f084SAshish Gupta {
241c378f084SAshish Gupta 	if (dev == NULL)
242c378f084SAshish Gupta 		return -1;
243c378f084SAshish Gupta 
244c378f084SAshish Gupta 	struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private;
245c378f084SAshish Gupta 	rte_mempool_free(vf->zip_mp);
246c378f084SAshish Gupta 
247c378f084SAshish Gupta 	return 0;
248c378f084SAshish Gupta }
249c378f084SAshish Gupta 
250c378f084SAshish Gupta /** Get device statistics */
251c378f084SAshish Gupta static void
252c378f084SAshish Gupta zip_pmd_stats_get(struct rte_compressdev *dev,
253c378f084SAshish Gupta 		struct rte_compressdev_stats *stats)
254c378f084SAshish Gupta {
255c378f084SAshish Gupta 	int qp_id;
256c378f084SAshish Gupta 
257c378f084SAshish Gupta 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
258c378f084SAshish Gupta 		struct zipvf_qp *qp = dev->data->queue_pairs[qp_id];
259c378f084SAshish Gupta 
260c378f084SAshish Gupta 		stats->enqueued_count += qp->qp_stats.enqueued_count;
261c378f084SAshish Gupta 		stats->dequeued_count += qp->qp_stats.dequeued_count;
262c378f084SAshish Gupta 
263c378f084SAshish Gupta 		stats->enqueue_err_count += qp->qp_stats.enqueue_err_count;
264c378f084SAshish Gupta 		stats->dequeue_err_count += qp->qp_stats.dequeue_err_count;
265c378f084SAshish Gupta 	}
266c378f084SAshish Gupta }
267c378f084SAshish Gupta 
268c378f084SAshish Gupta /** Reset device statistics */
269c378f084SAshish Gupta static void
270c378f084SAshish Gupta zip_pmd_stats_reset(struct rte_compressdev *dev)
271c378f084SAshish Gupta {
272c378f084SAshish Gupta 	int qp_id;
273c378f084SAshish Gupta 
274c378f084SAshish Gupta 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
275c378f084SAshish Gupta 		struct zipvf_qp *qp = dev->data->queue_pairs[qp_id];
276c378f084SAshish Gupta 		memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
277c378f084SAshish Gupta 	}
278c378f084SAshish Gupta }
279c378f084SAshish Gupta 
280c378f084SAshish Gupta /** Get device info */
281c378f084SAshish Gupta static void
282c378f084SAshish Gupta zip_pmd_info_get(struct rte_compressdev *dev,
283c378f084SAshish Gupta 		struct rte_compressdev_info *dev_info)
284c378f084SAshish Gupta {
285c378f084SAshish Gupta 	struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private;
286c378f084SAshish Gupta 
287c378f084SAshish Gupta 	if (dev_info != NULL) {
288c378f084SAshish Gupta 		dev_info->driver_name = dev->device->driver->name;
289c378f084SAshish Gupta 		dev_info->feature_flags = dev->feature_flags;
290c378f084SAshish Gupta 		dev_info->capabilities = octtx_zip_pmd_capabilities;
291c378f084SAshish Gupta 		dev_info->max_nb_queue_pairs = vf->max_nb_queue_pairs;
292c378f084SAshish Gupta 	}
293c378f084SAshish Gupta }
294c378f084SAshish Gupta 
295c378f084SAshish Gupta /** Release queue pair */
296c378f084SAshish Gupta static int
297c378f084SAshish Gupta zip_pmd_qp_release(struct rte_compressdev *dev, uint16_t qp_id)
298c378f084SAshish Gupta {
299c378f084SAshish Gupta 	struct zipvf_qp *qp = dev->data->queue_pairs[qp_id];
300c378f084SAshish Gupta 
301c378f084SAshish Gupta 	if (qp != NULL) {
302c378f084SAshish Gupta 		zipvf_q_term(qp);
303c378f084SAshish Gupta 
304c378f084SAshish Gupta 		rte_ring_free(qp->processed_pkts);
305c378f084SAshish Gupta 
306c378f084SAshish Gupta 		rte_free(qp);
307c378f084SAshish Gupta 		dev->data->queue_pairs[qp_id] = NULL;
308c378f084SAshish Gupta 	}
309c378f084SAshish Gupta 	return 0;
310c378f084SAshish Gupta }
311c378f084SAshish Gupta 
312c378f084SAshish Gupta /** Create a ring to place process packets on */
313c378f084SAshish Gupta static struct rte_ring *
314c378f084SAshish Gupta zip_pmd_qp_create_processed_pkts_ring(struct zipvf_qp *qp,
315c378f084SAshish Gupta 		unsigned int ring_size, int socket_id)
316c378f084SAshish Gupta {
317c378f084SAshish Gupta 	struct rte_ring *r;
318c378f084SAshish Gupta 
319c378f084SAshish Gupta 	r = rte_ring_lookup(qp->name);
320c378f084SAshish Gupta 	if (r) {
321c378f084SAshish Gupta 		if (rte_ring_get_size(r) >= ring_size) {
322c378f084SAshish Gupta 			ZIP_PMD_INFO("Reusing existing ring %s for processed"
323c378f084SAshish Gupta 					" packets", qp->name);
324c378f084SAshish Gupta 			return r;
325c378f084SAshish Gupta 		}
326c378f084SAshish Gupta 
327c378f084SAshish Gupta 		ZIP_PMD_ERR("Unable to reuse existing ring %s for processed"
328c378f084SAshish Gupta 				" packets", qp->name);
329c378f084SAshish Gupta 		return NULL;
330c378f084SAshish Gupta 	}
331c378f084SAshish Gupta 
332c378f084SAshish Gupta 	return rte_ring_create(qp->name, ring_size, socket_id,
333c378f084SAshish Gupta 						RING_F_EXACT_SZ);
334c378f084SAshish Gupta }
335c378f084SAshish Gupta 
336c378f084SAshish Gupta /** Setup a queue pair */
337c378f084SAshish Gupta static int
338c378f084SAshish Gupta zip_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
339c378f084SAshish Gupta 		uint32_t max_inflight_ops, int socket_id)
340c378f084SAshish Gupta {
341c378f084SAshish Gupta 	struct zipvf_qp *qp = NULL;
342c378f084SAshish Gupta 	struct zip_vf *vf;
343c378f084SAshish Gupta 	char *name;
344c378f084SAshish Gupta 	int ret;
345c378f084SAshish Gupta 
346c378f084SAshish Gupta 	if (!dev)
347c378f084SAshish Gupta 		return -1;
348c378f084SAshish Gupta 
349c378f084SAshish Gupta 	vf = (struct zip_vf *) (dev->data->dev_private);
350c378f084SAshish Gupta 
351c378f084SAshish Gupta 	/* Free memory prior to re-allocation if needed. */
352c378f084SAshish Gupta 	if (dev->data->queue_pairs[qp_id] != NULL) {
353c378f084SAshish Gupta 		ZIP_PMD_INFO("Using existing queue pair %d ", qp_id);
354c378f084SAshish Gupta 		return 0;
355c378f084SAshish Gupta 	}
356c378f084SAshish Gupta 
357c378f084SAshish Gupta 	name =  rte_malloc(NULL, RTE_COMPRESSDEV_NAME_MAX_LEN, 0);
358b072930fSWeiguo Li 	if (name == NULL)
359b072930fSWeiguo Li 		return (-ENOMEM);
360c378f084SAshish Gupta 	snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN,
361c378f084SAshish Gupta 		 "zip_pmd_%u_qp_%u",
362c378f084SAshish Gupta 		 dev->data->dev_id, qp_id);
363c378f084SAshish Gupta 
364c378f084SAshish Gupta 	/* Allocate the queue pair data structure. */
365c378f084SAshish Gupta 	qp = rte_zmalloc_socket(name, sizeof(*qp),
366c378f084SAshish Gupta 				RTE_CACHE_LINE_SIZE, socket_id);
367b072930fSWeiguo Li 	if (qp == NULL) {
368b072930fSWeiguo Li 		rte_free(name);
369c378f084SAshish Gupta 		return (-ENOMEM);
370b072930fSWeiguo Li 	}
371c378f084SAshish Gupta 
372c378f084SAshish Gupta 	qp->name = name;
373c378f084SAshish Gupta 
374c378f084SAshish Gupta 	/* Create completion queue up to max_inflight_ops */
375c378f084SAshish Gupta 	qp->processed_pkts = zip_pmd_qp_create_processed_pkts_ring(qp,
376c378f084SAshish Gupta 						max_inflight_ops, socket_id);
377c378f084SAshish Gupta 	if (qp->processed_pkts == NULL)
378c378f084SAshish Gupta 		goto qp_setup_cleanup;
379c378f084SAshish Gupta 
380c378f084SAshish Gupta 	qp->id = qp_id;
381c378f084SAshish Gupta 	qp->vf = vf;
382c378f084SAshish Gupta 
383c378f084SAshish Gupta 	ret = zipvf_q_init(qp);
384c378f084SAshish Gupta 	if (ret < 0)
385c378f084SAshish Gupta 		goto qp_setup_cleanup;
386c378f084SAshish Gupta 
387c378f084SAshish Gupta 	dev->data->queue_pairs[qp_id] = qp;
388c378f084SAshish Gupta 
389c378f084SAshish Gupta 	memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
390c378f084SAshish Gupta 	return 0;
391c378f084SAshish Gupta 
392c378f084SAshish Gupta qp_setup_cleanup:
393c378f084SAshish Gupta 	rte_ring_free(qp->processed_pkts);
394c378f084SAshish Gupta 	rte_free(qp);
395c378f084SAshish Gupta 	return -1;
396c378f084SAshish Gupta }
397c378f084SAshish Gupta 
398b43ebc65SAshish Gupta static int
399b43ebc65SAshish Gupta zip_pmd_stream_create(struct rte_compressdev *dev,
400b43ebc65SAshish Gupta 		const struct rte_comp_xform *xform, void **stream)
401b43ebc65SAshish Gupta {
402b43ebc65SAshish Gupta 	int ret;
403b43ebc65SAshish Gupta 	struct zip_stream *strm = NULL;
404b43ebc65SAshish Gupta 
405b43ebc65SAshish Gupta 	strm = rte_malloc(NULL,
406b43ebc65SAshish Gupta 			sizeof(struct zip_stream), 0);
407b43ebc65SAshish Gupta 
408b43ebc65SAshish Gupta 	if (strm == NULL)
409b43ebc65SAshish Gupta 		return (-ENOMEM);
410b43ebc65SAshish Gupta 
411b43ebc65SAshish Gupta 	ret = zip_set_stream_parameters(dev, xform, strm);
412b43ebc65SAshish Gupta 	if (ret < 0) {
413b43ebc65SAshish Gupta 		ZIP_PMD_ERR("failed configure xform parameters");
414b43ebc65SAshish Gupta 		rte_free(strm);
415b43ebc65SAshish Gupta 		return ret;
416b43ebc65SAshish Gupta 	}
417b43ebc65SAshish Gupta 	*stream = strm;
418*938f3f5fSMahipal Challa 
419b43ebc65SAshish Gupta 	return 0;
420b43ebc65SAshish Gupta }
421b43ebc65SAshish Gupta 
422b43ebc65SAshish Gupta static int
423b43ebc65SAshish Gupta zip_pmd_stream_free(struct rte_compressdev *dev, void *stream)
424b43ebc65SAshish Gupta {
425b43ebc65SAshish Gupta 	struct zip_vf *vf = (struct zip_vf *) (dev->data->dev_private);
426b43ebc65SAshish Gupta 	struct zip_stream *z_stream;
427b43ebc65SAshish Gupta 
428b43ebc65SAshish Gupta 	if (stream == NULL)
429b43ebc65SAshish Gupta 		return 0;
430b43ebc65SAshish Gupta 
431b43ebc65SAshish Gupta 	z_stream = (struct zip_stream *)stream;
432b43ebc65SAshish Gupta 
433b43ebc65SAshish Gupta 	/* Free resources back to pool */
434b43ebc65SAshish Gupta 	rte_mempool_put_bulk(vf->zip_mp,
435b43ebc65SAshish Gupta 				(void *)&(z_stream->bufs[0]),
436*938f3f5fSMahipal Challa 				(MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE));
437b43ebc65SAshish Gupta 
438b43ebc65SAshish Gupta 	/* Zero out the whole structure */
439b43ebc65SAshish Gupta 	memset(stream, 0, sizeof(struct zip_stream));
440b43ebc65SAshish Gupta 	rte_free(stream);
441b43ebc65SAshish Gupta 
442b43ebc65SAshish Gupta 	return 0;
443b43ebc65SAshish Gupta }
444b43ebc65SAshish Gupta 
445b43ebc65SAshish Gupta 
44652048f8fSAshish Gupta static uint16_t
447*938f3f5fSMahipal Challa zip_pmd_enqueue_burst(void *queue_pair,
44852048f8fSAshish Gupta 		struct rte_comp_op **ops, uint16_t nb_ops)
44952048f8fSAshish Gupta {
45052048f8fSAshish Gupta 	struct zipvf_qp *qp = queue_pair;
45152048f8fSAshish Gupta 	struct zip_stream *zstrm;
452*938f3f5fSMahipal Challa 	struct rte_comp_op *op;
45352048f8fSAshish Gupta 	int i, ret = 0;
45452048f8fSAshish Gupta 	uint16_t enqd = 0;
45552048f8fSAshish Gupta 
45652048f8fSAshish Gupta 	for (i = 0; i < nb_ops; i++) {
45752048f8fSAshish Gupta 		op = ops[i];
45852048f8fSAshish Gupta 
45952048f8fSAshish Gupta 		if (op->op_type == RTE_COMP_OP_STATEFUL) {
46052048f8fSAshish Gupta 			op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
46152048f8fSAshish Gupta 		} else {
46252048f8fSAshish Gupta 			/* process stateless ops */
46352048f8fSAshish Gupta 			zstrm = (struct zip_stream *)op->private_xform;
46452048f8fSAshish Gupta 			if (unlikely(zstrm == NULL))
46552048f8fSAshish Gupta 				op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
46652048f8fSAshish Gupta 			else
467*938f3f5fSMahipal Challa 				ret = zstrm->func(op, qp, zstrm, i);
46852048f8fSAshish Gupta 		}
46952048f8fSAshish Gupta 
47052048f8fSAshish Gupta 		/* Whatever is out of op, put it into completion queue with
47152048f8fSAshish Gupta 		 * its status
47252048f8fSAshish Gupta 		 */
47352048f8fSAshish Gupta 		if (!ret)
47452048f8fSAshish Gupta 			ret = rte_ring_enqueue(qp->processed_pkts, (void *)op);
47552048f8fSAshish Gupta 
47652048f8fSAshish Gupta 		if (unlikely(ret < 0)) {
47752048f8fSAshish Gupta 			/* increment count if failed to enqueue op*/
47852048f8fSAshish Gupta 			qp->qp_stats.enqueue_err_count++;
47952048f8fSAshish Gupta 		} else {
48052048f8fSAshish Gupta 			qp->qp_stats.enqueued_count++;
48152048f8fSAshish Gupta 			enqd++;
48252048f8fSAshish Gupta 		}
48352048f8fSAshish Gupta 	}
484*938f3f5fSMahipal Challa 
485*938f3f5fSMahipal Challa #ifdef ZIP_DBG
486*938f3f5fSMahipal Challa 	ZIP_PMD_INFO("ops_enqd[nb_ops:%d]:%d\n", nb_ops, enqd);
487*938f3f5fSMahipal Challa #endif
48852048f8fSAshish Gupta 	return enqd;
48952048f8fSAshish Gupta }
49052048f8fSAshish Gupta 
49152048f8fSAshish Gupta static uint16_t
492*938f3f5fSMahipal Challa zip_pmd_dequeue_burst(void *queue_pair,
49352048f8fSAshish Gupta 		struct rte_comp_op **ops, uint16_t nb_ops)
49452048f8fSAshish Gupta {
495*938f3f5fSMahipal Challa 	volatile union zip_zres_s *zresult = NULL;
49652048f8fSAshish Gupta 	struct zipvf_qp *qp = queue_pair;
49752048f8fSAshish Gupta 
49852048f8fSAshish Gupta 	unsigned int nb_dequeued = 0;
499*938f3f5fSMahipal Challa 	struct zip_stream *zstrm;
500*938f3f5fSMahipal Challa 	struct rte_comp_op *op;
501*938f3f5fSMahipal Challa 	unsigned int i;
50252048f8fSAshish Gupta 
50352048f8fSAshish Gupta 	nb_dequeued = rte_ring_dequeue_burst(qp->processed_pkts,
50452048f8fSAshish Gupta 				(void **)ops, nb_ops, NULL);
50552048f8fSAshish Gupta 	qp->qp_stats.dequeued_count += nb_dequeued;
50652048f8fSAshish Gupta 
507*938f3f5fSMahipal Challa 	/* Dequeue all the submitted ops */
508*938f3f5fSMahipal Challa 	for (i = 0; i < nb_dequeued; i++) {
509*938f3f5fSMahipal Challa 		op = ops[i];
510*938f3f5fSMahipal Challa 		/* process stateless ops */
511*938f3f5fSMahipal Challa 		zstrm = (struct zip_stream *)op->private_xform;
512*938f3f5fSMahipal Challa 		zresult = (union zip_zres_s *)zstrm->bufs[RES_BUF + i];
513*938f3f5fSMahipal Challa 
514*938f3f5fSMahipal Challa 		/* Check and Process results in sync mode */
515*938f3f5fSMahipal Challa 		do {
516*938f3f5fSMahipal Challa 		} while (!zresult->s.compcode);
517*938f3f5fSMahipal Challa 
518*938f3f5fSMahipal Challa 		if (zresult->s.compcode == ZIP_COMP_E_SUCCESS) {
519*938f3f5fSMahipal Challa 			op->status = RTE_COMP_OP_STATUS_SUCCESS;
520*938f3f5fSMahipal Challa 		} else {
521*938f3f5fSMahipal Challa 			/* FATAL error cannot do anything */
522*938f3f5fSMahipal Challa 			ZIP_PMD_ERR("operation failed with error code:%d\n",
523*938f3f5fSMahipal Challa 				zresult->s.compcode);
524*938f3f5fSMahipal Challa 			if (zresult->s.compcode == ZIP_COMP_E_DSTOP)
525*938f3f5fSMahipal Challa 				op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
526*938f3f5fSMahipal Challa 			else
527*938f3f5fSMahipal Challa 				op->status = RTE_COMP_OP_STATUS_ERROR;
528*938f3f5fSMahipal Challa 		}
529*938f3f5fSMahipal Challa 
530*938f3f5fSMahipal Challa 	#ifdef ZIP_DBG
531*938f3f5fSMahipal Challa 		ZIP_PMD_INFO("written %d\n", zresult->s.totalbyteswritten);
532*938f3f5fSMahipal Challa 	#endif
533*938f3f5fSMahipal Challa 
534*938f3f5fSMahipal Challa 		/* Update op stats */
535*938f3f5fSMahipal Challa 		switch (op->status) {
536*938f3f5fSMahipal Challa 		case RTE_COMP_OP_STATUS_SUCCESS:
537*938f3f5fSMahipal Challa 			op->consumed = zresult->s.totalbytesread;
538*938f3f5fSMahipal Challa 		/* Fall-through */
539*938f3f5fSMahipal Challa 		case RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED:
540*938f3f5fSMahipal Challa 			op->produced = zresult->s.totalbyteswritten;
541*938f3f5fSMahipal Challa 			break;
542*938f3f5fSMahipal Challa 		default:
543*938f3f5fSMahipal Challa 			ZIP_PMD_ERR("stats not updated for status:%d\n",
544*938f3f5fSMahipal Challa 				    op->status);
545*938f3f5fSMahipal Challa 			break;
546*938f3f5fSMahipal Challa 		}
547*938f3f5fSMahipal Challa 
548*938f3f5fSMahipal Challa 		/* zstream is reset irrespective of result */
549*938f3f5fSMahipal Challa 		reset_stream(zstrm->inst[i]);
550*938f3f5fSMahipal Challa 		zresult->s.compcode = ZIP_COMP_E_NOTDONE;
551*938f3f5fSMahipal Challa 	}
552*938f3f5fSMahipal Challa 
553*938f3f5fSMahipal Challa #ifdef ZIP_DBG
554*938f3f5fSMahipal Challa 	ZIP_PMD_INFO("ops_deqd[nb_ops:%d]: %d\n", nb_ops, nb_dequeued);
555*938f3f5fSMahipal Challa #endif
55652048f8fSAshish Gupta 	return nb_dequeued;
55752048f8fSAshish Gupta }
55852048f8fSAshish Gupta 
559b74fd6b8SFerruh Yigit static struct rte_compressdev_ops octtx_zip_pmd_ops = {
560c378f084SAshish Gupta 		.dev_configure		= zip_pmd_config,
561c378f084SAshish Gupta 		.dev_start		= zip_pmd_start,
562c378f084SAshish Gupta 		.dev_stop		= zip_pmd_stop,
563c378f084SAshish Gupta 		.dev_close		= zip_pmd_close,
564c378f084SAshish Gupta 
565c378f084SAshish Gupta 		.stats_get		= zip_pmd_stats_get,
566c378f084SAshish Gupta 		.stats_reset		= zip_pmd_stats_reset,
567c378f084SAshish Gupta 
568c378f084SAshish Gupta 		.dev_infos_get		= zip_pmd_info_get,
569c378f084SAshish Gupta 
570c378f084SAshish Gupta 		.queue_pair_setup	= zip_pmd_qp_setup,
571c378f084SAshish Gupta 		.queue_pair_release	= zip_pmd_qp_release,
572b43ebc65SAshish Gupta 
573b43ebc65SAshish Gupta 		.private_xform_create	= zip_pmd_stream_create,
574b43ebc65SAshish Gupta 		.private_xform_free	= zip_pmd_stream_free,
575b43ebc65SAshish Gupta 		.stream_create		= NULL,
576b43ebc65SAshish Gupta 		.stream_free		= NULL
57743e610bbSSunila Sahu };
57843e610bbSSunila Sahu 
57943e610bbSSunila Sahu static int
58043e610bbSSunila Sahu zip_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
58143e610bbSSunila Sahu 	struct rte_pci_device *pci_dev)
58243e610bbSSunila Sahu {
58343e610bbSSunila Sahu 	int ret = 0;
58443e610bbSSunila Sahu 	char compressdev_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
58543e610bbSSunila Sahu 	struct rte_compressdev *compressdev;
58643e610bbSSunila Sahu 	struct rte_compressdev_pmd_init_params init_params = {
58743e610bbSSunila Sahu 		"",
58843e610bbSSunila Sahu 		rte_socket_id(),
58943e610bbSSunila Sahu 	};
59043e610bbSSunila Sahu 
59143e610bbSSunila Sahu 	ZIP_PMD_INFO("vendor_id=0x%x device_id=0x%x",
59243e610bbSSunila Sahu 			(unsigned int)pci_dev->id.vendor_id,
59343e610bbSSunila Sahu 			(unsigned int)pci_dev->id.device_id);
59443e610bbSSunila Sahu 
59543e610bbSSunila Sahu 	rte_pci_device_name(&pci_dev->addr, compressdev_name,
59643e610bbSSunila Sahu 			    sizeof(compressdev_name));
59743e610bbSSunila Sahu 
59843e610bbSSunila Sahu 	compressdev = rte_compressdev_pmd_create(compressdev_name,
59943e610bbSSunila Sahu 		&pci_dev->device, sizeof(struct zip_vf), &init_params);
60043e610bbSSunila Sahu 	if (compressdev == NULL) {
60143e610bbSSunila Sahu 		ZIP_PMD_ERR("driver %s: create failed", init_params.name);
60243e610bbSSunila Sahu 		return -ENODEV;
60343e610bbSSunila Sahu 	}
60443e610bbSSunila Sahu 
60543e610bbSSunila Sahu 	/*
60643e610bbSSunila Sahu 	 * create only if proc_type is primary.
60743e610bbSSunila Sahu 	 */
60843e610bbSSunila Sahu 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
60943e610bbSSunila Sahu 		/*  create vf dev with given pmd dev id */
61043e610bbSSunila Sahu 		ret = zipvf_create(compressdev);
61143e610bbSSunila Sahu 		if (ret < 0) {
61243e610bbSSunila Sahu 			ZIP_PMD_ERR("Device creation failed");
61343e610bbSSunila Sahu 			rte_compressdev_pmd_destroy(compressdev);
61443e610bbSSunila Sahu 			return ret;
61543e610bbSSunila Sahu 		}
61643e610bbSSunila Sahu 	}
61743e610bbSSunila Sahu 
61843e610bbSSunila Sahu 	compressdev->dev_ops = &octtx_zip_pmd_ops;
61943e610bbSSunila Sahu 	/* register rx/tx burst functions for data path */
620*938f3f5fSMahipal Challa 	compressdev->dequeue_burst = zip_pmd_dequeue_burst;
621*938f3f5fSMahipal Challa 	compressdev->enqueue_burst = zip_pmd_enqueue_burst;
62243e610bbSSunila Sahu 	compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;
62343e610bbSSunila Sahu 	return ret;
62443e610bbSSunila Sahu }
62543e610bbSSunila Sahu 
62643e610bbSSunila Sahu static int
62743e610bbSSunila Sahu zip_pci_remove(struct rte_pci_device *pci_dev)
62843e610bbSSunila Sahu {
62943e610bbSSunila Sahu 	struct rte_compressdev *compressdev;
63043e610bbSSunila Sahu 	char compressdev_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
63143e610bbSSunila Sahu 
63243e610bbSSunila Sahu 	if (pci_dev == NULL) {
63343e610bbSSunila Sahu 		ZIP_PMD_ERR(" Invalid PCI Device\n");
63443e610bbSSunila Sahu 		return -EINVAL;
63543e610bbSSunila Sahu 	}
63643e610bbSSunila Sahu 	rte_pci_device_name(&pci_dev->addr, compressdev_name,
63743e610bbSSunila Sahu 			sizeof(compressdev_name));
63843e610bbSSunila Sahu 
63943e610bbSSunila Sahu 	compressdev = rte_compressdev_pmd_get_named_dev(compressdev_name);
64043e610bbSSunila Sahu 	if (compressdev == NULL)
64143e610bbSSunila Sahu 		return -ENODEV;
64243e610bbSSunila Sahu 
64343e610bbSSunila Sahu 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
64443e610bbSSunila Sahu 		if (zipvf_destroy(compressdev) < 0)
64543e610bbSSunila Sahu 			return -ENODEV;
64643e610bbSSunila Sahu 	}
64743e610bbSSunila Sahu 	return rte_compressdev_pmd_destroy(compressdev);
64843e610bbSSunila Sahu }
64943e610bbSSunila Sahu 
65043e610bbSSunila Sahu static struct rte_pci_id pci_id_octtx_zipvf_table[] = {
65143e610bbSSunila Sahu 	{
65243e610bbSSunila Sahu 		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
65343e610bbSSunila Sahu 			PCI_DEVICE_ID_OCTEONTX_ZIPVF),
65443e610bbSSunila Sahu 	},
65543e610bbSSunila Sahu 	{
656a80ea5c0SMahipal Challa 		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
657a80ea5c0SMahipal Challa 			PCI_DEVICE_ID_OCTEONTX2_ZIPVF),
658a80ea5c0SMahipal Challa 	},
659a80ea5c0SMahipal Challa 	{
66043e610bbSSunila Sahu 		.device_id = 0
66143e610bbSSunila Sahu 	},
66243e610bbSSunila Sahu };
66343e610bbSSunila Sahu 
66443e610bbSSunila Sahu /**
66543e610bbSSunila Sahu  * Structure that represents a PCI driver
66643e610bbSSunila Sahu  */
66743e610bbSSunila Sahu static struct rte_pci_driver octtx_zip_pmd = {
66843e610bbSSunila Sahu 	.id_table    = pci_id_octtx_zipvf_table,
66943e610bbSSunila Sahu 	.drv_flags   = RTE_PCI_DRV_NEED_MAPPING,
67043e610bbSSunila Sahu 	.probe       = zip_pci_probe,
67143e610bbSSunila Sahu 	.remove      = zip_pci_remove,
67243e610bbSSunila Sahu };
67343e610bbSSunila Sahu 
67443e610bbSSunila Sahu RTE_PMD_REGISTER_PCI(COMPRESSDEV_NAME_ZIP_PMD, octtx_zip_pmd);
67543e610bbSSunila Sahu RTE_PMD_REGISTER_PCI_TABLE(COMPRESSDEV_NAME_ZIP_PMD, pci_id_octtx_zipvf_table);
676eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(octtx_zip_logtype_driver, INFO);
677