compress/qat: add xform processing
[dpdk.git] / drivers / compress / qat / qat_comp.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4
5
6 #include <rte_mempool.h>
7 #include <rte_mbuf.h>
8 #include <rte_hexdump.h>
9 #include <rte_comp.h>
10 #include <rte_bus_pci.h>
11 #include <rte_byteorder.h>
12 #include <rte_memcpy.h>
13 #include <rte_common.h>
14 #include <rte_spinlock.h>
15 #include <rte_log.h>
16 #include <rte_malloc.h>
17
18 #include "qat_logs.h"
19 #include "qat_comp.h"
20 #include "qat_comp_pmd.h"
21
22 unsigned int
23 qat_comp_xform_size(void)
24 {
25         return RTE_ALIGN_CEIL(sizeof(struct qat_comp_xform), 8);
26 }
27
28 static void qat_comp_create_req_hdr(struct icp_qat_fw_comn_req_hdr *header,
29                                     enum qat_comp_request_type request)
30 {
31         if (request == QAT_COMP_REQUEST_FIXED_COMP_STATELESS)
32                 header->service_cmd_id = ICP_QAT_FW_COMP_CMD_STATIC;
33         else if (request == QAT_COMP_REQUEST_DYNAMIC_COMP_STATELESS)
34                 header->service_cmd_id = ICP_QAT_FW_COMP_CMD_DYNAMIC;
35         else if (request == QAT_COMP_REQUEST_DECOMPRESS)
36                 header->service_cmd_id = ICP_QAT_FW_COMP_CMD_DECOMPRESS;
37
38         header->service_type = ICP_QAT_FW_COMN_REQ_CPM_FW_COMP;
39         header->hdr_flags =
40             ICP_QAT_FW_COMN_HDR_FLAGS_BUILD(ICP_QAT_FW_COMN_REQ_FLAG_SET);
41
42         header->comn_req_flags = ICP_QAT_FW_COMN_FLAGS_BUILD(
43             QAT_COMN_CD_FLD_TYPE_16BYTE_DATA, QAT_COMN_PTR_TYPE_FLAT);
44 }
45
46 static int qat_comp_create_templates(struct qat_comp_xform *qat_xform,
47                         const struct rte_memzone *interm_buff_mz __rte_unused,
48                         const struct rte_comp_xform *xform)
49 {
50         struct icp_qat_fw_comp_req *comp_req;
51         int comp_level, algo;
52         uint32_t req_par_flags;
53         int direction = ICP_QAT_HW_COMPRESSION_DIR_COMPRESS;
54
55         if (unlikely(qat_xform == NULL)) {
56                 QAT_LOG(ERR, "Session was not created for this device");
57                 return -EINVAL;
58         }
59
60         if (qat_xform->qat_comp_request_type == QAT_COMP_REQUEST_DECOMPRESS) {
61                 direction = ICP_QAT_HW_COMPRESSION_DIR_DECOMPRESS;
62                 comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_1;
63                 req_par_flags = ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(
64                                 ICP_QAT_FW_COMP_SOP, ICP_QAT_FW_COMP_EOP,
65                                 ICP_QAT_FW_COMP_BFINAL, ICP_QAT_FW_COMP_NO_CNV,
66                                 ICP_QAT_FW_COMP_NO_CNV_RECOVERY);
67
68         } else {
69                 if (xform->compress.level == RTE_COMP_LEVEL_PMD_DEFAULT)
70                         comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_8;
71                 else if (xform->compress.level == 1)
72                         comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_1;
73                 else if (xform->compress.level == 2)
74                         comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_4;
75                 else if (xform->compress.level == 3)
76                         comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_8;
77                 else if (xform->compress.level >= 4 &&
78                          xform->compress.level <= 9)
79                         comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_16;
80                 else {
81                         QAT_LOG(ERR, "compression level not supported");
82                         return -EINVAL;
83                 }
84                 req_par_flags = ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(
85                                 ICP_QAT_FW_COMP_SOP, ICP_QAT_FW_COMP_EOP,
86                                 ICP_QAT_FW_COMP_BFINAL, ICP_QAT_FW_COMP_CNV,
87                                 ICP_QAT_FW_COMP_CNV_RECOVERY);
88         }
89
90         switch (xform->compress.algo) {
91         case RTE_COMP_ALGO_DEFLATE:
92                 algo = ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE;
93                 break;
94         case RTE_COMP_ALGO_LZS:
95         default:
96                 /* RTE_COMP_NULL */
97                 QAT_LOG(ERR, "compression algorithm not supported");
98                 return -EINVAL;
99         }
100
101         comp_req = &qat_xform->qat_comp_req_tmpl;
102
103         /* Initialize header */
104         qat_comp_create_req_hdr(&comp_req->comn_hdr,
105                                         qat_xform->qat_comp_request_type);
106
107         comp_req->comn_hdr.serv_specif_flags = ICP_QAT_FW_COMP_FLAGS_BUILD(
108             ICP_QAT_FW_COMP_STATELESS_SESSION,
109             ICP_QAT_FW_COMP_NOT_AUTO_SELECT_BEST,
110             ICP_QAT_FW_COMP_NOT_ENH_AUTO_SELECT_BEST,
111             ICP_QAT_FW_COMP_NOT_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST,
112             ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_USED_AS_INTMD_BUF);
113
114         comp_req->cd_pars.sl.comp_slice_cfg_word[0] =
115             ICP_QAT_HW_COMPRESSION_CONFIG_BUILD(
116                 direction,
117                 /* In CPM 1.6 only valid mode ! */
118                 ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED, algo,
119                 /* Translate level to depth */
120                 comp_level, ICP_QAT_HW_COMPRESSION_FILE_TYPE_0);
121
122         comp_req->comp_pars.initial_adler = 1;
123         comp_req->comp_pars.initial_crc32 = 0;
124         comp_req->comp_pars.req_par_flags = req_par_flags;
125
126
127         if (qat_xform->qat_comp_request_type ==
128                         QAT_COMP_REQUEST_FIXED_COMP_STATELESS ||
129             qat_xform->qat_comp_request_type == QAT_COMP_REQUEST_DECOMPRESS) {
130                 ICP_QAT_FW_COMN_NEXT_ID_SET(&comp_req->comp_cd_ctrl,
131                                             ICP_QAT_FW_SLICE_DRAM_WR);
132                 ICP_QAT_FW_COMN_CURR_ID_SET(&comp_req->comp_cd_ctrl,
133                                             ICP_QAT_FW_SLICE_COMP);
134         } else if (qat_xform->qat_comp_request_type ==
135                    QAT_COMP_REQUEST_DYNAMIC_COMP_STATELESS) {
136
137                 QAT_LOG(ERR, "Dynamic huffman encoding not supported");
138                 return -EINVAL;
139         }
140
141 #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
142         QAT_DP_HEXDUMP_LOG(DEBUG, "qat compression message template:", comp_req,
143                     sizeof(struct icp_qat_fw_comp_req));
144 #endif
145         return 0;
146 }
147
148 /**
149  * Create driver private_xform data.
150  *
151  * @param dev
152  *   Compressdev device
153  * @param xform
154  *   xform data from application
155  * @param private_xform
156  *   ptr where handle of pmd's private_xform data should be stored
157  * @return
158  *  - if successful returns 0
159  *    and valid private_xform handle
160  *  - <0 in error cases
161  *  - Returns -EINVAL if input parameters are invalid.
162  *  - Returns -ENOTSUP if comp device does not support the comp transform.
163  *  - Returns -ENOMEM if the private_xform could not be allocated.
164  */
165 int
166 qat_comp_private_xform_create(struct rte_compressdev *dev,
167                               const struct rte_comp_xform *xform,
168                               void **private_xform)
169 {
170         struct qat_comp_dev_private *qat = dev->data->dev_private;
171
172         if (unlikely(private_xform == NULL)) {
173                 QAT_LOG(ERR, "QAT: private_xform parameter is NULL");
174                 return -EINVAL;
175         }
176         if (unlikely(qat->xformpool == NULL)) {
177                 QAT_LOG(ERR, "QAT device has no private_xform mempool");
178                 return -ENOMEM;
179         }
180         if (rte_mempool_get(qat->xformpool, private_xform)) {
181                 QAT_LOG(ERR, "Couldn't get object from qat xform mempool");
182                 return -ENOMEM;
183         }
184
185         struct qat_comp_xform *qat_xform =
186                         (struct qat_comp_xform *)*private_xform;
187
188         if (xform->type == RTE_COMP_COMPRESS) {
189                 if (xform->compress.deflate.huffman ==
190                                 RTE_COMP_HUFFMAN_DYNAMIC) {
191                         QAT_LOG(ERR,
192                         "QAT device doesn't support dynamic compression");
193                         return -ENOTSUP;
194                 }
195
196                 if (xform->compress.deflate.huffman == RTE_COMP_HUFFMAN_FIXED ||
197                   ((xform->compress.deflate.huffman == RTE_COMP_HUFFMAN_DEFAULT)
198                                    && qat->interm_buff_mz == NULL))
199
200                         qat_xform->qat_comp_request_type =
201                                         QAT_COMP_REQUEST_FIXED_COMP_STATELESS;
202
203
204         } else {
205                 qat_xform->qat_comp_request_type = QAT_COMP_REQUEST_DECOMPRESS;
206         }
207
208         qat_xform->checksum_type = xform->compress.chksum;
209
210         if (qat_comp_create_templates(qat_xform, qat->interm_buff_mz, xform)) {
211                 QAT_LOG(ERR, "QAT: Problem with setting compression");
212                 return -EINVAL;
213         }
214         return 0;
215 }
216
217 /**
218  * Free driver private_xform data.
219  *
220  * @param dev
221  *   Compressdev device
222  * @param private_xform
223  *   handle of pmd's private_xform data
224  * @return
225  *  - 0 if successful
226  *  - <0 in error cases
227  *  - Returns -EINVAL if input parameters are invalid.
228  */
229 int
230 qat_comp_private_xform_free(struct rte_compressdev *dev __rte_unused,
231                             void *private_xform)
232 {
233         struct qat_comp_xform *qat_xform =
234                         (struct qat_comp_xform *)private_xform;
235
236         if (qat_xform) {
237                 memset(qat_xform, 0, qat_comp_xform_size());
238                 struct rte_mempool *mp = rte_mempool_from_obj(qat_xform);
239
240                 rte_mempool_put(mp, qat_xform);
241                 return 0;
242         }
243         return -EINVAL;
244 }