Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2015-2022 Intel Corporation
3 : : */
4 : :
5 : : #include <rte_malloc.h>
6 : :
7 : : #include "qat_comp.h"
8 : : #include "qat_comp_pmd.h"
9 : :
10 : : #define QAT_PMD_COMP_SGL_DEF_SEGMENTS 16
11 : :
12 : : #define COMP_ENQ_THRESHOLD_NAME "qat_comp_enq_threshold"
13 : :
14 : : static const char *const arguments[] = {
15 : : COMP_ENQ_THRESHOLD_NAME,
16 : : NULL
17 : : };
18 : :
19 : : struct qat_comp_gen_dev_ops qat_comp_gen_dev_ops[QAT_N_GENS];
20 : :
21 : : struct stream_create_info {
22 : : struct qat_comp_dev_private *comp_dev;
23 : : int socket_id;
24 : : int error;
25 : : };
26 : :
27 : : static struct
28 : : qat_comp_capabilities_info qat_comp_get_capa_info(
29 : : enum qat_device_gen qat_dev_gen, struct qat_pci_device *qat_dev)
30 : : {
31 : : struct qat_comp_capabilities_info ret = { .data = NULL, .size = 0 };
32 : :
33 : 0 : if (qat_dev_gen >= QAT_N_GENS)
34 : : return ret;
35 [ # # # # ]: 0 : if (qat_comp_gen_dev_ops[qat_dev_gen].qat_comp_get_capabilities == NULL)
36 : : return ret;
37 : 0 : return qat_comp_gen_dev_ops[qat_dev_gen]
38 : : .qat_comp_get_capabilities(qat_dev);
39 : : }
40 : :
41 : : void
42 : 0 : qat_comp_stats_get(struct rte_compressdev *dev,
43 : : struct rte_compressdev_stats *stats)
44 : : {
45 : 0 : struct qat_common_stats qat_stats = {0};
46 : : struct qat_comp_dev_private *qat_priv;
47 : :
48 [ # # ]: 0 : if (stats == NULL || dev == NULL) {
49 : 0 : QAT_LOG(ERR, "invalid ptr: stats %p, dev %p", stats, dev);
50 : 0 : return;
51 : : }
52 : 0 : qat_priv = dev->data->dev_private;
53 : :
54 : 0 : qat_stats_get(qat_priv->qat_dev, &qat_stats, QAT_SERVICE_COMPRESSION);
55 : 0 : stats->enqueued_count = qat_stats.enqueued_count;
56 : 0 : stats->dequeued_count = qat_stats.dequeued_count;
57 : 0 : stats->enqueue_err_count = qat_stats.enqueue_err_count;
58 : 0 : stats->dequeue_err_count = qat_stats.dequeue_err_count;
59 : : }
60 : :
61 : : void
62 : 0 : qat_comp_stats_reset(struct rte_compressdev *dev)
63 : : {
64 : : struct qat_comp_dev_private *qat_priv;
65 : :
66 [ # # ]: 0 : if (dev == NULL) {
67 : 0 : QAT_LOG(ERR, "invalid compressdev ptr %p", dev);
68 : 0 : return;
69 : : }
70 : 0 : qat_priv = dev->data->dev_private;
71 : :
72 : 0 : qat_stats_reset(qat_priv->qat_dev, QAT_SERVICE_COMPRESSION);
73 : :
74 : : }
75 : :
76 : : int
77 : 0 : qat_comp_qp_release(struct rte_compressdev *dev, uint16_t queue_pair_id)
78 : : {
79 : 0 : struct qat_comp_dev_private *qat_private = dev->data->dev_private;
80 : 0 : struct qat_qp **qp_addr =
81 : 0 : (struct qat_qp **)&(dev->data->queue_pairs[queue_pair_id]);
82 : 0 : struct qat_qp *qp = (struct qat_qp *)*qp_addr;
83 : 0 : enum qat_device_gen qat_dev_gen = qat_private->qat_dev->qat_dev_gen;
84 : : uint32_t i;
85 : :
86 : 0 : QAT_LOG(DEBUG, "Release comp qp %u on device %d",
87 : : queue_pair_id, dev->data->dev_id);
88 : :
89 : 0 : qat_private->qat_dev->qps_in_use[QAT_SERVICE_COMPRESSION][queue_pair_id]
90 : 0 : = NULL;
91 : :
92 [ # # ]: 0 : if (qp != NULL)
93 [ # # ]: 0 : for (i = 0; i < qp->nb_descriptors; i++) {
94 : 0 : struct qat_comp_op_cookie *cookie = qp->op_cookies[i];
95 : :
96 : 0 : rte_free(cookie->qat_sgl_src_d);
97 : 0 : rte_free(cookie->qat_sgl_dst_d);
98 : : }
99 : :
100 : 0 : return qat_qp_release(qat_dev_gen, (struct qat_qp **)
101 : 0 : &(dev->data->queue_pairs[queue_pair_id]));
102 : : }
103 : :
104 : : int
105 : 0 : qat_comp_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
106 : : uint32_t max_inflight_ops, int socket_id)
107 : : {
108 : 0 : struct qat_qp_config qat_qp_conf = {0};
109 : 0 : struct qat_qp **qp_addr =
110 : 0 : (struct qat_qp **)&(dev->data->queue_pairs[qp_id]);
111 : 0 : struct qat_comp_dev_private *qat_private = dev->data->dev_private;
112 : 0 : struct qat_pci_device *qat_dev = qat_private->qat_dev;
113 : : struct qat_qp *qp;
114 : : uint32_t i;
115 : : int ret;
116 : :
117 : : /* If qp is already in use free ring memory and qp metadata. */
118 [ # # ]: 0 : if (*qp_addr != NULL) {
119 : 0 : ret = qat_comp_qp_release(dev, qp_id);
120 [ # # ]: 0 : if (ret < 0)
121 : : return ret;
122 : : }
123 [ # # ]: 0 : if (qp_id >= qat_qps_per_service(qat_dev,
124 : : QAT_SERVICE_COMPRESSION)) {
125 : 0 : QAT_LOG(ERR, "qp_id %u invalid for this device", qp_id);
126 : 0 : return -EINVAL;
127 : : }
128 : :
129 : :
130 : 0 : qat_qp_conf.hw = qat_qp_get_hw_data(qat_dev, QAT_SERVICE_COMPRESSION,
131 : : qp_id);
132 [ # # ]: 0 : if (qat_qp_conf.hw == NULL) {
133 : 0 : QAT_LOG(ERR, "qp_id %u invalid for this device", qp_id);
134 : 0 : return -EINVAL;
135 : : }
136 : 0 : qat_qp_conf.cookie_size = sizeof(struct qat_comp_op_cookie);
137 : 0 : qat_qp_conf.nb_descriptors = max_inflight_ops;
138 : 0 : qat_qp_conf.socket_id = socket_id;
139 : 0 : qat_qp_conf.service_str = "comp";
140 : :
141 : 0 : ret = qat_qp_setup(qat_private->qat_dev, qp_addr, qp_id, &qat_qp_conf);
142 [ # # ]: 0 : if (ret != 0)
143 : : return ret;
144 : : /* store a link to the qp in the qat_pci_device */
145 : 0 : qat_private->qat_dev->qps_in_use[QAT_SERVICE_COMPRESSION][qp_id]
146 : 0 : = *qp_addr;
147 : :
148 : : qp = (struct qat_qp *)*qp_addr;
149 : 0 : qp->min_enq_burst_threshold = qat_private->min_enq_burst_threshold;
150 : :
151 [ # # ]: 0 : for (i = 0; i < qp->nb_descriptors; i++) {
152 : :
153 : 0 : struct qat_comp_op_cookie *cookie =
154 : 0 : qp->op_cookies[i];
155 : :
156 : 0 : cookie->qp = qp;
157 : 0 : cookie->cookie_index = i;
158 : :
159 : 0 : cookie->qat_sgl_src_d = rte_zmalloc_socket(NULL,
160 : : sizeof(struct qat_sgl) +
161 : : sizeof(struct qat_flat_buf) *
162 : : QAT_PMD_COMP_SGL_DEF_SEGMENTS,
163 : 0 : 64, dev->data->socket_id);
164 : :
165 : 0 : cookie->qat_sgl_dst_d = rte_zmalloc_socket(NULL,
166 : : sizeof(struct qat_sgl) +
167 : : sizeof(struct qat_flat_buf) *
168 : : QAT_PMD_COMP_SGL_DEF_SEGMENTS,
169 : 0 : 64, dev->data->socket_id);
170 : :
171 [ # # # # ]: 0 : if (cookie->qat_sgl_src_d == NULL ||
172 : : cookie->qat_sgl_dst_d == NULL) {
173 : 0 : QAT_LOG(ERR, "Can't allocate SGL"
174 : : " for device %s",
175 : : qat_private->qat_dev->name);
176 : 0 : return -ENOMEM;
177 : : }
178 : :
179 : 0 : cookie->qat_sgl_src_phys_addr =
180 : 0 : rte_malloc_virt2iova(cookie->qat_sgl_src_d);
181 : :
182 : 0 : cookie->qat_sgl_dst_phys_addr =
183 : 0 : rte_malloc_virt2iova(cookie->qat_sgl_dst_d);
184 : :
185 : 0 : cookie->dst_nb_elems = cookie->src_nb_elems =
186 : : QAT_PMD_COMP_SGL_DEF_SEGMENTS;
187 : :
188 : 0 : cookie->socket_id = dev->data->socket_id;
189 : :
190 : 0 : cookie->error = 0;
191 : : }
192 : :
193 : : return ret;
194 : : }
195 : :
196 : :
197 : : #define QAT_IM_BUFFER_DEBUG 0
198 : : const struct rte_memzone *
199 : 0 : qat_comp_setup_inter_buffers(struct qat_comp_dev_private *comp_dev,
200 : : uint32_t buff_size)
201 : : {
202 : : char inter_buff_mz_name[RTE_MEMZONE_NAMESIZE];
203 : : const struct rte_memzone *memzone;
204 : : uint8_t *mz_start = NULL;
205 : : rte_iova_t mz_start_phys = 0;
206 : : struct array_of_ptrs *array_of_pointers;
207 : : int size_of_ptr_array;
208 : : uint32_t full_size;
209 : : uint32_t offset_of_flat_buffs;
210 : : int i;
211 : 0 : int num_im_sgls = qat_comp_get_num_im_bufs_required(
212 : 0 : comp_dev->qat_dev->qat_dev_gen);
213 : :
214 : 0 : QAT_LOG(DEBUG, "QAT COMP device %s needs %d sgls",
215 : : comp_dev->qat_dev->name, num_im_sgls);
216 : : snprintf(inter_buff_mz_name, RTE_MEMZONE_NAMESIZE,
217 : 0 : "%s_inter_buff", comp_dev->qat_dev->name);
218 : 0 : memzone = rte_memzone_lookup(inter_buff_mz_name);
219 [ # # ]: 0 : if (memzone != NULL) {
220 : 0 : QAT_LOG(DEBUG, "QAT COMP im buffer memzone created already");
221 : 0 : return memzone;
222 : : }
223 : :
224 : : /* Create multiple memzones to hold intermediate buffers and associated
225 : : * meta-data needed by the firmware.
226 : : * The first memzone contains:
227 : : * - a list of num_im_sgls physical pointers to sgls
228 : : * All other memzones contain:
229 : : * - the sgl structure, pointing to QAT_NUM_BUFS_IN_IM_SGL flat buffers
230 : : * - the flat buffers: QAT_NUM_BUFS_IN_IM_SGL buffers,
231 : : * each of buff_size
232 : : * num_im_sgls depends on the hardware generation of the device
233 : : * buff_size comes from the user via the config file
234 : : */
235 : :
236 : 0 : size_of_ptr_array = num_im_sgls * sizeof(phys_addr_t);
237 : : offset_of_flat_buffs = sizeof(struct qat_inter_sgl);
238 : 0 : full_size = offset_of_flat_buffs +
239 : : buff_size * QAT_NUM_BUFS_IN_IM_SGL;
240 : :
241 : 0 : memzone = rte_memzone_reserve_aligned(inter_buff_mz_name,
242 : : size_of_ptr_array,
243 : 0 : comp_dev->compressdev->data->socket_id,
244 : : RTE_MEMZONE_IOVA_CONTIG, QAT_64_BYTE_ALIGN);
245 [ # # ]: 0 : if (memzone == NULL) {
246 : 0 : QAT_LOG(ERR,
247 : : "Can't allocate intermediate buffers for device %s",
248 : : comp_dev->qat_dev->name);
249 : 0 : return NULL;
250 : : }
251 : :
252 : 0 : mz_start = (uint8_t *)memzone->addr;
253 : 0 : mz_start_phys = memzone->iova;
254 : 0 : QAT_LOG(DEBUG, "Memzone %s: addr = %p, phys = 0x%"PRIx64
255 : : ", size required %d, size created %zu",
256 : : inter_buff_mz_name, mz_start, mz_start_phys,
257 : : size_of_ptr_array, memzone->len);
258 : :
259 : : array_of_pointers = (struct array_of_ptrs *)mz_start;
260 [ # # ]: 0 : for (i = 0; i < num_im_sgls; i++) {
261 : : const struct rte_memzone *mz;
262 : : struct qat_inter_sgl *sgl;
263 : : int lb;
264 : :
265 : : snprintf(inter_buff_mz_name, RTE_MEMZONE_NAMESIZE,
266 : 0 : "%s_inter_buff_%d", comp_dev->qat_dev->name, i);
267 : 0 : mz = rte_memzone_lookup(inter_buff_mz_name);
268 [ # # ]: 0 : if (mz == NULL) {
269 : 0 : mz = rte_memzone_reserve_aligned(inter_buff_mz_name,
270 : : full_size,
271 : 0 : comp_dev->compressdev->data->socket_id,
272 : : RTE_MEMZONE_IOVA_CONTIG,
273 : : QAT_64_BYTE_ALIGN);
274 [ # # ]: 0 : if (mz == NULL) {
275 : 0 : QAT_LOG(ERR,
276 : : "Can't allocate intermediate buffers for device %s",
277 : : comp_dev->qat_dev->name);
278 [ # # ]: 0 : while (--i >= 0) {
279 : : snprintf(inter_buff_mz_name,
280 : : RTE_MEMZONE_NAMESIZE,
281 : : "%s_inter_buff_%d",
282 : 0 : comp_dev->qat_dev->name,
283 : : i);
284 : 0 : rte_memzone_free(
285 : : rte_memzone_lookup(
286 : : inter_buff_mz_name));
287 : : }
288 : 0 : rte_memzone_free(memzone);
289 : 0 : return NULL;
290 : : }
291 : : }
292 : :
293 : 0 : QAT_LOG(DEBUG, "Memzone %s: addr = %p, phys = 0x%"PRIx64
294 : : ", size required %d, size created %zu",
295 : : inter_buff_mz_name, mz->addr, mz->iova,
296 : : full_size, mz->len);
297 : :
298 : 0 : array_of_pointers->pointer[i] = mz->iova;
299 : :
300 : 0 : sgl = (struct qat_inter_sgl *) mz->addr;
301 : 0 : sgl->num_bufs = QAT_NUM_BUFS_IN_IM_SGL;
302 : 0 : sgl->num_mapped_bufs = 0;
303 : 0 : sgl->resrvd = 0;
304 : :
305 : : #if QAT_IM_BUFFER_DEBUG
306 : : QAT_LOG(DEBUG, " : phys addr of sgl[%i] in array_of_pointers"
307 : : " = 0x%"PRIx64, i, array_of_pointers->pointer[i]);
308 : : QAT_LOG(DEBUG, " : virt address of sgl[%i] = %p", i, sgl);
309 : : #endif
310 [ # # ]: 0 : for (lb = 0; lb < QAT_NUM_BUFS_IN_IM_SGL; lb++) {
311 : 0 : sgl->buffers[lb].addr =
312 : 0 : mz->iova + offset_of_flat_buffs +
313 : : lb * buff_size;
314 : 0 : sgl->buffers[lb].len = buff_size;
315 : 0 : sgl->buffers[lb].resrvd = 0;
316 : : #if QAT_IM_BUFFER_DEBUG
317 : : QAT_LOG(DEBUG,
318 : : " : sgl->buffers[%d].addr = 0x%"PRIx64", len=%d",
319 : : lb, sgl->buffers[lb].addr, sgl->buffers[lb].len);
320 : : #endif
321 : : }
322 : : }
323 : : #if QAT_IM_BUFFER_DEBUG
324 : : QAT_DP_HEXDUMP_LOG(DEBUG, "IM buffer memzone start:",
325 : : memzone->addr, size_of_ptr_array);
326 : : #endif
327 : : return memzone;
328 : : }
329 : :
330 : : static struct rte_mempool *
331 : 0 : qat_comp_create_xform_pool(struct qat_comp_dev_private *comp_dev,
332 : : struct rte_compressdev_config *config,
333 : : uint32_t num_elements)
334 : : {
335 : : char xform_pool_name[RTE_MEMPOOL_NAMESIZE];
336 : : struct rte_mempool *mp;
337 : :
338 : : snprintf(xform_pool_name, RTE_MEMPOOL_NAMESIZE,
339 : 0 : "%s_xforms", comp_dev->qat_dev->name);
340 : :
341 : 0 : QAT_LOG(DEBUG, "xformpool: %s", xform_pool_name);
342 : 0 : mp = rte_mempool_lookup(xform_pool_name);
343 : :
344 [ # # ]: 0 : if (mp != NULL) {
345 : 0 : QAT_LOG(DEBUG, "xformpool already created");
346 [ # # ]: 0 : if (mp->size != num_elements) {
347 : 0 : QAT_LOG(DEBUG, "xformpool wrong size - delete it");
348 : 0 : rte_mempool_free(mp);
349 : : mp = NULL;
350 : 0 : comp_dev->xformpool = NULL;
351 : : }
352 : : }
353 : :
354 [ # # ]: 0 : if (mp == NULL)
355 : 0 : mp = rte_mempool_create(xform_pool_name,
356 : : num_elements,
357 : : qat_comp_xform_size(), 0, 0,
358 : : NULL, NULL, NULL, NULL, config->socket_id,
359 : : 0);
360 [ # # ]: 0 : if (mp == NULL) {
361 : 0 : QAT_LOG(ERR, "Err creating mempool %s w %d elements of size %d",
362 : : xform_pool_name, num_elements, qat_comp_xform_size());
363 : 0 : return NULL;
364 : : }
365 : :
366 : : return mp;
367 : : }
368 : :
369 : : static void
370 : 0 : qat_comp_stream_init(struct rte_mempool *mp __rte_unused, void *opaque,
371 : : void *obj, unsigned int obj_idx)
372 : : {
373 : : struct stream_create_info *info = opaque;
374 : : struct qat_comp_stream *stream = obj;
375 : : char mz_name[RTE_MEMZONE_NAMESIZE];
376 : : const struct rte_memzone *memzone;
377 : : struct qat_inter_sgl *ram_banks_desc;
378 : :
379 : : /* find a memzone for RAM banks */
380 : : snprintf(mz_name, RTE_MEMZONE_NAMESIZE, "%s_%u_rambanks",
381 : 0 : info->comp_dev->qat_dev->name, obj_idx);
382 : 0 : memzone = rte_memzone_lookup(mz_name);
383 [ # # ]: 0 : if (memzone == NULL) {
384 : : /* allocate a memzone for compression state and RAM banks */
385 : 0 : memzone = rte_memzone_reserve_aligned(mz_name,
386 : : QAT_STATE_REGISTERS_MAX_SIZE
387 : : + sizeof(struct qat_inter_sgl)
388 : : + QAT_INFLATE_CONTEXT_SIZE,
389 : : info->socket_id,
390 : : RTE_MEMZONE_IOVA_CONTIG, QAT_64_BYTE_ALIGN);
391 [ # # ]: 0 : if (memzone == NULL) {
392 : 0 : QAT_LOG(ERR,
393 : : "Can't allocate RAM banks for device %s, object %u",
394 : : info->comp_dev->qat_dev->name, obj_idx);
395 : 0 : info->error = -ENOMEM;
396 : 0 : return;
397 : : }
398 : : }
399 : :
400 : : /* prepare the buffer list descriptor for RAM banks */
401 : : ram_banks_desc = (struct qat_inter_sgl *)
402 : 0 : (((uint8_t *) memzone->addr) + QAT_STATE_REGISTERS_MAX_SIZE);
403 : 0 : ram_banks_desc->num_bufs = 1;
404 : 0 : ram_banks_desc->buffers[0].len = QAT_INFLATE_CONTEXT_SIZE;
405 : 0 : ram_banks_desc->buffers[0].addr = memzone->iova
406 : : + QAT_STATE_REGISTERS_MAX_SIZE
407 : 0 : + sizeof(struct qat_inter_sgl);
408 : :
409 : 0 : memset(stream, 0, qat_comp_stream_size());
410 : 0 : stream->memzone = memzone;
411 : 0 : stream->state_registers_decomp = memzone->addr;
412 : 0 : stream->state_registers_decomp_phys = memzone->iova;
413 : 0 : stream->inflate_context = ((uint8_t *) memzone->addr)
414 : 0 : + QAT_STATE_REGISTERS_MAX_SIZE;
415 : 0 : stream->inflate_context_phys = memzone->iova
416 : 0 : + QAT_STATE_REGISTERS_MAX_SIZE;
417 : : }
418 : :
419 : : static void
420 : 0 : qat_comp_stream_destroy(struct rte_mempool *mp __rte_unused,
421 : : void *opaque __rte_unused, void *obj,
422 : : unsigned obj_idx __rte_unused)
423 : : {
424 : : struct qat_comp_stream *stream = obj;
425 : :
426 : 0 : rte_memzone_free(stream->memzone);
427 : 0 : }
428 : :
429 : : static struct rte_mempool *
430 : 0 : qat_comp_create_stream_pool(struct qat_comp_dev_private *comp_dev,
431 : : int socket_id,
432 : : uint32_t num_elements)
433 : : {
434 : : char stream_pool_name[RTE_MEMPOOL_NAMESIZE];
435 : : struct rte_mempool *mp;
436 : :
437 : : snprintf(stream_pool_name, RTE_MEMPOOL_NAMESIZE,
438 : 0 : "%s_streams", comp_dev->qat_dev->name);
439 : :
440 : 0 : QAT_LOG(DEBUG, "streampool: %s", stream_pool_name);
441 : 0 : mp = rte_mempool_lookup(stream_pool_name);
442 : :
443 [ # # ]: 0 : if (mp != NULL) {
444 : 0 : QAT_LOG(DEBUG, "streampool already created");
445 [ # # ]: 0 : if (mp->size != num_elements) {
446 : 0 : QAT_LOG(DEBUG, "streampool wrong size - delete it");
447 : 0 : rte_mempool_obj_iter(mp, qat_comp_stream_destroy, NULL);
448 : 0 : rte_mempool_free(mp);
449 : : mp = NULL;
450 : 0 : comp_dev->streampool = NULL;
451 : : }
452 : : }
453 : :
454 [ # # ]: 0 : if (mp == NULL) {
455 : 0 : struct stream_create_info info = {
456 : : .comp_dev = comp_dev,
457 : : .socket_id = socket_id,
458 : : .error = 0
459 : : };
460 : 0 : mp = rte_mempool_create(stream_pool_name,
461 : : num_elements,
462 : : qat_comp_stream_size(), 0, 0,
463 : : NULL, NULL, qat_comp_stream_init, &info,
464 : : socket_id, 0);
465 [ # # ]: 0 : if (mp == NULL) {
466 : 0 : QAT_LOG(ERR,
467 : : "Err creating mempool %s w %d elements of size %d",
468 : : stream_pool_name, num_elements,
469 : : qat_comp_stream_size());
470 [ # # ]: 0 : } else if (info.error) {
471 : 0 : rte_mempool_obj_iter(mp, qat_comp_stream_destroy, NULL);
472 : 0 : QAT_LOG(ERR,
473 : : "Destroying mempool %s as at least one element failed initialisation",
474 : : stream_pool_name);
475 : 0 : rte_mempool_free(mp);
476 : : mp = NULL;
477 : : }
478 : : }
479 : :
480 : 0 : return mp;
481 : : }
482 : :
483 : : static void
484 : 0 : _qat_comp_dev_config_clear(struct qat_comp_dev_private *comp_dev)
485 : : {
486 : : /* Free intermediate buffers */
487 [ # # ]: 0 : if (comp_dev->interm_buff_mz) {
488 : : char mz_name[RTE_MEMZONE_NAMESIZE];
489 : 0 : int i = qat_comp_get_num_im_bufs_required(
490 : 0 : comp_dev->qat_dev->qat_dev_gen);
491 : :
492 [ # # ]: 0 : while (--i >= 0) {
493 : : snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
494 : : "%s_inter_buff_%d",
495 : 0 : comp_dev->qat_dev->name, i);
496 : 0 : rte_memzone_free(rte_memzone_lookup(mz_name));
497 : : }
498 : 0 : rte_memzone_free(comp_dev->interm_buff_mz);
499 : 0 : comp_dev->interm_buff_mz = NULL;
500 : : }
501 : :
502 : : /* Free private_xform pool */
503 [ # # ]: 0 : if (comp_dev->xformpool) {
504 : : /* Free internal mempool for private xforms */
505 : 0 : rte_mempool_free(comp_dev->xformpool);
506 : 0 : comp_dev->xformpool = NULL;
507 : : }
508 : :
509 : : /* Free stream pool */
510 [ # # ]: 0 : if (comp_dev->streampool) {
511 : 0 : rte_mempool_obj_iter(comp_dev->streampool,
512 : : qat_comp_stream_destroy, NULL);
513 : 0 : rte_mempool_free(comp_dev->streampool);
514 : 0 : comp_dev->streampool = NULL;
515 : : }
516 : 0 : }
517 : :
518 : : int
519 : 0 : qat_comp_dev_config(struct rte_compressdev *dev,
520 : : struct rte_compressdev_config *config)
521 : : {
522 : 0 : struct qat_comp_dev_private *comp_dev = dev->data->dev_private;
523 : : int ret = 0;
524 : :
525 [ # # ]: 0 : if (config->max_nb_priv_xforms) {
526 : 0 : comp_dev->xformpool = qat_comp_create_xform_pool(comp_dev,
527 : : config, config->max_nb_priv_xforms);
528 [ # # ]: 0 : if (comp_dev->xformpool == NULL) {
529 : : ret = -ENOMEM;
530 : 0 : goto error_out;
531 : : }
532 : : } else
533 : 0 : comp_dev->xformpool = NULL;
534 : :
535 [ # # ]: 0 : if (config->max_nb_streams) {
536 : 0 : comp_dev->streampool = qat_comp_create_stream_pool(comp_dev,
537 : : config->socket_id, config->max_nb_streams);
538 [ # # ]: 0 : if (comp_dev->streampool == NULL) {
539 : : ret = -ENOMEM;
540 : 0 : goto error_out;
541 : : }
542 : : } else
543 : 0 : comp_dev->streampool = NULL;
544 : :
545 : : return 0;
546 : :
547 : 0 : error_out:
548 : 0 : _qat_comp_dev_config_clear(comp_dev);
549 : 0 : return ret;
550 : : }
551 : :
552 : : int
553 : 0 : qat_comp_dev_start(struct rte_compressdev *dev __rte_unused)
554 : : {
555 : 0 : return 0;
556 : : }
557 : :
558 : : void
559 : 0 : qat_comp_dev_stop(struct rte_compressdev *dev __rte_unused)
560 : : {
561 : :
562 : 0 : }
563 : :
564 : : int
565 : 0 : qat_comp_dev_close(struct rte_compressdev *dev)
566 : : {
567 : : int i;
568 : : int ret = 0;
569 : 0 : struct qat_comp_dev_private *comp_dev = dev->data->dev_private;
570 : :
571 [ # # ]: 0 : for (i = 0; i < dev->data->nb_queue_pairs; i++) {
572 : 0 : ret = qat_comp_qp_release(dev, i);
573 [ # # ]: 0 : if (ret < 0)
574 : 0 : return ret;
575 : : }
576 : :
577 : 0 : _qat_comp_dev_config_clear(comp_dev);
578 : :
579 : 0 : return ret;
580 : : }
581 : :
582 : : void
583 : 0 : qat_comp_dev_info_get(struct rte_compressdev *dev,
584 : : struct rte_compressdev_info *info)
585 : : {
586 : 0 : struct qat_comp_dev_private *comp_dev = dev->data->dev_private;
587 : 0 : struct qat_pci_device *qat_dev = comp_dev->qat_dev;
588 : :
589 [ # # ]: 0 : if (info != NULL) {
590 : 0 : info->max_nb_queue_pairs =
591 : 0 : qat_qps_per_service(qat_dev,
592 : : QAT_SERVICE_COMPRESSION);
593 : 0 : info->feature_flags = dev->feature_flags;
594 : 0 : info->capabilities = comp_dev->qat_dev_capabilities;
595 : : }
596 : 0 : }
597 : :
598 : : static uint16_t
599 : 0 : qat_comp_pmd_enq_deq_dummy_op_burst(void *qp __rte_unused,
600 : : struct rte_comp_op **ops __rte_unused,
601 : : uint16_t nb_ops __rte_unused)
602 : : {
603 : 0 : QAT_DP_LOG(ERR, "QAT PMD detected wrong FW version !");
604 : 0 : return 0;
605 : : }
606 : :
607 : : static struct rte_compressdev_ops compress_qat_dummy_ops = {
608 : :
609 : : /* Device related operations */
610 : : .dev_configure = NULL,
611 : : .dev_start = NULL,
612 : : .dev_stop = qat_comp_dev_stop,
613 : : .dev_close = qat_comp_dev_close,
614 : : .dev_infos_get = NULL,
615 : :
616 : : .stats_get = NULL,
617 : : .stats_reset = qat_comp_stats_reset,
618 : : .queue_pair_setup = NULL,
619 : : .queue_pair_release = qat_comp_qp_release,
620 : :
621 : : /* Compression related operations */
622 : : .private_xform_create = NULL,
623 : : .private_xform_free = qat_comp_private_xform_free
624 : : };
625 : :
626 : : static uint16_t
627 : 0 : qat_comp_dequeue_burst(void *qp, struct rte_comp_op **ops, uint16_t nb_ops)
628 : : {
629 : 0 : return qat_dequeue_op_burst(qp, (void **)ops, qat_comp_process_response,
630 : : nb_ops);
631 : : }
632 : :
633 : : static uint16_t
634 : 0 : qat_comp_pmd_dequeue_first_op_burst(void *qp, struct rte_comp_op **ops,
635 : : uint16_t nb_ops)
636 : : {
637 : 0 : uint16_t ret = qat_comp_dequeue_burst(qp, ops, nb_ops);
638 : : struct qat_qp *tmp_qp = (struct qat_qp *)qp;
639 : 0 : struct qat_comp_dev_private *dev =
640 : 0 : tmp_qp->qat_dev->pmd[QAT_SERVICE_COMPRESSION];
641 : :
642 [ # # ]: 0 : if (ret) {
643 [ # # ]: 0 : if ((*ops)->debug_status ==
644 : : (uint64_t)ERR_CODE_QAT_COMP_WRONG_FW) {
645 : 0 : dev->compressdev->enqueue_burst =
646 : : qat_comp_pmd_enq_deq_dummy_op_burst;
647 : 0 : dev->compressdev->dequeue_burst =
648 : : qat_comp_pmd_enq_deq_dummy_op_burst;
649 : :
650 : 0 : dev->compressdev->dev_ops =
651 : : &compress_qat_dummy_ops;
652 : 0 : QAT_LOG(ERR,
653 : : "This QAT hardware doesn't support compression operation");
654 : :
655 : : } else {
656 : 0 : dev->compressdev->dequeue_burst =
657 : : qat_comp_dequeue_burst;
658 : : }
659 : : }
660 : 0 : return ret;
661 : : }
662 : :
663 : : /* An rte_driver is needed in the registration of the device with compressdev.
664 : : * The actual qat pci's rte_driver can't be used as its name represents
665 : : * the whole pci device with all services. Think of this as a holder for a name
666 : : * for the compression part of the pci device.
667 : : */
668 : : static const char qat_comp_drv_name[] = RTE_STR(COMPRESSDEV_NAME_QAT_PMD);
669 : : static const struct rte_driver compdev_qat_driver = {
670 : : .name = qat_comp_drv_name,
671 : : .alias = qat_comp_drv_name
672 : : };
673 : :
674 : : static int
675 : 0 : qat_comp_dev_create(struct qat_pci_device *qat_pci_dev)
676 : : {
677 : : struct qat_device_info *qat_dev_instance =
678 : 0 : &qat_pci_devs[qat_pci_dev->qat_dev_id];
679 : 0 : struct rte_compressdev_pmd_init_params init_params = {
680 : : .name = "",
681 : 0 : .socket_id = qat_dev_instance->pci_dev->device.numa_node,
682 : : };
683 : : char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
684 : : char capa_memz_name[RTE_COMPRESSDEV_NAME_MAX_LEN];
685 : : struct rte_compressdev *compressdev;
686 : : struct qat_comp_dev_private *comp_dev;
687 : : struct qat_comp_capabilities_info capabilities_info;
688 : : const struct rte_compressdev_capabilities *capabilities;
689 : : const struct qat_comp_gen_dev_ops *qat_comp_gen_ops =
690 : 0 : &qat_comp_gen_dev_ops[qat_pci_dev->qat_dev_gen];
691 : : uint64_t capa_size;
692 : 0 : uint16_t sub_id = qat_dev_instance->pci_dev->id.subsystem_device_id;
693 : : char *cmdline = NULL;
694 : :
695 : : snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s",
696 : 0 : qat_pci_dev->name, "comp");
697 : 0 : QAT_LOG(DEBUG, "Creating QAT COMP device %s", name);
698 : :
699 [ # # # # ]: 0 : if (qat_pci_dev->qat_dev_gen == QAT_VQAT &&
700 : : sub_id != ADF_VQAT_DC_PCI_SUBSYSTEM_ID) {
701 : 0 : QAT_LOG(ERR, "Device (vqat instance) %s does not support compression",
702 : : name);
703 : 0 : return -EFAULT;
704 : : }
705 [ # # ]: 0 : if (qat_comp_gen_ops->compressdev_ops == NULL) {
706 : 0 : QAT_LOG(DEBUG, "Device %s does not support compression", name);
707 : 0 : return -ENOTSUP;
708 : : }
709 : :
710 : : /* Populate subset device to use in compressdev device creation */
711 : 0 : qat_dev_instance->comp_rte_dev.driver = &compdev_qat_driver;
712 : 0 : qat_dev_instance->comp_rte_dev.numa_node =
713 : 0 : qat_dev_instance->pci_dev->device.numa_node;
714 : 0 : qat_dev_instance->comp_rte_dev.devargs = NULL;
715 : :
716 : 0 : compressdev = rte_compressdev_pmd_create(name,
717 : : &(qat_dev_instance->comp_rte_dev),
718 : : sizeof(struct qat_comp_dev_private),
719 : : &init_params);
720 : :
721 [ # # ]: 0 : if (compressdev == NULL)
722 : : return -ENODEV;
723 : :
724 : 0 : compressdev->dev_ops = qat_comp_gen_ops->compressdev_ops;
725 : :
726 : 0 : compressdev->enqueue_burst = (compressdev_enqueue_pkt_burst_t)
727 : : qat_enqueue_comp_op_burst;
728 : 0 : compressdev->dequeue_burst = qat_comp_pmd_dequeue_first_op_burst;
729 : 0 : compressdev->feature_flags =
730 : 0 : qat_comp_gen_ops->qat_comp_get_feature_flags();
731 : :
732 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
733 : : return 0;
734 : :
735 : : snprintf(capa_memz_name, RTE_COMPRESSDEV_NAME_MAX_LEN,
736 : : "QAT_COMP_CAPA_GEN_%d",
737 [ # # ]: 0 : qat_pci_dev->qat_dev_gen);
738 : :
739 : 0 : comp_dev = compressdev->data->dev_private;
740 : 0 : comp_dev->qat_dev = qat_pci_dev;
741 : 0 : comp_dev->compressdev = compressdev;
742 : :
743 [ # # ]: 0 : capabilities_info = qat_comp_get_capa_info(qat_pci_dev->qat_dev_gen,
744 : : qat_pci_dev);
745 : :
746 [ # # ]: 0 : if (capabilities_info.data == NULL) {
747 : 0 : QAT_LOG(DEBUG,
748 : : "QAT gen %d capabilities unknown, default to GEN1",
749 : : qat_pci_dev->qat_dev_gen);
750 : : capabilities_info = qat_comp_get_capa_info(QAT_GEN1,
751 : : qat_pci_dev);
752 : : }
753 : :
754 : : capabilities = capabilities_info.data;
755 : : capa_size = capabilities_info.size;
756 : :
757 : 0 : comp_dev->capa_mz = rte_memzone_lookup(capa_memz_name);
758 [ # # ]: 0 : if (comp_dev->capa_mz == NULL) {
759 : 0 : comp_dev->capa_mz = rte_memzone_reserve(capa_memz_name,
760 : : capa_size,
761 : 0 : rte_socket_id(), 0);
762 : : }
763 [ # # ]: 0 : if (comp_dev->capa_mz == NULL) {
764 : 0 : QAT_LOG(DEBUG,
765 : : "Error allocating memzone for capabilities, destroying PMD for %s",
766 : : name);
767 : : memset(&qat_dev_instance->comp_rte_dev, 0,
768 : : sizeof(qat_dev_instance->comp_rte_dev));
769 : 0 : rte_compressdev_pmd_destroy(compressdev);
770 : 0 : return -EFAULT;
771 : : }
772 : :
773 : 0 : memcpy(comp_dev->capa_mz->addr, capabilities, capa_size);
774 : 0 : comp_dev->qat_dev_capabilities = comp_dev->capa_mz->addr;
775 : :
776 : 0 : cmdline = qat_dev_cmdline_get_val(qat_pci_dev,
777 : : COMP_ENQ_THRESHOLD_NAME);
778 [ # # ]: 0 : if (cmdline) {
779 [ # # ]: 0 : comp_dev->min_enq_burst_threshold =
780 : : atoi(cmdline) > MAX_QP_THRESHOLD_SIZE ?
781 : : MAX_QP_THRESHOLD_SIZE :
782 : : atoi(cmdline);
783 : : }
784 : 0 : qat_pci_dev->pmd[QAT_SERVICE_COMPRESSION] = comp_dev;
785 : :
786 : 0 : QAT_LOG(DEBUG,
787 : : "Created QAT COMP device %s as compressdev instance %d",
788 : : name, compressdev->data->dev_id);
789 : 0 : return 0;
790 : : }
791 : :
792 : : static int
793 : 0 : qat_comp_dev_destroy(struct qat_pci_device *qat_pci_dev)
794 : : {
795 : : struct qat_comp_dev_private *dev;
796 : :
797 [ # # ]: 0 : if (qat_pci_dev == NULL)
798 : : return -ENODEV;
799 : :
800 : 0 : dev = qat_pci_dev->pmd[QAT_SERVICE_COMPRESSION];
801 [ # # ]: 0 : if (dev == NULL)
802 : : return 0;
803 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY)
804 : 0 : rte_memzone_free(dev->capa_mz);
805 : :
806 : : /* clean up any resources used by the device */
807 : 0 : qat_comp_dev_close(dev->compressdev);
808 : :
809 : 0 : rte_compressdev_pmd_destroy(dev->compressdev);
810 : 0 : qat_pci_dev->pmd[QAT_SERVICE_COMPRESSION] = NULL;
811 : :
812 : 0 : return 0;
813 : : }
814 : :
815 : 251 : RTE_INIT(qat_sym_init)
816 : : {
817 : 251 : qat_cmdline_defines[QAT_SERVICE_COMPRESSION] = arguments;
818 : 251 : qat_service[QAT_SERVICE_COMPRESSION].name = "symmetric crypto";
819 : 251 : qat_service[QAT_SERVICE_COMPRESSION].dev_create = qat_comp_dev_create;
820 : 251 : qat_service[QAT_SERVICE_COMPRESSION].dev_destroy = qat_comp_dev_destroy;
821 : 251 : }
|