xref: /dpdk/drivers/compress/octeontx/otx_zip_pmd.c (revision f665790a5dbad7b645ff46f31d65e977324e7bfc)
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 |
1909442498SMahipal Challa 					RTE_COMP_FF_HUFFMAN_DYNAMIC |
2009442498SMahipal Challa 					RTE_COMP_FF_OOP_SGL_IN_SGL_OUT |
2109442498SMahipal Challa 					RTE_COMP_FF_OOP_SGL_IN_LB_OUT |
2209442498SMahipal Challa 					RTE_COMP_FF_OOP_LB_IN_SGL_OUT,
23c378f084SAshish Gupta 		/* Non sharable Priv XFORM and Stateless */
24c378f084SAshish Gupta 		.window_size = {
25c378f084SAshish Gupta 				.min = 1,
26c378f084SAshish Gupta 				.max = 14,
27c378f084SAshish Gupta 				.increment = 1
28c378f084SAshish Gupta 				/* size supported 2^1 to 2^14 */
29c378f084SAshish Gupta 		},
30c378f084SAshish Gupta 	},
31c378f084SAshish Gupta 	RTE_COMP_END_OF_CAPABILITIES_LIST()
32c378f084SAshish Gupta };
3343e610bbSSunila Sahu 
3452048f8fSAshish Gupta /*
3552048f8fSAshish Gupta  * Reset session to default state for next set of stateless operation
3652048f8fSAshish Gupta  */
3752048f8fSAshish Gupta static inline void
38938f3f5fSMahipal Challa reset_stream(union zip_inst_s *inst)
3952048f8fSAshish Gupta {
4052048f8fSAshish Gupta 	inst->s.bf = 1;
4152048f8fSAshish Gupta 	inst->s.ef = 0;
4252048f8fSAshish Gupta }
4352048f8fSAshish Gupta 
4452048f8fSAshish Gupta int
4552048f8fSAshish Gupta zip_process_op(struct rte_comp_op *op,
4652048f8fSAshish Gupta 		struct zipvf_qp *qp,
47938f3f5fSMahipal Challa 		struct zip_stream *zstrm, int num)
4852048f8fSAshish Gupta {
49938f3f5fSMahipal Challa 	union zip_inst_s *inst = zstrm->inst[num];
5052048f8fSAshish Gupta 	volatile union zip_zres_s *zresult = NULL;
5152048f8fSAshish Gupta 
5209442498SMahipal Challa 	if (op->m_src->nb_segs > 1)
5309442498SMahipal Challa 		if (rte_mempool_get(qp->vf->sg_mp, (void *)&qp->g_info) < 0) {
5409442498SMahipal Challa 			ZIP_PMD_ERR("Can't1 allocate object from SG pool");
5509442498SMahipal Challa 			return (-ENOMEM);
5652048f8fSAshish Gupta 		}
5752048f8fSAshish Gupta 
5809442498SMahipal Challa 	if (op->m_dst->nb_segs > 1)
5909442498SMahipal Challa 		if (rte_mempool_get(qp->vf->sg_mp, (void *)&qp->s_info) < 0) {
6009442498SMahipal Challa 			rte_mempool_put(qp->vf->sg_mp, qp->g_info);
6109442498SMahipal Challa 			ZIP_PMD_ERR("Can't allocate object from SG pool");
6209442498SMahipal Challa 			return (-ENOMEM);
6309442498SMahipal Challa 		}
6409442498SMahipal Challa 
6509442498SMahipal Challa 	if (zipvf_prepare_cmd_stateless(op, qp, inst)) {
6609442498SMahipal Challa 		op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
6709442498SMahipal Challa 		rte_mempool_put(qp->vf->sg_mp, qp->g_info);
6809442498SMahipal Challa 		rte_mempool_put(qp->vf->sg_mp, qp->s_info);
6909442498SMahipal Challa 
7009442498SMahipal Challa 		ZIP_PMD_ERR("Can't fill SGL buffers");
7109442498SMahipal Challa 		return -EINVAL;
7209442498SMahipal Challa 	}
7352048f8fSAshish Gupta 
74938f3f5fSMahipal Challa 	zresult = (union zip_zres_s *)zstrm->bufs[RES_BUF + num];
7552048f8fSAshish Gupta 	zresult->s.compcode = 0;
7652048f8fSAshish Gupta 
7752048f8fSAshish Gupta #ifdef ZIP_DBG
7852048f8fSAshish Gupta 	zip_dump_instruction(inst);
7952048f8fSAshish Gupta #endif
8052048f8fSAshish Gupta 
8152048f8fSAshish Gupta 	/* Submit zip command */
8252048f8fSAshish Gupta 	zipvf_push_command(qp, (void *)inst);
8352048f8fSAshish Gupta 
8452048f8fSAshish Gupta 	return 0;
8552048f8fSAshish Gupta }
8652048f8fSAshish Gupta 
87b43ebc65SAshish Gupta /** Parse xform parameters and setup a stream */
88b43ebc65SAshish Gupta static int
89b43ebc65SAshish Gupta zip_set_stream_parameters(struct rte_compressdev *dev,
90b43ebc65SAshish Gupta 			const struct rte_comp_xform *xform,
91b43ebc65SAshish Gupta 			struct zip_stream *z_stream)
92b43ebc65SAshish Gupta {
93b43ebc65SAshish Gupta 	struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private;
94938f3f5fSMahipal Challa 	union zip_inst_s *inst;
95b43ebc65SAshish Gupta 	void *res;
96938f3f5fSMahipal Challa 	int ret, i;
97b43ebc65SAshish Gupta 
98b43ebc65SAshish Gupta 	/* Allocate resources required by a stream */
99b43ebc65SAshish Gupta 	ret = rte_mempool_get_bulk(vf->zip_mp,
100938f3f5fSMahipal Challa 			z_stream->bufs, (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE));
101b43ebc65SAshish Gupta 	if (ret < 0)
102b43ebc65SAshish Gupta 		return -1;
103b43ebc65SAshish Gupta 
104938f3f5fSMahipal Challa 	for (i = 0; i < ZIP_BURST_SIZE; i++) {
105b43ebc65SAshish Gupta 		/* get one command buffer from pool and set up */
106938f3f5fSMahipal Challa 		inst = (union zip_inst_s *)z_stream->bufs[(CMD_BUF * ZIP_BURST_SIZE) + i];
107938f3f5fSMahipal Challa 		res = z_stream->bufs[(RES_BUF * ZIP_BURST_SIZE) + i];
108b43ebc65SAshish Gupta 		memset(inst->u, 0, sizeof(inst->u));
109b43ebc65SAshish Gupta 
110b43ebc65SAshish Gupta 		/* set bf for only first ops of stream */
111b43ebc65SAshish Gupta 		inst->s.bf = 1;
112b43ebc65SAshish Gupta 
113b43ebc65SAshish Gupta 		if (xform->type == RTE_COMP_COMPRESS) {
114b43ebc65SAshish Gupta 			inst->s.op = ZIP_OP_E_COMP;
115b43ebc65SAshish Gupta 
116b43ebc65SAshish Gupta 			switch (xform->compress.deflate.huffman) {
117b43ebc65SAshish Gupta 			case RTE_COMP_HUFFMAN_DEFAULT:
118b43ebc65SAshish Gupta 				inst->s.cc = ZIP_CC_DEFAULT;
119b43ebc65SAshish Gupta 				break;
120b43ebc65SAshish Gupta 			case RTE_COMP_HUFFMAN_FIXED:
121b43ebc65SAshish Gupta 				inst->s.cc = ZIP_CC_FIXED_HUFF;
122b43ebc65SAshish Gupta 				break;
123b43ebc65SAshish Gupta 			case RTE_COMP_HUFFMAN_DYNAMIC:
124b43ebc65SAshish Gupta 				inst->s.cc = ZIP_CC_DYN_HUFF;
125b43ebc65SAshish Gupta 				break;
126b43ebc65SAshish Gupta 			default:
127b43ebc65SAshish Gupta 				ret = -1;
128b43ebc65SAshish Gupta 				goto err;
129b43ebc65SAshish Gupta 			}
130b43ebc65SAshish Gupta 
131b43ebc65SAshish Gupta 			switch (xform->compress.level) {
132b43ebc65SAshish Gupta 			case RTE_COMP_LEVEL_MIN:
133b43ebc65SAshish Gupta 				inst->s.ss = ZIP_COMP_E_LEVEL_MIN;
134b43ebc65SAshish Gupta 				break;
135b43ebc65SAshish Gupta 			case RTE_COMP_LEVEL_MAX:
136b43ebc65SAshish Gupta 				inst->s.ss = ZIP_COMP_E_LEVEL_MAX;
137b43ebc65SAshish Gupta 				break;
138b43ebc65SAshish Gupta 			case RTE_COMP_LEVEL_NONE:
139b43ebc65SAshish Gupta 				ZIP_PMD_ERR("Compression level not supported");
140b43ebc65SAshish Gupta 				ret = -1;
141b43ebc65SAshish Gupta 				goto err;
142b43ebc65SAshish Gupta 			default:
143b43ebc65SAshish Gupta 				/* for any value between min and max , choose
144b43ebc65SAshish Gupta 				 * PMD default.
145b43ebc65SAshish Gupta 				 */
146b43ebc65SAshish Gupta 				inst->s.ss = ZIP_COMP_E_LEVEL_MED; /** PMD default **/
147b43ebc65SAshish Gupta 				break;
148b43ebc65SAshish Gupta 			}
149b43ebc65SAshish Gupta 		} else if (xform->type == RTE_COMP_DECOMPRESS) {
150b43ebc65SAshish Gupta 			inst->s.op = ZIP_OP_E_DECOMP;
151b43ebc65SAshish Gupta 			/* from HRM,
152b43ebc65SAshish Gupta 			 * For DEFLATE decompression, [CC] must be 0x0.
153b43ebc65SAshish Gupta 			 * For decompression, [SS] must be 0x0
154b43ebc65SAshish Gupta 			 */
155b43ebc65SAshish Gupta 			inst->s.cc = 0;
156b43ebc65SAshish Gupta 			/* Speed bit should not be set for decompression */
157b43ebc65SAshish Gupta 			inst->s.ss = 0;
158b43ebc65SAshish Gupta 			/* decompression context is supported only for STATEFUL
159b43ebc65SAshish Gupta 			 * operations. Currently we support STATELESS ONLY so
160b43ebc65SAshish Gupta 			 * skip setting of ctx pointer
161b43ebc65SAshish Gupta 			 */
162b43ebc65SAshish Gupta 
163b43ebc65SAshish Gupta 		} else {
164*f665790aSDavid Marchand 			ZIP_PMD_ERR("xform type not supported");
165b43ebc65SAshish Gupta 			ret = -1;
166b43ebc65SAshish Gupta 			goto err;
167b43ebc65SAshish Gupta 		}
168b43ebc65SAshish Gupta 
169b43ebc65SAshish Gupta 		inst->s.res_ptr_addr.s.addr = rte_mempool_virt2iova(res);
170b43ebc65SAshish Gupta 		inst->s.res_ptr_ctl.s.length = 0;
171b43ebc65SAshish Gupta 
172938f3f5fSMahipal Challa 		z_stream->inst[i] = inst;
173938f3f5fSMahipal Challa 	}
174938f3f5fSMahipal Challa 
17552048f8fSAshish Gupta 	z_stream->func = zip_process_op;
176b43ebc65SAshish Gupta 
177b43ebc65SAshish Gupta 	return 0;
178b43ebc65SAshish Gupta 
179b43ebc65SAshish Gupta err:
180b43ebc65SAshish Gupta 	rte_mempool_put_bulk(vf->zip_mp,
181b43ebc65SAshish Gupta 			     (void *)&(z_stream->bufs[0]),
182938f3f5fSMahipal Challa 			     (MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE));
183b43ebc65SAshish Gupta 
184b43ebc65SAshish Gupta 	return ret;
185b43ebc65SAshish Gupta }
186b43ebc65SAshish Gupta 
187c378f084SAshish Gupta /** Configure device */
188c378f084SAshish Gupta static int
189c378f084SAshish Gupta zip_pmd_config(struct rte_compressdev *dev,
190c378f084SAshish Gupta 		struct rte_compressdev_config *config)
191c378f084SAshish Gupta {
192c378f084SAshish Gupta 	char res_pool[RTE_MEMZONE_NAMESIZE];
19309442498SMahipal Challa 	char sg_pool[RTE_MEMZONE_NAMESIZE];
194c378f084SAshish Gupta 	struct rte_mempool *zip_buf_mp;
19509442498SMahipal Challa 	struct rte_mempool *zip_sg_mp;
19609442498SMahipal Challa 	struct zip_vf *vf;
19709442498SMahipal Challa 	int nb_streams;
198c378f084SAshish Gupta 
199c378f084SAshish Gupta 	if (!config || !dev)
200c378f084SAshish Gupta 		return -EIO;
201c378f084SAshish Gupta 
202c378f084SAshish Gupta 	vf = (struct zip_vf *)(dev->data->dev_private);
203c378f084SAshish Gupta 
204c378f084SAshish Gupta 	/* create pool with maximum numbers of resources
205c378f084SAshish Gupta 	 * required by streams
206c378f084SAshish Gupta 	 */
207c378f084SAshish Gupta 
208c378f084SAshish Gupta 	/* use common pool for non-shareable priv_xform and stream */
209c378f084SAshish Gupta 	nb_streams = config->max_nb_priv_xforms + config->max_nb_streams;
210c378f084SAshish Gupta 
211c378f084SAshish Gupta 	snprintf(res_pool, RTE_MEMZONE_NAMESIZE, "octtx_zip_res_pool%u",
212c378f084SAshish Gupta 		 dev->data->dev_id);
213c378f084SAshish Gupta 
21409442498SMahipal Challa 	snprintf(sg_pool, RTE_MEMZONE_NAMESIZE, "octtx_zip_sg_pool%u",
21509442498SMahipal Challa 		 dev->data->dev_id);
21609442498SMahipal Challa 
217c378f084SAshish Gupta 	/** TBD Should we use the per core object cache for stream resources */
218c378f084SAshish Gupta 	zip_buf_mp = rte_mempool_create(
219c378f084SAshish Gupta 			res_pool,
220938f3f5fSMahipal Challa 			(nb_streams * MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE),
221c378f084SAshish Gupta 			ZIP_BUF_SIZE,
222c378f084SAshish Gupta 			0,
223c378f084SAshish Gupta 			0,
224c378f084SAshish Gupta 			NULL,
225c378f084SAshish Gupta 			NULL,
226c378f084SAshish Gupta 			NULL,
227c378f084SAshish Gupta 			NULL,
228c378f084SAshish Gupta 			SOCKET_ID_ANY,
229c378f084SAshish Gupta 			0);
230c378f084SAshish Gupta 
231c378f084SAshish Gupta 	if (zip_buf_mp == NULL) {
232c378f084SAshish Gupta 		ZIP_PMD_ERR(
233c378f084SAshish Gupta 			"Failed to create buf mempool octtx_zip_res_pool%u",
234c378f084SAshish Gupta 			dev->data->dev_id);
235c378f084SAshish Gupta 		return -1;
236c378f084SAshish Gupta 	}
237c378f084SAshish Gupta 
23809442498SMahipal Challa 	/* Scatter gather buffer pool */
23909442498SMahipal Challa 	zip_sg_mp = rte_mempool_create(
24009442498SMahipal Challa 			sg_pool,
24109442498SMahipal Challa 			(2 * nb_streams * ZIP_BURST_SIZE * ZIP_MAX_SEGS),
24209442498SMahipal Challa 			ZIP_SGBUF_SIZE,
24309442498SMahipal Challa 			0,
24409442498SMahipal Challa 			0,
24509442498SMahipal Challa 			NULL,
24609442498SMahipal Challa 			NULL,
24709442498SMahipal Challa 			NULL,
24809442498SMahipal Challa 			NULL,
24909442498SMahipal Challa 			SOCKET_ID_ANY,
25009442498SMahipal Challa 			MEMPOOL_F_NO_SPREAD);
25109442498SMahipal Challa 
25209442498SMahipal Challa 	if (zip_sg_mp == NULL) {
25309442498SMahipal Challa 		ZIP_PMD_ERR("Failed to create SG buf mempool octtx_zip_sg_pool%u",
25409442498SMahipal Challa 			    dev->data->dev_id);
25509442498SMahipal Challa 
25609442498SMahipal Challa 		rte_mempool_free(vf->zip_mp);
25709442498SMahipal Challa 		return -1;
25809442498SMahipal Challa 	}
25909442498SMahipal Challa 
260c378f084SAshish Gupta 	vf->zip_mp = zip_buf_mp;
26109442498SMahipal Challa 	vf->sg_mp = zip_sg_mp;
262c378f084SAshish Gupta 
263c378f084SAshish Gupta 	return 0;
264c378f084SAshish Gupta }
265c378f084SAshish Gupta 
266c378f084SAshish Gupta /** Start device */
267c378f084SAshish Gupta static int
268c378f084SAshish Gupta zip_pmd_start(__rte_unused struct rte_compressdev *dev)
269c378f084SAshish Gupta {
270c378f084SAshish Gupta 	return 0;
271c378f084SAshish Gupta }
272c378f084SAshish Gupta 
273c378f084SAshish Gupta /** Stop device */
274c378f084SAshish Gupta static void
275c378f084SAshish Gupta zip_pmd_stop(__rte_unused struct rte_compressdev *dev)
276c378f084SAshish Gupta {
277c378f084SAshish Gupta 
278c378f084SAshish Gupta }
279c378f084SAshish Gupta 
280c378f084SAshish Gupta /** Close device */
281c378f084SAshish Gupta static int
282c378f084SAshish Gupta zip_pmd_close(struct rte_compressdev *dev)
283c378f084SAshish Gupta {
284c378f084SAshish Gupta 	if (dev == NULL)
285c378f084SAshish Gupta 		return -1;
286c378f084SAshish Gupta 
287c378f084SAshish Gupta 	struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private;
288c378f084SAshish Gupta 	rte_mempool_free(vf->zip_mp);
28909442498SMahipal Challa 	rte_mempool_free(vf->sg_mp);
290c378f084SAshish Gupta 
291c378f084SAshish Gupta 	return 0;
292c378f084SAshish Gupta }
293c378f084SAshish Gupta 
294c378f084SAshish Gupta /** Get device statistics */
295c378f084SAshish Gupta static void
296c378f084SAshish Gupta zip_pmd_stats_get(struct rte_compressdev *dev,
297c378f084SAshish Gupta 		struct rte_compressdev_stats *stats)
298c378f084SAshish Gupta {
299c378f084SAshish Gupta 	int qp_id;
300c378f084SAshish Gupta 
301c378f084SAshish Gupta 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
302c378f084SAshish Gupta 		struct zipvf_qp *qp = dev->data->queue_pairs[qp_id];
303c378f084SAshish Gupta 
304c378f084SAshish Gupta 		stats->enqueued_count += qp->qp_stats.enqueued_count;
305c378f084SAshish Gupta 		stats->dequeued_count += qp->qp_stats.dequeued_count;
306c378f084SAshish Gupta 
307c378f084SAshish Gupta 		stats->enqueue_err_count += qp->qp_stats.enqueue_err_count;
308c378f084SAshish Gupta 		stats->dequeue_err_count += qp->qp_stats.dequeue_err_count;
309c378f084SAshish Gupta 	}
310c378f084SAshish Gupta }
311c378f084SAshish Gupta 
312c378f084SAshish Gupta /** Reset device statistics */
313c378f084SAshish Gupta static void
314c378f084SAshish Gupta zip_pmd_stats_reset(struct rte_compressdev *dev)
315c378f084SAshish Gupta {
316c378f084SAshish Gupta 	int qp_id;
317c378f084SAshish Gupta 
318c378f084SAshish Gupta 	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
319c378f084SAshish Gupta 		struct zipvf_qp *qp = dev->data->queue_pairs[qp_id];
320c378f084SAshish Gupta 		memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
321c378f084SAshish Gupta 	}
322c378f084SAshish Gupta }
323c378f084SAshish Gupta 
324c378f084SAshish Gupta /** Get device info */
325c378f084SAshish Gupta static void
326c378f084SAshish Gupta zip_pmd_info_get(struct rte_compressdev *dev,
327c378f084SAshish Gupta 		struct rte_compressdev_info *dev_info)
328c378f084SAshish Gupta {
329c378f084SAshish Gupta 	struct zip_vf *vf = (struct zip_vf *)dev->data->dev_private;
330c378f084SAshish Gupta 
331c378f084SAshish Gupta 	if (dev_info != NULL) {
332c378f084SAshish Gupta 		dev_info->driver_name = dev->device->driver->name;
333c378f084SAshish Gupta 		dev_info->feature_flags = dev->feature_flags;
334c378f084SAshish Gupta 		dev_info->capabilities = octtx_zip_pmd_capabilities;
335c378f084SAshish Gupta 		dev_info->max_nb_queue_pairs = vf->max_nb_queue_pairs;
336c378f084SAshish Gupta 	}
337c378f084SAshish Gupta }
338c378f084SAshish Gupta 
339c378f084SAshish Gupta /** Release queue pair */
340c378f084SAshish Gupta static int
341c378f084SAshish Gupta zip_pmd_qp_release(struct rte_compressdev *dev, uint16_t qp_id)
342c378f084SAshish Gupta {
343c378f084SAshish Gupta 	struct zipvf_qp *qp = dev->data->queue_pairs[qp_id];
344c378f084SAshish Gupta 
345c378f084SAshish Gupta 	if (qp != NULL) {
346c378f084SAshish Gupta 		zipvf_q_term(qp);
347c378f084SAshish Gupta 
348c378f084SAshish Gupta 		rte_ring_free(qp->processed_pkts);
349c378f084SAshish Gupta 
350c378f084SAshish Gupta 		rte_free(qp);
351c378f084SAshish Gupta 		dev->data->queue_pairs[qp_id] = NULL;
352c378f084SAshish Gupta 	}
353c378f084SAshish Gupta 	return 0;
354c378f084SAshish Gupta }
355c378f084SAshish Gupta 
356c378f084SAshish Gupta /** Create a ring to place process packets on */
357c378f084SAshish Gupta static struct rte_ring *
358c378f084SAshish Gupta zip_pmd_qp_create_processed_pkts_ring(struct zipvf_qp *qp,
359c378f084SAshish Gupta 		unsigned int ring_size, int socket_id)
360c378f084SAshish Gupta {
361c378f084SAshish Gupta 	struct rte_ring *r;
362c378f084SAshish Gupta 
363c378f084SAshish Gupta 	r = rte_ring_lookup(qp->name);
364c378f084SAshish Gupta 	if (r) {
365c378f084SAshish Gupta 		if (rte_ring_get_size(r) >= ring_size) {
366c378f084SAshish Gupta 			ZIP_PMD_INFO("Reusing existing ring %s for processed"
367c378f084SAshish Gupta 					" packets", qp->name);
368c378f084SAshish Gupta 			return r;
369c378f084SAshish Gupta 		}
370c378f084SAshish Gupta 
371c378f084SAshish Gupta 		ZIP_PMD_ERR("Unable to reuse existing ring %s for processed"
372c378f084SAshish Gupta 				" packets", qp->name);
373c378f084SAshish Gupta 		return NULL;
374c378f084SAshish Gupta 	}
375c378f084SAshish Gupta 
376c378f084SAshish Gupta 	return rte_ring_create(qp->name, ring_size, socket_id,
377c378f084SAshish Gupta 						RING_F_EXACT_SZ);
378c378f084SAshish Gupta }
379c378f084SAshish Gupta 
380c378f084SAshish Gupta /** Setup a queue pair */
381c378f084SAshish Gupta static int
382c378f084SAshish Gupta zip_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
383c378f084SAshish Gupta 		uint32_t max_inflight_ops, int socket_id)
384c378f084SAshish Gupta {
385c378f084SAshish Gupta 	struct zipvf_qp *qp = NULL;
386c378f084SAshish Gupta 	struct zip_vf *vf;
387c378f084SAshish Gupta 	char *name;
388c378f084SAshish Gupta 	int ret;
389c378f084SAshish Gupta 
390c378f084SAshish Gupta 	if (!dev)
391c378f084SAshish Gupta 		return -1;
392c378f084SAshish Gupta 
393c378f084SAshish Gupta 	vf = (struct zip_vf *) (dev->data->dev_private);
394c378f084SAshish Gupta 
395c378f084SAshish Gupta 	/* Free memory prior to re-allocation if needed. */
396c378f084SAshish Gupta 	if (dev->data->queue_pairs[qp_id] != NULL) {
397c378f084SAshish Gupta 		ZIP_PMD_INFO("Using existing queue pair %d ", qp_id);
398c378f084SAshish Gupta 		return 0;
399c378f084SAshish Gupta 	}
400c378f084SAshish Gupta 
401c378f084SAshish Gupta 	name =  rte_malloc(NULL, RTE_COMPRESSDEV_NAME_MAX_LEN, 0);
402b072930fSWeiguo Li 	if (name == NULL)
403b072930fSWeiguo Li 		return (-ENOMEM);
404c378f084SAshish Gupta 	snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN,
405c378f084SAshish Gupta 		 "zip_pmd_%u_qp_%u",
406c378f084SAshish Gupta 		 dev->data->dev_id, qp_id);
407c378f084SAshish Gupta 
408c378f084SAshish Gupta 	/* Allocate the queue pair data structure. */
409c378f084SAshish Gupta 	qp = rte_zmalloc_socket(name, sizeof(*qp),
410c378f084SAshish Gupta 				RTE_CACHE_LINE_SIZE, socket_id);
411b072930fSWeiguo Li 	if (qp == NULL) {
412b072930fSWeiguo Li 		rte_free(name);
413c378f084SAshish Gupta 		return (-ENOMEM);
414b072930fSWeiguo Li 	}
415c378f084SAshish Gupta 
416c378f084SAshish Gupta 	qp->name = name;
417c378f084SAshish Gupta 
418c378f084SAshish Gupta 	/* Create completion queue up to max_inflight_ops */
419c378f084SAshish Gupta 	qp->processed_pkts = zip_pmd_qp_create_processed_pkts_ring(qp,
420c378f084SAshish Gupta 						max_inflight_ops, socket_id);
421c378f084SAshish Gupta 	if (qp->processed_pkts == NULL)
422c378f084SAshish Gupta 		goto qp_setup_cleanup;
423c378f084SAshish Gupta 
424c378f084SAshish Gupta 	qp->id = qp_id;
425c378f084SAshish Gupta 	qp->vf = vf;
426c378f084SAshish Gupta 
427c378f084SAshish Gupta 	ret = zipvf_q_init(qp);
428c378f084SAshish Gupta 	if (ret < 0)
429c378f084SAshish Gupta 		goto qp_setup_cleanup;
430c378f084SAshish Gupta 
431c378f084SAshish Gupta 	dev->data->queue_pairs[qp_id] = qp;
432c378f084SAshish Gupta 
433c378f084SAshish Gupta 	memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
434c378f084SAshish Gupta 	return 0;
435c378f084SAshish Gupta 
436c378f084SAshish Gupta qp_setup_cleanup:
437c378f084SAshish Gupta 	rte_ring_free(qp->processed_pkts);
438c378f084SAshish Gupta 	rte_free(qp);
439c378f084SAshish Gupta 	return -1;
440c378f084SAshish Gupta }
441c378f084SAshish Gupta 
442b43ebc65SAshish Gupta static int
443b43ebc65SAshish Gupta zip_pmd_stream_create(struct rte_compressdev *dev,
444b43ebc65SAshish Gupta 		const struct rte_comp_xform *xform, void **stream)
445b43ebc65SAshish Gupta {
446b43ebc65SAshish Gupta 	int ret;
447b43ebc65SAshish Gupta 	struct zip_stream *strm = NULL;
448b43ebc65SAshish Gupta 
449b43ebc65SAshish Gupta 	strm = rte_malloc(NULL,
450b43ebc65SAshish Gupta 			sizeof(struct zip_stream), 0);
451b43ebc65SAshish Gupta 
452b43ebc65SAshish Gupta 	if (strm == NULL)
453b43ebc65SAshish Gupta 		return (-ENOMEM);
454b43ebc65SAshish Gupta 
455b43ebc65SAshish Gupta 	ret = zip_set_stream_parameters(dev, xform, strm);
456b43ebc65SAshish Gupta 	if (ret < 0) {
457b43ebc65SAshish Gupta 		ZIP_PMD_ERR("failed configure xform parameters");
458b43ebc65SAshish Gupta 		rte_free(strm);
459b43ebc65SAshish Gupta 		return ret;
460b43ebc65SAshish Gupta 	}
461b43ebc65SAshish Gupta 	*stream = strm;
462938f3f5fSMahipal Challa 
463b43ebc65SAshish Gupta 	return 0;
464b43ebc65SAshish Gupta }
465b43ebc65SAshish Gupta 
466b43ebc65SAshish Gupta static int
467b43ebc65SAshish Gupta zip_pmd_stream_free(struct rte_compressdev *dev, void *stream)
468b43ebc65SAshish Gupta {
469b43ebc65SAshish Gupta 	struct zip_vf *vf = (struct zip_vf *) (dev->data->dev_private);
470b43ebc65SAshish Gupta 	struct zip_stream *z_stream;
471b43ebc65SAshish Gupta 
472b43ebc65SAshish Gupta 	if (stream == NULL)
473b43ebc65SAshish Gupta 		return 0;
474b43ebc65SAshish Gupta 
475b43ebc65SAshish Gupta 	z_stream = (struct zip_stream *)stream;
476b43ebc65SAshish Gupta 
477b43ebc65SAshish Gupta 	/* Free resources back to pool */
478b43ebc65SAshish Gupta 	rte_mempool_put_bulk(vf->zip_mp,
479b43ebc65SAshish Gupta 				(void *)&(z_stream->bufs[0]),
480938f3f5fSMahipal Challa 				(MAX_BUFS_PER_STREAM * ZIP_BURST_SIZE));
481b43ebc65SAshish Gupta 
482b43ebc65SAshish Gupta 	/* Zero out the whole structure */
483b43ebc65SAshish Gupta 	memset(stream, 0, sizeof(struct zip_stream));
484b43ebc65SAshish Gupta 	rte_free(stream);
485b43ebc65SAshish Gupta 
486b43ebc65SAshish Gupta 	return 0;
487b43ebc65SAshish Gupta }
488b43ebc65SAshish Gupta 
489b43ebc65SAshish Gupta 
49052048f8fSAshish Gupta static uint16_t
491938f3f5fSMahipal Challa zip_pmd_enqueue_burst(void *queue_pair,
49252048f8fSAshish Gupta 		struct rte_comp_op **ops, uint16_t nb_ops)
49352048f8fSAshish Gupta {
49452048f8fSAshish Gupta 	struct zipvf_qp *qp = queue_pair;
49552048f8fSAshish Gupta 	struct zip_stream *zstrm;
496938f3f5fSMahipal Challa 	struct rte_comp_op *op;
49752048f8fSAshish Gupta 	int i, ret = 0;
49852048f8fSAshish Gupta 	uint16_t enqd = 0;
49952048f8fSAshish Gupta 
50052048f8fSAshish Gupta 	for (i = 0; i < nb_ops; i++) {
50152048f8fSAshish Gupta 		op = ops[i];
50252048f8fSAshish Gupta 
50352048f8fSAshish Gupta 		if (op->op_type == RTE_COMP_OP_STATEFUL) {
50452048f8fSAshish Gupta 			op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
50552048f8fSAshish Gupta 		} else {
50652048f8fSAshish Gupta 			/* process stateless ops */
50752048f8fSAshish Gupta 			zstrm = (struct zip_stream *)op->private_xform;
50852048f8fSAshish Gupta 			if (unlikely(zstrm == NULL))
50952048f8fSAshish Gupta 				op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
51052048f8fSAshish Gupta 			else
511938f3f5fSMahipal Challa 				ret = zstrm->func(op, qp, zstrm, i);
51252048f8fSAshish Gupta 		}
51352048f8fSAshish Gupta 
51452048f8fSAshish Gupta 		/* Whatever is out of op, put it into completion queue with
51552048f8fSAshish Gupta 		 * its status
51652048f8fSAshish Gupta 		 */
51752048f8fSAshish Gupta 		if (!ret)
51852048f8fSAshish Gupta 			ret = rte_ring_enqueue(qp->processed_pkts, (void *)op);
51952048f8fSAshish Gupta 
52052048f8fSAshish Gupta 		if (unlikely(ret < 0)) {
52152048f8fSAshish Gupta 			/* increment count if failed to enqueue op*/
52252048f8fSAshish Gupta 			qp->qp_stats.enqueue_err_count++;
52352048f8fSAshish Gupta 		} else {
52452048f8fSAshish Gupta 			qp->qp_stats.enqueued_count++;
52552048f8fSAshish Gupta 			enqd++;
52652048f8fSAshish Gupta 		}
52752048f8fSAshish Gupta 	}
528938f3f5fSMahipal Challa 
52909442498SMahipal Challa 	qp->enqed = enqd;
530*f665790aSDavid Marchand 	ZIP_PMD_LOG(DEBUG, "ops_enqd[nb_ops:%d]:%d", nb_ops, enqd);
53109442498SMahipal Challa 
53252048f8fSAshish Gupta 	return enqd;
53352048f8fSAshish Gupta }
53452048f8fSAshish Gupta 
53552048f8fSAshish Gupta static uint16_t
536938f3f5fSMahipal Challa zip_pmd_dequeue_burst(void *queue_pair,
53752048f8fSAshish Gupta 		struct rte_comp_op **ops, uint16_t nb_ops)
53852048f8fSAshish Gupta {
539938f3f5fSMahipal Challa 	volatile union zip_zres_s *zresult = NULL;
54052048f8fSAshish Gupta 	struct zipvf_qp *qp = queue_pair;
54152048f8fSAshish Gupta 
54252048f8fSAshish Gupta 	unsigned int nb_dequeued = 0;
543938f3f5fSMahipal Challa 	struct zip_stream *zstrm;
544938f3f5fSMahipal Challa 	struct rte_comp_op *op;
545938f3f5fSMahipal Challa 	unsigned int i;
54652048f8fSAshish Gupta 
54752048f8fSAshish Gupta 	nb_dequeued = rte_ring_dequeue_burst(qp->processed_pkts,
54852048f8fSAshish Gupta 				(void **)ops, nb_ops, NULL);
54952048f8fSAshish Gupta 	qp->qp_stats.dequeued_count += nb_dequeued;
55052048f8fSAshish Gupta 
551938f3f5fSMahipal Challa 	/* Dequeue all the submitted ops */
552938f3f5fSMahipal Challa 	for (i = 0; i < nb_dequeued; i++) {
553938f3f5fSMahipal Challa 		op = ops[i];
554938f3f5fSMahipal Challa 		/* process stateless ops */
555938f3f5fSMahipal Challa 		zstrm = (struct zip_stream *)op->private_xform;
556938f3f5fSMahipal Challa 		zresult = (union zip_zres_s *)zstrm->bufs[RES_BUF + i];
557938f3f5fSMahipal Challa 
558938f3f5fSMahipal Challa 		/* Check and Process results in sync mode */
559938f3f5fSMahipal Challa 		do {
560938f3f5fSMahipal Challa 		} while (!zresult->s.compcode);
561938f3f5fSMahipal Challa 
562938f3f5fSMahipal Challa 		if (zresult->s.compcode == ZIP_COMP_E_SUCCESS) {
563938f3f5fSMahipal Challa 			op->status = RTE_COMP_OP_STATUS_SUCCESS;
564938f3f5fSMahipal Challa 		} else {
565938f3f5fSMahipal Challa 			/* FATAL error cannot do anything */
566*f665790aSDavid Marchand 			ZIP_PMD_ERR("operation failed with error code:%d",
567938f3f5fSMahipal Challa 				zresult->s.compcode);
568938f3f5fSMahipal Challa 			if (zresult->s.compcode == ZIP_COMP_E_DSTOP)
569938f3f5fSMahipal Challa 				op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
570938f3f5fSMahipal Challa 			else
571938f3f5fSMahipal Challa 				op->status = RTE_COMP_OP_STATUS_ERROR;
572938f3f5fSMahipal Challa 		}
573938f3f5fSMahipal Challa 
574*f665790aSDavid Marchand 		ZIP_PMD_LOG(DEBUG, "written %d", zresult->s.totalbyteswritten);
575938f3f5fSMahipal Challa 
576938f3f5fSMahipal Challa 		/* Update op stats */
577938f3f5fSMahipal Challa 		switch (op->status) {
578938f3f5fSMahipal Challa 		case RTE_COMP_OP_STATUS_SUCCESS:
579938f3f5fSMahipal Challa 			op->consumed = zresult->s.totalbytesread;
580938f3f5fSMahipal Challa 		/* Fall-through */
581938f3f5fSMahipal Challa 		case RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED:
582938f3f5fSMahipal Challa 			op->produced = zresult->s.totalbyteswritten;
583938f3f5fSMahipal Challa 			break;
584938f3f5fSMahipal Challa 		default:
585*f665790aSDavid Marchand 			ZIP_PMD_ERR("stats not updated for status:%d",
586938f3f5fSMahipal Challa 				    op->status);
587938f3f5fSMahipal Challa 			break;
588938f3f5fSMahipal Challa 		}
589938f3f5fSMahipal Challa 
590938f3f5fSMahipal Challa 		/* zstream is reset irrespective of result */
591938f3f5fSMahipal Challa 		reset_stream(zstrm->inst[i]);
592938f3f5fSMahipal Challa 		zresult->s.compcode = ZIP_COMP_E_NOTDONE;
59309442498SMahipal Challa 
59409442498SMahipal Challa 		if (op->m_src->nb_segs > 1)
59509442498SMahipal Challa 			rte_mempool_put(qp->vf->sg_mp, qp->g_info);
59609442498SMahipal Challa 
59709442498SMahipal Challa 		if (op->m_dst->nb_segs > 1)
59809442498SMahipal Challa 			rte_mempool_put(qp->vf->sg_mp, qp->s_info);
599938f3f5fSMahipal Challa 	}
600938f3f5fSMahipal Challa 
601*f665790aSDavid Marchand 	ZIP_PMD_LOG(DEBUG, "ops_deqd[nb_ops:%d]: %d", nb_ops, nb_dequeued);
60252048f8fSAshish Gupta 	return nb_dequeued;
60352048f8fSAshish Gupta }
60452048f8fSAshish Gupta 
605b74fd6b8SFerruh Yigit static struct rte_compressdev_ops octtx_zip_pmd_ops = {
606c378f084SAshish Gupta 		.dev_configure		= zip_pmd_config,
607c378f084SAshish Gupta 		.dev_start		= zip_pmd_start,
608c378f084SAshish Gupta 		.dev_stop		= zip_pmd_stop,
609c378f084SAshish Gupta 		.dev_close		= zip_pmd_close,
610c378f084SAshish Gupta 
611c378f084SAshish Gupta 		.stats_get		= zip_pmd_stats_get,
612c378f084SAshish Gupta 		.stats_reset		= zip_pmd_stats_reset,
613c378f084SAshish Gupta 
614c378f084SAshish Gupta 		.dev_infos_get		= zip_pmd_info_get,
615c378f084SAshish Gupta 
616c378f084SAshish Gupta 		.queue_pair_setup	= zip_pmd_qp_setup,
617c378f084SAshish Gupta 		.queue_pair_release	= zip_pmd_qp_release,
618b43ebc65SAshish Gupta 
619b43ebc65SAshish Gupta 		.private_xform_create	= zip_pmd_stream_create,
620b43ebc65SAshish Gupta 		.private_xform_free	= zip_pmd_stream_free,
621b43ebc65SAshish Gupta 		.stream_create		= NULL,
622b43ebc65SAshish Gupta 		.stream_free		= NULL
62343e610bbSSunila Sahu };
62443e610bbSSunila Sahu 
62543e610bbSSunila Sahu static int
62643e610bbSSunila Sahu zip_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
62743e610bbSSunila Sahu 	struct rte_pci_device *pci_dev)
62843e610bbSSunila Sahu {
62943e610bbSSunila Sahu 	int ret = 0;
63043e610bbSSunila Sahu 	char compressdev_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
63143e610bbSSunila Sahu 	struct rte_compressdev *compressdev;
63243e610bbSSunila Sahu 	struct rte_compressdev_pmd_init_params init_params = {
63343e610bbSSunila Sahu 		"",
63443e610bbSSunila Sahu 		rte_socket_id(),
63543e610bbSSunila Sahu 	};
63643e610bbSSunila Sahu 
63743e610bbSSunila Sahu 	ZIP_PMD_INFO("vendor_id=0x%x device_id=0x%x",
63843e610bbSSunila Sahu 			(unsigned int)pci_dev->id.vendor_id,
63943e610bbSSunila Sahu 			(unsigned int)pci_dev->id.device_id);
64043e610bbSSunila Sahu 
64143e610bbSSunila Sahu 	rte_pci_device_name(&pci_dev->addr, compressdev_name,
64243e610bbSSunila Sahu 			    sizeof(compressdev_name));
64343e610bbSSunila Sahu 
64443e610bbSSunila Sahu 	compressdev = rte_compressdev_pmd_create(compressdev_name,
64543e610bbSSunila Sahu 		&pci_dev->device, sizeof(struct zip_vf), &init_params);
64643e610bbSSunila Sahu 	if (compressdev == NULL) {
64743e610bbSSunila Sahu 		ZIP_PMD_ERR("driver %s: create failed", init_params.name);
64843e610bbSSunila Sahu 		return -ENODEV;
64943e610bbSSunila Sahu 	}
65043e610bbSSunila Sahu 
65143e610bbSSunila Sahu 	/*
65243e610bbSSunila Sahu 	 * create only if proc_type is primary.
65343e610bbSSunila Sahu 	 */
65443e610bbSSunila Sahu 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
65543e610bbSSunila Sahu 		/*  create vf dev with given pmd dev id */
65643e610bbSSunila Sahu 		ret = zipvf_create(compressdev);
65743e610bbSSunila Sahu 		if (ret < 0) {
65843e610bbSSunila Sahu 			ZIP_PMD_ERR("Device creation failed");
65943e610bbSSunila Sahu 			rte_compressdev_pmd_destroy(compressdev);
66043e610bbSSunila Sahu 			return ret;
66143e610bbSSunila Sahu 		}
66243e610bbSSunila Sahu 	}
66343e610bbSSunila Sahu 
66443e610bbSSunila Sahu 	compressdev->dev_ops = &octtx_zip_pmd_ops;
66543e610bbSSunila Sahu 	/* register rx/tx burst functions for data path */
666938f3f5fSMahipal Challa 	compressdev->dequeue_burst = zip_pmd_dequeue_burst;
667938f3f5fSMahipal Challa 	compressdev->enqueue_burst = zip_pmd_enqueue_burst;
66843e610bbSSunila Sahu 	compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;
66943e610bbSSunila Sahu 	return ret;
67043e610bbSSunila Sahu }
67143e610bbSSunila Sahu 
67243e610bbSSunila Sahu static int
67343e610bbSSunila Sahu zip_pci_remove(struct rte_pci_device *pci_dev)
67443e610bbSSunila Sahu {
67543e610bbSSunila Sahu 	struct rte_compressdev *compressdev;
67643e610bbSSunila Sahu 	char compressdev_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
67743e610bbSSunila Sahu 
67843e610bbSSunila Sahu 	if (pci_dev == NULL) {
679*f665790aSDavid Marchand 		ZIP_PMD_ERR(" Invalid PCI Device");
68043e610bbSSunila Sahu 		return -EINVAL;
68143e610bbSSunila Sahu 	}
68243e610bbSSunila Sahu 	rte_pci_device_name(&pci_dev->addr, compressdev_name,
68343e610bbSSunila Sahu 			sizeof(compressdev_name));
68443e610bbSSunila Sahu 
68543e610bbSSunila Sahu 	compressdev = rte_compressdev_pmd_get_named_dev(compressdev_name);
68643e610bbSSunila Sahu 	if (compressdev == NULL)
68743e610bbSSunila Sahu 		return -ENODEV;
68843e610bbSSunila Sahu 
68943e610bbSSunila Sahu 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
69043e610bbSSunila Sahu 		if (zipvf_destroy(compressdev) < 0)
69143e610bbSSunila Sahu 			return -ENODEV;
69243e610bbSSunila Sahu 	}
69343e610bbSSunila Sahu 	return rte_compressdev_pmd_destroy(compressdev);
69443e610bbSSunila Sahu }
69543e610bbSSunila Sahu 
69643e610bbSSunila Sahu static struct rte_pci_id pci_id_octtx_zipvf_table[] = {
69743e610bbSSunila Sahu 	{
69843e610bbSSunila Sahu 		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
69943e610bbSSunila Sahu 			PCI_DEVICE_ID_OCTEONTX_ZIPVF),
70043e610bbSSunila Sahu 	},
70143e610bbSSunila Sahu 	{
702a80ea5c0SMahipal Challa 		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
703a80ea5c0SMahipal Challa 			PCI_DEVICE_ID_OCTEONTX2_ZIPVF),
704a80ea5c0SMahipal Challa 	},
705a80ea5c0SMahipal Challa 	{
70643e610bbSSunila Sahu 		.device_id = 0
70743e610bbSSunila Sahu 	},
70843e610bbSSunila Sahu };
70943e610bbSSunila Sahu 
71043e610bbSSunila Sahu /**
71143e610bbSSunila Sahu  * Structure that represents a PCI driver
71243e610bbSSunila Sahu  */
71343e610bbSSunila Sahu static struct rte_pci_driver octtx_zip_pmd = {
71443e610bbSSunila Sahu 	.id_table    = pci_id_octtx_zipvf_table,
71543e610bbSSunila Sahu 	.drv_flags   = RTE_PCI_DRV_NEED_MAPPING,
71643e610bbSSunila Sahu 	.probe       = zip_pci_probe,
71743e610bbSSunila Sahu 	.remove      = zip_pci_remove,
71843e610bbSSunila Sahu };
71943e610bbSSunila Sahu 
72043e610bbSSunila Sahu RTE_PMD_REGISTER_PCI(COMPRESSDEV_NAME_ZIP_PMD, octtx_zip_pmd);
72143e610bbSSunila Sahu RTE_PMD_REGISTER_PCI_TABLE(COMPRESSDEV_NAME_ZIP_PMD, pci_id_octtx_zipvf_table);
722eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(octtx_zip_logtype_driver, INFO);
723