Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Cavium Networks
3 : : */
4 : :
5 : : #include <string.h>
6 : :
7 : : #include <dev_driver.h>
8 : : #include <rte_common.h>
9 : : #include <rte_malloc.h>
10 : :
11 : : #include "zlib_pmd_private.h"
12 : :
13 : : static const struct rte_compressdev_capabilities zlib_pmd_capabilities[] = {
14 : : { /* Deflate */
15 : : .algo = RTE_COMP_ALGO_DEFLATE,
16 : : .comp_feature_flags = (RTE_COMP_FF_NONCOMPRESSED_BLOCKS |
17 : : RTE_COMP_FF_HUFFMAN_FIXED |
18 : : RTE_COMP_FF_HUFFMAN_DYNAMIC),
19 : : .window_size = {
20 : : .min = 8,
21 : : .max = 15,
22 : : .increment = 1
23 : : },
24 : : },
25 : :
26 : : RTE_COMP_END_OF_CAPABILITIES_LIST()
27 : :
28 : : };
29 : :
30 : : /** Configure device */
31 : : static int
32 : 0 : zlib_pmd_config(struct rte_compressdev *dev,
33 : : struct rte_compressdev_config *config)
34 : : {
35 : : struct rte_mempool *mp;
36 : : char mp_name[RTE_MEMPOOL_NAMESIZE];
37 : 0 : struct zlib_private *internals = dev->data->dev_private;
38 : :
39 : 0 : snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
40 [ # # ]: 0 : "stream_mp_%u", dev->data->dev_id);
41 : 0 : mp = internals->mp;
42 [ # # ]: 0 : if (mp == NULL) {
43 : 0 : mp = rte_mempool_create(mp_name,
44 : 0 : config->max_nb_priv_xforms +
45 : 0 : config->max_nb_streams,
46 : : sizeof(struct zlib_priv_xform),
47 : : 0, 0, NULL, NULL, NULL,
48 : : NULL, config->socket_id,
49 : : 0);
50 [ # # ]: 0 : if (mp == NULL) {
51 : 0 : ZLIB_PMD_ERR("Cannot create private xform pool on socket %d",
52 : : config->socket_id);
53 : 0 : return -ENOMEM;
54 : : }
55 : 0 : internals->mp = mp;
56 : : }
57 : : return 0;
58 : : }
59 : :
60 : : /** Start device */
61 : : static int
62 : 0 : zlib_pmd_start(__rte_unused struct rte_compressdev *dev)
63 : : {
64 : 0 : return 0;
65 : : }
66 : :
67 : : /** Stop device */
68 : : static void
69 : 0 : zlib_pmd_stop(__rte_unused struct rte_compressdev *dev)
70 : : {
71 : 0 : }
72 : :
73 : : /** Close device */
74 : : static int
75 : 0 : zlib_pmd_close(struct rte_compressdev *dev)
76 : : {
77 : 0 : struct zlib_private *internals = dev->data->dev_private;
78 : 0 : rte_mempool_free(internals->mp);
79 : 0 : internals->mp = NULL;
80 : 0 : return 0;
81 : : }
82 : :
83 : : /** Get device statistics */
84 : : static void
85 : 0 : zlib_pmd_stats_get(struct rte_compressdev *dev,
86 : : struct rte_compressdev_stats *stats)
87 : : {
88 : : int qp_id;
89 : :
90 [ # # ]: 0 : for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
91 : 0 : struct zlib_qp *qp = dev->data->queue_pairs[qp_id];
92 : :
93 : 0 : stats->enqueued_count += qp->qp_stats.enqueued_count;
94 : 0 : stats->dequeued_count += qp->qp_stats.dequeued_count;
95 : :
96 : 0 : stats->enqueue_err_count += qp->qp_stats.enqueue_err_count;
97 : 0 : stats->dequeue_err_count += qp->qp_stats.dequeue_err_count;
98 : : }
99 : 0 : }
100 : :
101 : : /** Reset device statistics */
102 : : static void
103 : 0 : zlib_pmd_stats_reset(struct rte_compressdev *dev)
104 : : {
105 : : int qp_id;
106 : :
107 [ # # ]: 0 : for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
108 : 0 : struct zlib_qp *qp = dev->data->queue_pairs[qp_id];
109 : :
110 : 0 : memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
111 : : }
112 : 0 : }
113 : :
114 : : /** Get device info */
115 : : static void
116 : 0 : zlib_pmd_info_get(struct rte_compressdev *dev,
117 : : struct rte_compressdev_info *dev_info)
118 : : {
119 [ # # ]: 0 : if (dev_info != NULL) {
120 : 0 : dev_info->driver_name = dev->device->name;
121 : 0 : dev_info->feature_flags = dev->feature_flags;
122 : 0 : dev_info->capabilities = zlib_pmd_capabilities;
123 : : }
124 : 0 : }
125 : :
126 : : /** Release queue pair */
127 : : static int
128 : 0 : zlib_pmd_qp_release(struct rte_compressdev *dev, uint16_t qp_id)
129 : : {
130 : 0 : struct zlib_qp *qp = dev->data->queue_pairs[qp_id];
131 : :
132 [ # # ]: 0 : if (qp != NULL) {
133 : 0 : rte_ring_free(qp->processed_pkts);
134 : 0 : rte_free(qp);
135 : 0 : dev->data->queue_pairs[qp_id] = NULL;
136 : : }
137 : 0 : return 0;
138 : : }
139 : :
140 : : /** set a unique name for the queue pair based on its name, dev_id and qp_id */
141 : : static int
142 : 0 : zlib_pmd_qp_set_unique_name(struct rte_compressdev *dev,
143 : : struct zlib_qp *qp)
144 : : {
145 : 0 : unsigned int n = snprintf(qp->name, sizeof(qp->name),
146 : : "zlib_pmd_%u_qp_%u",
147 [ # # ]: 0 : dev->data->dev_id, qp->id);
148 : :
149 [ # # ]: 0 : if (n >= sizeof(qp->name))
150 : 0 : return -1;
151 : :
152 : : return 0;
153 : : }
154 : :
155 : : /** Create a ring to place process packets on */
156 : : static struct rte_ring *
157 : 0 : zlib_pmd_qp_create_processed_pkts_ring(struct zlib_qp *qp,
158 : : unsigned int ring_size, int socket_id)
159 : : {
160 : 0 : struct rte_ring *r = qp->processed_pkts;
161 : :
162 [ # # ]: 0 : if (r) {
163 [ # # ]: 0 : if (rte_ring_get_size(r) >= ring_size) {
164 : 0 : ZLIB_PMD_INFO("Reusing existing ring %s for processed"
165 : : " packets", qp->name);
166 : 0 : return r;
167 : : }
168 : :
169 : 0 : ZLIB_PMD_ERR("Unable to reuse existing ring %s for processed"
170 : : " packets", qp->name);
171 : 0 : return NULL;
172 : : }
173 : :
174 : 0 : return rte_ring_create(qp->name, ring_size, socket_id,
175 : : RING_F_EXACT_SZ);
176 : : }
177 : :
178 : : /** Setup a queue pair */
179 : : static int
180 : 0 : zlib_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
181 : : uint32_t max_inflight_ops, int socket_id)
182 : : {
183 : : struct zlib_qp *qp = NULL;
184 : :
185 : : /* Free memory prior to re-allocation if needed. */
186 [ # # ]: 0 : if (dev->data->queue_pairs[qp_id] != NULL)
187 : 0 : zlib_pmd_qp_release(dev, qp_id);
188 : :
189 : : /* Allocate the queue pair data structure. */
190 : 0 : qp = rte_zmalloc_socket("ZLIB PMD Queue Pair", sizeof(*qp),
191 : : RTE_CACHE_LINE_SIZE, socket_id);
192 [ # # ]: 0 : if (qp == NULL)
193 : : return (-ENOMEM);
194 : :
195 : 0 : qp->id = qp_id;
196 : 0 : dev->data->queue_pairs[qp_id] = qp;
197 : :
198 [ # # ]: 0 : if (zlib_pmd_qp_set_unique_name(dev, qp))
199 : 0 : goto qp_setup_cleanup;
200 : :
201 : 0 : qp->processed_pkts = zlib_pmd_qp_create_processed_pkts_ring(qp,
202 : : max_inflight_ops, socket_id);
203 [ # # ]: 0 : if (qp->processed_pkts == NULL)
204 : 0 : goto qp_setup_cleanup;
205 : :
206 : 0 : memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
207 : 0 : return 0;
208 : :
209 : 0 : qp_setup_cleanup:
210 : : if (qp) {
211 : 0 : rte_free(qp);
212 : : qp = NULL;
213 : : }
214 : 0 : return -1;
215 : : }
216 : :
217 : : /** Configure stream */
218 : : static int
219 : 0 : zlib_pmd_stream_create(struct rte_compressdev *dev,
220 : : const struct rte_comp_xform *xform,
221 : : void **zstream)
222 : : {
223 : : int ret = 0;
224 : : struct zlib_stream *stream;
225 : 0 : struct zlib_private *internals = dev->data->dev_private;
226 : :
227 [ # # ]: 0 : if (xform == NULL) {
228 : 0 : ZLIB_PMD_ERR("invalid xform struct");
229 : 0 : return -EINVAL;
230 : : }
231 : :
232 [ # # # # ]: 0 : if (rte_mempool_get(internals->mp, zstream)) {
233 : 0 : ZLIB_PMD_ERR("Couldn't get object from session mempool");
234 : 0 : return -ENOMEM;
235 : : }
236 : 0 : stream = *((struct zlib_stream **)zstream);
237 : :
238 : 0 : ret = zlib_set_stream_parameters(xform, stream);
239 : :
240 [ # # ]: 0 : if (ret < 0) {
241 : 0 : ZLIB_PMD_ERR("failed configure session parameters");
242 : :
243 : : memset(stream, 0, sizeof(struct zlib_stream));
244 : : /* Return session to mempool */
245 [ # # ]: 0 : rte_mempool_put(internals->mp, stream);
246 : 0 : return ret;
247 : : }
248 : :
249 : : return 0;
250 : : }
251 : :
252 : : /** Configure private xform */
253 : : static int
254 : 0 : zlib_pmd_private_xform_create(struct rte_compressdev *dev,
255 : : const struct rte_comp_xform *xform,
256 : : void **private_xform)
257 : : {
258 : 0 : return zlib_pmd_stream_create(dev, xform, private_xform);
259 : : }
260 : :
261 : : /** Clear the memory of stream so it doesn't leave key material behind */
262 : : static int
263 : 0 : zlib_pmd_stream_free(__rte_unused struct rte_compressdev *dev,
264 : : void *zstream)
265 : : {
266 : : struct zlib_stream *stream = (struct zlib_stream *)zstream;
267 [ # # ]: 0 : if (!stream)
268 : : return -EINVAL;
269 : :
270 : 0 : stream->free(&stream->strm);
271 : : /* Zero out the whole structure */
272 : : memset(stream, 0, sizeof(struct zlib_stream));
273 : : struct rte_mempool *mp = rte_mempool_from_obj(stream);
274 : 0 : rte_mempool_put(mp, stream);
275 : :
276 : 0 : return 0;
277 : : }
278 : :
279 : : /** Clear the memory of stream so it doesn't leave key material behind */
280 : : static int
281 : 0 : zlib_pmd_private_xform_free(struct rte_compressdev *dev,
282 : : void *private_xform)
283 : : {
284 : 0 : return zlib_pmd_stream_free(dev, private_xform);
285 : : }
286 : :
287 : : struct rte_compressdev_ops zlib_pmd_ops = {
288 : : .dev_configure = zlib_pmd_config,
289 : : .dev_start = zlib_pmd_start,
290 : : .dev_stop = zlib_pmd_stop,
291 : : .dev_close = zlib_pmd_close,
292 : :
293 : : .stats_get = zlib_pmd_stats_get,
294 : : .stats_reset = zlib_pmd_stats_reset,
295 : :
296 : : .dev_infos_get = zlib_pmd_info_get,
297 : :
298 : : .queue_pair_setup = zlib_pmd_qp_setup,
299 : : .queue_pair_release = zlib_pmd_qp_release,
300 : :
301 : : .private_xform_create = zlib_pmd_private_xform_create,
302 : : .private_xform_free = zlib_pmd_private_xform_free,
303 : :
304 : : .stream_create = NULL,
305 : : .stream_free = NULL
306 : : };
307 : :
308 : : struct rte_compressdev_ops *rte_zlib_pmd_ops = &zlib_pmd_ops;
|