Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2024 Marvell.
3 : : */
4 : :
5 : : #include <rte_compressdev_pmd.h>
6 : : #include <rte_errno.h>
7 : : #include <rte_malloc.h>
8 : : #include <rte_hexdump.h>
9 : :
10 : : #include "nitrox_comp_reqmgr.h"
11 : : #include "nitrox_logs.h"
12 : : #include "rte_comp.h"
13 : :
14 : : #define NITROX_INSTR_BUFFER_DEBUG 0
15 : : #define NITROX_ZIP_SGL_COUNT 16
16 : : #define NITROX_ZIP_MAX_ZPTRS 2048
17 : : #define NITROX_ZIP_MAX_DATASIZE ((1 << 24) - 1)
18 : : #define NITROX_ZIP_MAX_ONFSIZE 1024
19 : : #define CMD_TIMEOUT 2
20 : :
21 : : union nitrox_zip_instr_word0 {
22 : : uint64_t u64;
23 : : struct {
24 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
25 : : uint64_t raz0 : 8;
26 : : uint64_t tol : 24;
27 : : uint64_t raz1 : 5;
28 : : uint64_t exn : 3;
29 : : uint64_t raz2 : 1;
30 : : uint64_t exbits : 7;
31 : : uint64_t raz3 : 3;
32 : : uint64_t ca : 1;
33 : : uint64_t sf : 1;
34 : : uint64_t ss : 2;
35 : : uint64_t cc : 2;
36 : : uint64_t ef : 1;
37 : : uint64_t bf : 1;
38 : : uint64_t co : 1;
39 : : uint64_t raz4 : 1;
40 : : uint64_t ds : 1;
41 : : uint64_t dg : 1;
42 : : uint64_t hg : 1;
43 : : #else
44 : : uint64_t hg : 1;
45 : : uint64_t dg : 1;
46 : : uint64_t ds : 1;
47 : : uint64_t raz4 : 1;
48 : : uint64_t co : 1;
49 : : uint64_t bf : 1;
50 : : uint64_t ef : 1;
51 : : uint64_t cc : 2;
52 : : uint64_t ss : 2;
53 : : uint64_t sf : 1;
54 : : uint64_t ca : 1;
55 : : uint64_t raz3 : 3;
56 : : uint64_t exbits : 7;
57 : : uint64_t raz2 : 1;
58 : : uint64_t exn : 3;
59 : : uint64_t raz1 : 5;
60 : : uint64_t tol : 24;
61 : : uint64_t raz0 : 8;
62 : : #endif
63 : :
64 : : };
65 : : };
66 : :
67 : : union nitrox_zip_instr_word1 {
68 : : uint64_t u64;
69 : : struct {
70 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
71 : : uint64_t hl : 16;
72 : : uint64_t raz0 : 16;
73 : : uint64_t adlercrc32 : 32;
74 : : #else
75 : : uint64_t adlercrc32 : 32;
76 : : uint64_t raz0 : 16;
77 : : uint64_t hl : 16;
78 : : #endif
79 : : };
80 : : };
81 : :
82 : : union nitrox_zip_instr_word2 {
83 : : uint64_t u64;
84 : : struct {
85 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
86 : : uint64_t raz0 : 20;
87 : : uint64_t cptr : 44;
88 : : #else
89 : : uint64_t cptr : 44;
90 : : uint64_t raz0 : 20;
91 : : #endif
92 : : };
93 : : };
94 : :
95 : : union nitrox_zip_instr_word3 {
96 : : uint64_t u64;
97 : : struct {
98 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
99 : : uint64_t raz0 : 4;
100 : : uint64_t hlen : 16;
101 : : uint64_t hptr : 44;
102 : : #else
103 : : uint64_t hptr : 44;
104 : : uint64_t hlen : 16;
105 : : uint64_t raz0 : 4;
106 : : #endif
107 : : };
108 : : };
109 : :
110 : : union nitrox_zip_instr_word4 {
111 : : uint64_t u64;
112 : : struct {
113 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
114 : : uint64_t raz0 : 4;
115 : : uint64_t ilen : 16;
116 : : uint64_t iptr : 44;
117 : : #else
118 : : uint64_t iptr : 44;
119 : : uint64_t ilen : 16;
120 : : uint64_t raz0 : 4;
121 : : #endif
122 : : };
123 : : };
124 : :
125 : : union nitrox_zip_instr_word5 {
126 : : uint64_t u64;
127 : : struct {
128 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
129 : : uint64_t raz0 : 4;
130 : : uint64_t olen : 16;
131 : : uint64_t optr : 44;
132 : : #else
133 : : uint64_t optr : 44;
134 : : uint64_t olen : 16;
135 : : uint64_t raz0 : 4;
136 : : #endif
137 : : };
138 : : };
139 : :
140 : : union nitrox_zip_instr_word6 {
141 : : uint64_t u64;
142 : : struct {
143 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
144 : : uint64_t raz0 : 20;
145 : : uint64_t rptr : 44;
146 : : #else
147 : : uint64_t rptr : 44;
148 : : uint64_t raz0 : 20;
149 : : #endif
150 : : };
151 : : };
152 : :
153 : : union nitrox_zip_instr_word7 {
154 : : uint64_t u64;
155 : : struct {
156 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
157 : : uint64_t grp : 3;
158 : : uint64_t raz0 : 41;
159 : : uint64_t addr_msb: 20;
160 : : #else
161 : : uint64_t addr_msb: 20;
162 : : uint64_t raz0 : 41;
163 : : uint64_t grp : 3;
164 : : #endif
165 : : };
166 : : };
167 : :
168 : : struct nitrox_zip_instr {
169 : : union nitrox_zip_instr_word0 w0;
170 : : union nitrox_zip_instr_word1 w1;
171 : : union nitrox_zip_instr_word2 w2;
172 : : union nitrox_zip_instr_word3 w3;
173 : : union nitrox_zip_instr_word4 w4;
174 : : union nitrox_zip_instr_word5 w5;
175 : : union nitrox_zip_instr_word6 w6;
176 : : union nitrox_zip_instr_word7 w7;
177 : : };
178 : :
179 : : union nitrox_zip_result_word0 {
180 : : uint64_t u64;
181 : : struct {
182 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
183 : : uint64_t crc32 : 32;
184 : : uint64_t adler32: 32;
185 : : #else
186 : : uint64_t adler32: 32;
187 : : uint64_t crc32 : 32;
188 : : #endif
189 : : };
190 : : };
191 : :
192 : : union nitrox_zip_result_word1 {
193 : : uint64_t u64;
194 : : struct {
195 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
196 : : uint64_t tbyteswritten : 32;
197 : : uint64_t tbytesread : 32;
198 : : #else
199 : : uint64_t tbytesread : 32;
200 : : uint64_t tbyteswritten : 32;
201 : : #endif
202 : : };
203 : : };
204 : :
205 : : union nitrox_zip_result_word2 {
206 : : uint64_t u64;
207 : : struct {
208 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
209 : : uint64_t tbits : 32;
210 : : uint64_t raz0 : 5;
211 : : uint64_t exn : 3;
212 : : uint64_t raz1 : 1;
213 : : uint64_t exbits : 7;
214 : : uint64_t raz2 : 7;
215 : : uint64_t ef : 1;
216 : : uint64_t compcode: 8;
217 : : #else
218 : : uint64_t compcode: 8;
219 : : uint64_t ef : 1;
220 : : uint64_t raz2 : 7;
221 : : uint64_t exbits : 7;
222 : : uint64_t raz1 : 1;
223 : : uint64_t exn : 3;
224 : : uint64_t raz0 : 5;
225 : : uint64_t tbits : 32;
226 : : #endif
227 : : };
228 : : };
229 : :
230 : : struct nitrox_zip_result {
231 : : union nitrox_zip_result_word0 w0;
232 : : union nitrox_zip_result_word1 w1;
233 : : union nitrox_zip_result_word2 w2;
234 : : };
235 : :
236 : : union nitrox_zip_zptr {
237 : : uint64_t u64;
238 : : struct {
239 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
240 : : uint64_t raz0 : 3;
241 : : uint64_t le : 1;
242 : : uint64_t length : 16;
243 : : uint64_t addr : 44;
244 : : #else
245 : : uint64_t addr : 44;
246 : : uint64_t length : 16;
247 : : uint64_t le : 1;
248 : : uint64_t raz0 : 3;
249 : : #endif
250 : : } s;
251 : : };
252 : :
253 : : struct nitrox_zip_iova_addr {
254 : : union {
255 : : uint64_t u64;
256 : : struct {
257 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
258 : : uint64_t addr_msb: 20;
259 : : uint64_t addr : 44;
260 : : #else
261 : : uint64_t addr : 44;
262 : : uint64_t addr_msb: 20;
263 : : #endif
264 : : } zda;
265 : :
266 : : struct {
267 : : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
268 : : uint64_t addr_msb: 20;
269 : : uint64_t addr : 41;
270 : : uint64_t align_8bytes: 3;
271 : : #else
272 : : uint64_t align_8bytes: 3;
273 : : uint64_t addr : 41;
274 : : uint64_t addr_msb: 20;
275 : : #endif
276 : : } z8a;
277 : : };
278 : : };
279 : :
280 : : enum nitrox_zip_comp_code {
281 : : NITROX_CC_NOTDONE = 0,
282 : : NITROX_CC_SUCCESS = 1,
283 : : NITROX_CC_DTRUNC = 2,
284 : : NITROX_CC_STOP = 3,
285 : : NITROX_CC_ITRUNK = 4,
286 : : NITROX_CC_RBLOCK = 5,
287 : : NITROX_CC_NLEN = 6,
288 : : NITROX_CC_BADCODE = 7,
289 : : NITROX_CC_BADCODE2 = 8,
290 : : NITROX_CC_ZERO_LEN = 9,
291 : : NITROX_CC_PARITY = 10,
292 : : NITROX_CC_FATAL = 11,
293 : : NITROX_CC_TIMEOUT = 12,
294 : : NITROX_CC_NPCI_ERR = 13,
295 : : };
296 : :
297 : : struct nitrox_sgtable {
298 : : union nitrox_zip_zptr *sgl;
299 : : uint64_t addr_msb;
300 : : uint32_t total_bytes;
301 : : uint16_t nb_sgls;
302 : : uint16_t filled_sgls;
303 : : };
304 : :
305 : : struct nitrox_softreq {
306 : : struct nitrox_zip_instr instr;
307 : : alignas(8) struct nitrox_zip_result zip_res;
308 : : uint8_t decomp_threshold[NITROX_ZIP_MAX_ONFSIZE];
309 : : struct rte_comp_op *op;
310 : : struct nitrox_sgtable src;
311 : : struct nitrox_sgtable dst;
312 : : uint64_t timeout;
313 : : };
314 : :
315 : : #if NITROX_INSTR_BUFFER_DEBUG
316 : : static void nitrox_dump_databuf(const char *name, struct rte_mbuf *m,
317 : : uint32_t off, uint32_t datalen)
318 : : {
319 : : uint32_t mlen;
320 : :
321 : : if (!rte_log_can_log(nitrox_logtype, RTE_LOG_DEBUG))
322 : : return;
323 : :
324 : : for (; m && off > rte_pktmbuf_data_len(m); m = m->next)
325 : : off -= rte_pktmbuf_data_len(m);
326 : :
327 : : mlen = rte_pktmbuf_data_len(m) - off;
328 : : if (datalen <= mlen)
329 : : mlen = datalen;
330 : :
331 : : rte_hexdump(rte_log_get_stream(), name,
332 : : rte_pktmbuf_mtod_offset(m, char *, off), mlen);
333 : : for (m = m->next; m && datalen; m = m->next) {
334 : : mlen = rte_pktmbuf_data_len(m) < datalen ?
335 : : rte_pktmbuf_data_len(m) : datalen;
336 : : rte_hexdump(rte_log_get_stream(), name,
337 : : rte_pktmbuf_mtod(m, char *), mlen);
338 : : }
339 : :
340 : : NITROX_LOG_LINE(DEBUG,);
341 : : }
342 : :
343 : : static void nitrox_dump_zip_instr(struct nitrox_zip_instr *instr,
344 : : union nitrox_zip_zptr *hptr_arr,
345 : : union nitrox_zip_zptr *iptr_arr,
346 : : union nitrox_zip_zptr *optr_arr)
347 : : {
348 : : uint64_t value;
349 : : int i = 0;
350 : :
351 : : NITROX_LOG_LINE(DEBUG, "\nZIP instruction..(%p)", instr);
352 : : NITROX_LOG_LINE(DEBUG, "\tWORD0 = 0x%016"PRIx64, instr->w0.u64);
353 : : NITROX_LOG_LINE(DEBUG, "\t\tTOL = %d", instr->w0.tol);
354 : : NITROX_LOG_LINE(DEBUG, "\t\tEXNUM = %d", instr->w0.exn);
355 : : NITROX_LOG_LINE(DEBUG, "\t\tEXBITS = %x", instr->w0.exbits);
356 : : NITROX_LOG_LINE(DEBUG, "\t\tCA = %d", instr->w0.ca);
357 : : NITROX_LOG_LINE(DEBUG, "\t\tSF = %d", instr->w0.sf);
358 : : NITROX_LOG_LINE(DEBUG, "\t\tSS = %d", instr->w0.ss);
359 : : NITROX_LOG_LINE(DEBUG, "\t\tCC = %d", instr->w0.cc);
360 : : NITROX_LOG_LINE(DEBUG, "\t\tEF = %d", instr->w0.ef);
361 : : NITROX_LOG_LINE(DEBUG, "\t\tBF = %d", instr->w0.bf);
362 : : NITROX_LOG_LINE(DEBUG, "\t\tCO = %d", instr->w0.co);
363 : : NITROX_LOG_LINE(DEBUG, "\t\tDS = %d", instr->w0.ds);
364 : : NITROX_LOG_LINE(DEBUG, "\t\tDG = %d", instr->w0.dg);
365 : : NITROX_LOG_LINE(DEBUG, "\t\tHG = %d", instr->w0.hg);
366 : : NITROX_LOG_LINE(DEBUG,);
367 : :
368 : : NITROX_LOG_LINE(DEBUG, "\tWORD1 = 0x%016"PRIx64, instr->w1.u64);
369 : : NITROX_LOG_LINE(DEBUG, "\t\tHL = %d", instr->w1.hl);
370 : : NITROX_LOG_LINE(DEBUG, "\t\tADLERCRC32 = 0x%08x", instr->w1.adlercrc32);
371 : : NITROX_LOG_LINE(DEBUG,);
372 : :
373 : : value = instr->w2.cptr;
374 : : NITROX_LOG_LINE(DEBUG, "\tWORD2 = 0x%016"PRIx64, instr->w2.u64);
375 : : NITROX_LOG_LINE(DEBUG, "\t\tCPTR = 0x%11"PRIx64, value);
376 : : NITROX_LOG_LINE(DEBUG,);
377 : :
378 : : value = instr->w3.hptr;
379 : : NITROX_LOG_LINE(DEBUG, "\tWORD3 = 0x%016"PRIx64, instr->w3.u64);
380 : : NITROX_LOG_LINE(DEBUG, "\t\tHLEN = %d", instr->w3.hlen);
381 : : NITROX_LOG_LINE(DEBUG, "\t\tHPTR = 0x%11"PRIx64, value);
382 : :
383 : : if (instr->w0.hg && hptr_arr) {
384 : : for (i = 0; i < instr->w3.hlen; i++) {
385 : : value = hptr_arr[i].s.addr;
386 : : NITROX_LOG_LINE(DEBUG, "\t\t\tZPTR[%d] : Length = %d Addr = 0x%11"PRIx64,
387 : : i, hptr_arr[i].s.length, value);
388 : : }
389 : : }
390 : :
391 : : NITROX_LOG_LINE(DEBUG,);
392 : :
393 : : value = instr->w4.iptr;
394 : : NITROX_LOG_LINE(DEBUG, "\tWORD4 = 0x%016"PRIx64, instr->w4.u64);
395 : : NITROX_LOG_LINE(DEBUG, "\t\tILEN = %d", instr->w4.ilen);
396 : : NITROX_LOG_LINE(DEBUG, "\t\tIPTR = 0x%11"PRIx64, value);
397 : : if (instr->w0.dg && iptr_arr) {
398 : : for (i = 0; i < instr->w4.ilen; i++) {
399 : : value = iptr_arr[i].s.addr;
400 : : NITROX_LOG_LINE(DEBUG, "\t\t\tZPTR[%d] : Length = %d Addr = 0x%11"PRIx64,
401 : : i, iptr_arr[i].s.length, value);
402 : : }
403 : : }
404 : :
405 : : NITROX_LOG_LINE(DEBUG,);
406 : :
407 : : value = instr->w5.optr;
408 : : NITROX_LOG_LINE(DEBUG, "\tWORD5 = 0x%016"PRIx64, instr->w5.u64);
409 : : NITROX_LOG_LINE(DEBUG, "\t\t OLEN = %d", instr->w5.olen);
410 : : NITROX_LOG_LINE(DEBUG, "\t\t OPTR = 0x%11"PRIx64, value);
411 : : if (instr->w0.ds && optr_arr) {
412 : : for (i = 0; i < instr->w5.olen; i++) {
413 : : value = optr_arr[i].s.addr;
414 : : NITROX_LOG_LINE(DEBUG, "\t\t\tZPTR[%d] : Length = %d Addr = 0x%11"PRIx64,
415 : : i, optr_arr[i].s.length, value);
416 : : }
417 : : }
418 : :
419 : : NITROX_LOG_LINE(DEBUG,);
420 : :
421 : : value = instr->w6.rptr;
422 : : NITROX_LOG_LINE(DEBUG, "\tWORD6 = 0x%016"PRIx64, instr->w6.u64);
423 : : NITROX_LOG_LINE(DEBUG, "\t\tRPTR = 0x%11"PRIx64, value);
424 : : NITROX_LOG_LINE(DEBUG,);
425 : :
426 : : NITROX_LOG_LINE(DEBUG, "\tWORD7 = 0x%016"PRIx64, instr->w7.u64);
427 : : NITROX_LOG_LINE(DEBUG, "\t\tGRP = %x", instr->w7.grp);
428 : : NITROX_LOG_LINE(DEBUG, "\t\tADDR_MSB = 0x%5x", instr->w7.addr_msb);
429 : : NITROX_LOG_LINE(DEBUG,);
430 : : }
431 : :
432 : : static void nitrox_dump_zip_result(struct nitrox_zip_instr *instr,
433 : : struct nitrox_zip_result *result)
434 : : {
435 : : NITROX_LOG_LINE(DEBUG, "ZIP result..(instr %p)", instr);
436 : : NITROX_LOG_LINE(DEBUG, "\tWORD0 = 0x%016"PRIx64, result->w0.u64);
437 : : NITROX_LOG_LINE(DEBUG, "\t\tCRC32 = 0x%8x", result->w0.crc32);
438 : : NITROX_LOG_LINE(DEBUG, "\t\tADLER32 = 0x%8x", result->w0.adler32);
439 : : NITROX_LOG_LINE(DEBUG,);
440 : :
441 : : NITROX_LOG_LINE(DEBUG, "\tWORD1 = 0x%016"PRIx64, result->w1.u64);
442 : : NITROX_LOG_LINE(DEBUG, "\t\tTBYTESWRITTEN = %u", result->w1.tbyteswritten);
443 : : NITROX_LOG_LINE(DEBUG, "\t\tTBYTESREAD = %u", result->w1.tbytesread);
444 : : NITROX_LOG_LINE(DEBUG,);
445 : :
446 : : NITROX_LOG_LINE(DEBUG, "\tWORD2 = 0x%016"PRIx64, result->w2.u64);
447 : : NITROX_LOG_LINE(DEBUG, "\t\tTBITS = %u", result->w2.tbits);
448 : : NITROX_LOG_LINE(DEBUG, "\t\tEXN = %d", result->w2.exn);
449 : : NITROX_LOG_LINE(DEBUG, "\t\tEBITS = %x", result->w2.exbits);
450 : : NITROX_LOG_LINE(DEBUG, "\t\tEF = %d", result->w2.ef);
451 : : NITROX_LOG_LINE(DEBUG, "\t\tCOMPCODE = 0x%2x", result->w2.compcode);
452 : : NITROX_LOG_LINE(DEBUG,);
453 : : }
454 : : #else
455 : : #define nitrox_dump_databuf(name, m, off, datalen)
456 : : #define nitrox_dump_zip_instr(instr, hptr_arr, iptr_arr, optr_arr)
457 : : #define nitrox_dump_zip_result(instr, result)
458 : : #endif
459 : :
460 : 0 : static int handle_zero_length_compression(struct nitrox_softreq *sr,
461 : : struct nitrox_comp_xform *xform)
462 : : {
463 : : union {
464 : : uint32_t num;
465 : : uint8_t bytes[4];
466 : : } fblk;
467 : : uint32_t dstlen, rlen;
468 : : struct rte_mbuf *m;
469 : : uint32_t off;
470 : : uint32_t mlen;
471 : : uint32_t i = 0;
472 : : uint8_t *ptr;
473 : :
474 [ # # ]: 0 : fblk.num = xform->exn ? (xform->exbits & 0x7F) : 0;
475 : 0 : fblk.num |= (0x3 << xform->exn);
476 [ # # ]: 0 : memset(&sr->zip_res, 0, sizeof(sr->zip_res));
477 : 0 : sr->zip_res.w1.tbytesread = xform->hlen;
478 : 0 : sr->zip_res.w1.tbyteswritten = 2;
479 : 0 : sr->zip_res.w2.ef = 1;
480 [ # # ]: 0 : if (xform->exn == 7)
481 : 0 : sr->zip_res.w1.tbyteswritten++;
482 : :
483 : 0 : rlen = sr->zip_res.w1.tbyteswritten;
484 : 0 : dstlen = rte_pktmbuf_pkt_len(sr->op->m_dst) - sr->op->dst.offset;
485 [ # # ]: 0 : if (unlikely(dstlen < rlen))
486 : : return -EIO;
487 : :
488 : : off = sr->op->dst.offset;
489 [ # # # # ]: 0 : for (m = sr->op->m_dst; m && off > rte_pktmbuf_data_len(m); m = m->next)
490 : 0 : off -= rte_pktmbuf_data_len(m);
491 : :
492 [ # # ]: 0 : if (unlikely(!m))
493 : : return -EIO;
494 : :
495 : 0 : mlen = rte_pktmbuf_data_len(m) - off;
496 : : if (rlen <= mlen)
497 : : mlen = rlen;
498 : :
499 : 0 : ptr = rte_pktmbuf_mtod_offset(m, uint8_t *, off);
500 : 0 : memcpy(ptr, fblk.bytes, mlen);
501 : : i += mlen;
502 : 0 : rlen -= mlen;
503 [ # # ]: 0 : for (m = m->next; m && rlen; m = m->next) {
504 : 0 : mlen = rte_pktmbuf_data_len(m) < rlen ?
505 : : rte_pktmbuf_data_len(m) : rlen;
506 : 0 : ptr = rte_pktmbuf_mtod(m, uint8_t *);
507 : 0 : memcpy(ptr, &fblk.bytes[i], mlen);
508 : 0 : i += mlen;
509 : 0 : rlen -= mlen;
510 : : }
511 : :
512 [ # # ]: 0 : if (unlikely(rlen != 0))
513 : : return -EIO;
514 : :
515 : 0 : sr->zip_res.w2.compcode = NITROX_CC_SUCCESS;
516 : 0 : sr->op->status = RTE_COMP_OP_STATUS_SUCCESS;
517 [ # # ]: 0 : sr->zip_res.w0.u64 = rte_cpu_to_be_64(sr->zip_res.w0.u64);
518 [ # # ]: 0 : sr->zip_res.w1.u64 = rte_cpu_to_be_64(sr->zip_res.w1.u64);
519 [ # # ]: 0 : sr->zip_res.w2.u64 = rte_cpu_to_be_64(sr->zip_res.w2.u64);
520 : 0 : return 0;
521 : : }
522 : :
523 : 0 : static int create_sglist_from_mbuf(struct nitrox_sgtable *sgtbl,
524 : : struct rte_mbuf *mbuf, uint32_t off,
525 : : uint32_t datalen, uint8_t extra_segs,
526 : : int socket_id)
527 : : {
528 : : struct rte_mbuf *m;
529 : : union nitrox_zip_zptr *sgl;
530 : : struct nitrox_zip_iova_addr zip_addr;
531 : : uint16_t nb_segs;
532 : : uint16_t i;
533 : : uint32_t mlen;
534 : :
535 [ # # ]: 0 : if (unlikely(datalen > NITROX_ZIP_MAX_DATASIZE)) {
536 : 0 : NITROX_LOG_LINE(ERR, "Unsupported datalen %d, max supported %d",
537 : : datalen, NITROX_ZIP_MAX_DATASIZE);
538 : 0 : return -ENOTSUP;
539 : : }
540 : :
541 : 0 : nb_segs = mbuf->nb_segs + extra_segs;
542 [ # # # # ]: 0 : for (m = mbuf; m && off > rte_pktmbuf_data_len(m); m = m->next) {
543 : 0 : off -= rte_pktmbuf_data_len(m);
544 : 0 : nb_segs--;
545 : : }
546 : :
547 [ # # ]: 0 : if (unlikely(nb_segs > NITROX_ZIP_MAX_ZPTRS)) {
548 : 0 : NITROX_LOG_LINE(ERR, "Mbuf has more segments %d than supported",
549 : : nb_segs);
550 : 0 : return -ENOTSUP;
551 : : }
552 : :
553 [ # # ]: 0 : if (unlikely(nb_segs > sgtbl->nb_sgls)) {
554 : : union nitrox_zip_zptr *sgl;
555 : :
556 : 0 : NITROX_LOG_LINE(INFO, "Mbuf has more segs %d than allocated %d",
557 : : nb_segs, sgtbl->nb_sgls);
558 : 0 : sgl = rte_realloc_socket(sgtbl->sgl,
559 : : sizeof(*sgtbl->sgl) * nb_segs,
560 : : 8, socket_id);
561 [ # # ]: 0 : if (unlikely(!sgl)) {
562 : 0 : NITROX_LOG_LINE(ERR, "Failed to expand sglist memory");
563 : 0 : return -ENOMEM;
564 : : }
565 : :
566 : 0 : sgtbl->sgl = sgl;
567 : 0 : sgtbl->nb_sgls = nb_segs;
568 : : }
569 : :
570 : 0 : sgtbl->filled_sgls = 0;
571 : 0 : sgtbl->total_bytes = 0;
572 : 0 : sgl = sgtbl->sgl;
573 [ # # ]: 0 : if (!m)
574 : : return 0;
575 : :
576 : 0 : mlen = rte_pktmbuf_data_len(m) - off;
577 : : if (datalen <= mlen)
578 : : mlen = datalen;
579 : :
580 : : i = 0;
581 : 0 : zip_addr.u64 = rte_pktmbuf_iova_offset(m, off);
582 : 0 : sgl[i].s.addr = zip_addr.zda.addr;
583 : 0 : sgl[i].s.length = mlen;
584 : 0 : sgl[i].s.le = 0;
585 : 0 : sgtbl->total_bytes += mlen;
586 : 0 : sgtbl->addr_msb = zip_addr.zda.addr_msb;
587 : 0 : datalen -= mlen;
588 : : i++;
589 [ # # ]: 0 : for (m = m->next; m && datalen; m = m->next) {
590 [ # # ]: 0 : mlen = rte_pktmbuf_data_len(m) < datalen ?
591 : : rte_pktmbuf_data_len(m) : datalen;
592 : 0 : zip_addr.u64 = rte_pktmbuf_iova(m);
593 [ # # ]: 0 : if (unlikely(zip_addr.zda.addr_msb != sgtbl->addr_msb)) {
594 : 0 : NITROX_LOG_LINE(ERR, "zip_ptrs have different msb addr");
595 : 0 : return -ENOTSUP;
596 : : }
597 : :
598 : 0 : sgl[i].s.addr = zip_addr.zda.addr;
599 : 0 : sgl[i].s.length = mlen;
600 : 0 : sgl[i].s.le = 0;
601 : 0 : sgtbl->total_bytes += mlen;
602 : 0 : datalen -= mlen;
603 : 0 : i++;
604 : : }
605 : :
606 : 0 : sgtbl->filled_sgls = i;
607 : 0 : return 0;
608 : : }
609 : :
610 [ # # ]: 0 : static int softreq_init(struct nitrox_softreq *sr,
611 : : struct nitrox_comp_xform *xform)
612 : : {
613 : : struct rte_mempool *mp;
614 : : int err;
615 : : bool need_decomp_threshold;
616 : :
617 : : mp = rte_mempool_from_obj(sr);
618 [ # # ]: 0 : if (unlikely(mp == NULL))
619 : : return -EINVAL;
620 : :
621 : 0 : err = create_sglist_from_mbuf(&sr->src, sr->op->m_src,
622 : : sr->op->src.offset,
623 : 0 : sr->op->src.length, 0, mp->socket_id);
624 [ # # ]: 0 : if (unlikely(err))
625 : : return err;
626 : :
627 [ # # ]: 0 : need_decomp_threshold = (sr->op->op_type == RTE_COMP_OP_STATELESS &&
628 [ # # ]: 0 : xform->op == NITROX_COMP_OP_DECOMPRESS);
629 : 0 : err = create_sglist_from_mbuf(&sr->dst, sr->op->m_dst,
630 : : sr->op->dst.offset,
631 : 0 : rte_pktmbuf_pkt_len(sr->op->m_dst) - sr->op->dst.offset,
632 : : need_decomp_threshold ? 1 : 0,
633 : : mp->socket_id);
634 [ # # ]: 0 : if (unlikely(err))
635 : : return err;
636 : :
637 [ # # ]: 0 : if (need_decomp_threshold) {
638 : : struct nitrox_zip_iova_addr zip_addr;
639 : : int i;
640 : :
641 : 0 : zip_addr.u64 = rte_mempool_virt2iova(sr) +
642 : : offsetof(struct nitrox_softreq, decomp_threshold);
643 : 0 : i = sr->dst.filled_sgls;
644 : 0 : sr->dst.sgl[i].s.addr = zip_addr.zda.addr;
645 : 0 : sr->dst.sgl[i].s.length = NITROX_ZIP_MAX_ONFSIZE;
646 : 0 : sr->dst.sgl[i].s.le = 0;
647 : 0 : sr->dst.total_bytes += NITROX_ZIP_MAX_ONFSIZE;
648 : 0 : sr->dst.filled_sgls++;
649 : : }
650 : :
651 : : return 0;
652 : : }
653 : :
654 : 0 : static void nitrox_zip_instr_to_b64(struct nitrox_softreq *sr)
655 : : {
656 : : struct nitrox_zip_instr *instr = &sr->instr;
657 : : int i;
658 : :
659 [ # # # # ]: 0 : for (i = 0; instr->w0.dg && (i < instr->w4.ilen); i++)
660 [ # # ]: 0 : sr->src.sgl[i].u64 = rte_cpu_to_be_64(sr->src.sgl[i].u64);
661 : :
662 [ # # # # ]: 0 : for (i = 0; instr->w0.ds && (i < instr->w5.olen); i++)
663 [ # # ]: 0 : sr->dst.sgl[i].u64 = rte_cpu_to_be_64(sr->dst.sgl[i].u64);
664 : :
665 [ # # ]: 0 : instr->w0.u64 = rte_cpu_to_be_64(instr->w0.u64);
666 [ # # ]: 0 : instr->w1.u64 = rte_cpu_to_be_64(instr->w1.u64);
667 [ # # ]: 0 : instr->w2.u64 = rte_cpu_to_be_64(instr->w2.u64);
668 [ # # ]: 0 : instr->w3.u64 = rte_cpu_to_be_64(instr->w3.u64);
669 [ # # ]: 0 : instr->w4.u64 = rte_cpu_to_be_64(instr->w4.u64);
670 [ # # ]: 0 : instr->w5.u64 = rte_cpu_to_be_64(instr->w5.u64);
671 [ # # ]: 0 : instr->w6.u64 = rte_cpu_to_be_64(instr->w6.u64);
672 [ # # ]: 0 : instr->w7.u64 = rte_cpu_to_be_64(instr->w7.u64);
673 : 0 : }
674 : :
675 : 0 : static int process_zip_request(struct nitrox_softreq *sr)
676 : : {
677 : : struct nitrox_zip_instr *instr;
678 : : struct nitrox_comp_xform *xform;
679 : : struct nitrox_zip_iova_addr zip_addr;
680 : : uint64_t iptr_msb, optr_msb, rptr_msb, cptr_msb, hptr_msb;
681 : : int err;
682 : :
683 : 0 : xform = sr->op->private_xform;
684 [ # # ]: 0 : if (unlikely(xform == NULL)) {
685 : 0 : NITROX_LOG_LINE(ERR, "Invalid stateless comp op");
686 : 0 : return -EINVAL;
687 : : }
688 : :
689 [ # # # # : 0 : if (unlikely(sr->op->op_type == RTE_COMP_OP_STATEFUL &&
# # # # ]
690 : : xform->op == NITROX_COMP_OP_COMPRESS &&
691 : : sr->op->flush_flag == RTE_COMP_FLUSH_FINAL &&
692 : : sr->op->src.length == 0))
693 : 0 : return handle_zero_length_compression(sr, xform);
694 : :
695 [ # # # # : 0 : if (unlikely(sr->op->op_type == RTE_COMP_OP_STATELESS &&
# # # # ]
696 : : xform->op == NITROX_COMP_OP_COMPRESS &&
697 : : sr->op->flush_flag != RTE_COMP_FLUSH_FULL &&
698 : : sr->op->flush_flag != RTE_COMP_FLUSH_FINAL)) {
699 : 0 : NITROX_LOG_LINE(ERR, "Invalid flush flag %d in stateless op",
700 : : sr->op->flush_flag);
701 : 0 : return -EINVAL;
702 : : }
703 : :
704 : 0 : err = softreq_init(sr, xform);
705 [ # # ]: 0 : if (unlikely(err))
706 : : return err;
707 : :
708 [ # # ]: 0 : instr = &sr->instr;
709 : : memset(instr, 0, sizeof(*instr));
710 : : /* word 0 */
711 : 0 : instr->w0.tol = sr->dst.total_bytes;
712 : 0 : instr->w0.exn = xform->exn;
713 : 0 : instr->w0.exbits = xform->exbits;
714 : : instr->w0.ca = 0;
715 [ # # ]: 0 : if (xform->op == NITROX_COMP_OP_DECOMPRESS ||
716 [ # # # # ]: 0 : sr->op->flush_flag == RTE_COMP_FLUSH_SYNC ||
717 : : sr->op->flush_flag == RTE_COMP_FLUSH_FULL)
718 : 0 : instr->w0.sf = 1;
719 : : else
720 : : instr->w0.sf = 0;
721 : :
722 : 0 : instr->w0.ss = xform->level;
723 : 0 : instr->w0.cc = xform->algo;
724 [ # # ]: 0 : if (sr->op->flush_flag == RTE_COMP_FLUSH_FINAL)
725 : 0 : instr->w0.ef = 1;
726 : : else
727 : : instr->w0.ef = 0;
728 : :
729 : 0 : instr->w0.bf = xform->bf;
730 : 0 : instr->w0.co = xform->op;
731 [ # # ]: 0 : if (sr->dst.filled_sgls > 1)
732 : 0 : instr->w0.ds = 1;
733 : : else
734 : : instr->w0.ds = 0;
735 : :
736 [ # # ]: 0 : if (sr->src.filled_sgls > 1)
737 : 0 : instr->w0.dg = 1;
738 : : else
739 : : instr->w0.dg = 0;
740 : :
741 : : instr->w0.hg = 0;
742 : :
743 : : /* word 1 */
744 : 0 : instr->w1.hl = xform->hlen;
745 [ # # # # ]: 0 : if (sr->op->op_type == RTE_COMP_OP_STATEFUL && !xform->bf)
746 : 0 : instr->w1.adlercrc32 = xform->chksum;
747 [ # # ]: 0 : else if (sr->op->op_type == RTE_COMP_OP_STATELESS &&
748 [ # # ]: 0 : sr->op->input_chksum != 0)
749 : 0 : instr->w1.adlercrc32 = sr->op->input_chksum;
750 [ # # ]: 0 : else if (xform->chksum_type == NITROX_CHKSUM_TYPE_ADLER32)
751 : 0 : instr->w1.adlercrc32 = 1;
752 : : else if (xform->chksum_type == NITROX_CHKSUM_TYPE_CRC32)
753 : : instr->w1.adlercrc32 = 0;
754 : :
755 : : /* word 2 */
756 [ # # ]: 0 : if (xform->context)
757 : 0 : zip_addr.u64 = rte_malloc_virt2iova(xform->context);
758 : : else
759 : 0 : zip_addr.u64 = 0;
760 : :
761 : 0 : instr->w2.cptr = zip_addr.zda.addr;
762 : 0 : cptr_msb = zip_addr.zda.addr_msb;
763 : :
764 : : /* word 3 */
765 : 0 : instr->w3.hlen = xform->hlen;
766 [ # # ]: 0 : if (xform->history_window)
767 : 0 : zip_addr.u64 = rte_malloc_virt2iova(xform->history_window);
768 : : else
769 : 0 : zip_addr.u64 = 0;
770 : :
771 : 0 : instr->w3.hptr = zip_addr.zda.addr;
772 : 0 : hptr_msb = zip_addr.zda.addr_msb;
773 : :
774 : : /* word 4 */
775 [ # # ]: 0 : if (sr->src.filled_sgls == 1) {
776 : 0 : instr->w4.ilen = sr->src.sgl[0].s.length;
777 : 0 : instr->w4.iptr = sr->src.sgl[0].s.addr;
778 : 0 : iptr_msb = sr->src.addr_msb;
779 : : } else {
780 : 0 : zip_addr.u64 = rte_malloc_virt2iova(sr->src.sgl);
781 : 0 : instr->w4.ilen = sr->src.filled_sgls;
782 : 0 : instr->w4.iptr = zip_addr.zda.addr;
783 : 0 : iptr_msb = zip_addr.zda.addr_msb;
784 : : }
785 : :
786 : : /* word 5 */
787 [ # # ]: 0 : if (sr->dst.filled_sgls == 1) {
788 : 0 : instr->w5.olen = sr->dst.sgl[0].s.length;
789 : 0 : instr->w5.optr = sr->dst.sgl[0].s.addr;
790 : 0 : optr_msb = sr->dst.addr_msb;
791 : : } else {
792 : 0 : zip_addr.u64 = rte_malloc_virt2iova(sr->dst.sgl);
793 : 0 : instr->w5.olen = sr->dst.filled_sgls;
794 : 0 : instr->w5.optr = zip_addr.zda.addr;
795 : 0 : optr_msb = zip_addr.zda.addr_msb;
796 : : }
797 : :
798 : : /* word 6 */
799 [ # # ]: 0 : memset(&sr->zip_res, 0, sizeof(sr->zip_res));
800 : 0 : zip_addr.u64 = rte_mempool_virt2iova(sr) +
801 : : offsetof(struct nitrox_softreq, zip_res);
802 : 0 : instr->w6.rptr = zip_addr.zda.addr;
803 : 0 : rptr_msb = zip_addr.zda.addr_msb;
804 : :
805 [ # # # # : 0 : if (unlikely(iptr_msb != optr_msb || iptr_msb != rptr_msb ||
# # # # #
# ]
806 : : (xform->history_window && (iptr_msb != hptr_msb)) ||
807 : : (xform->context && (iptr_msb != cptr_msb)))) {
808 : 0 : NITROX_LOG_LINE(ERR, "addr_msb is not same for all addresses");
809 : 0 : return -ENOTSUP;
810 : : }
811 : :
812 : : /* word 7 */
813 : 0 : instr->w7.addr_msb = iptr_msb;
814 : 0 : instr->w7.grp = 0;
815 : :
816 : : nitrox_dump_zip_instr(instr, NULL, sr->src.sgl, sr->dst.sgl);
817 : : nitrox_dump_databuf("IN", sr->op->m_src, sr->op->src.offset,
818 : : sr->op->src.length);
819 : 0 : nitrox_zip_instr_to_b64(sr);
820 : 0 : return 0;
821 : : }
822 : :
823 : : int
824 : 0 : nitrox_process_comp_req(struct rte_comp_op *op, struct nitrox_softreq *sr)
825 : : {
826 : : int err;
827 : :
828 : 0 : sr->op = op;
829 : 0 : sr->op->status = RTE_COMP_OP_STATUS_NOT_PROCESSED;
830 : 0 : err = process_zip_request(sr);
831 [ # # ]: 0 : if (unlikely(err))
832 : 0 : goto err_exit;
833 : :
834 : 0 : sr->timeout = rte_get_timer_cycles() + CMD_TIMEOUT * rte_get_timer_hz();
835 : 0 : return 0;
836 : : err_exit:
837 [ # # ]: 0 : if (err == -ENOMEM)
838 : 0 : sr->op->status = RTE_COMP_OP_STATUS_ERROR;
839 : : else
840 : 0 : sr->op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
841 : :
842 : : return err;
843 : : }
844 : :
845 : 0 : static struct nitrox_zip_result zip_result_to_cpu64(struct nitrox_zip_result *r)
846 : : {
847 : : struct nitrox_zip_result out_res;
848 : :
849 [ # # ]: 0 : out_res.w2.u64 = rte_be_to_cpu_64(r->w2.u64);
850 [ # # ]: 0 : out_res.w1.u64 = rte_be_to_cpu_64(r->w1.u64);
851 [ # # ]: 0 : out_res.w0.u64 = rte_be_to_cpu_64(r->w0.u64);
852 : 0 : return out_res;
853 : : }
854 : :
855 : 0 : static int post_process_zip_stateless(struct nitrox_softreq *sr,
856 : : struct nitrox_comp_xform *xform,
857 : : struct nitrox_zip_result *zip_res)
858 : : {
859 : : int output_unused_bytes;
860 : :
861 [ # # ]: 0 : if (unlikely(zip_res->w2.compcode != NITROX_CC_SUCCESS)) {
862 : 0 : struct rte_comp_op *op = sr->op;
863 : :
864 : 0 : NITROX_LOG_LINE(ERR, "Dequeue error 0x%x",
865 : : zip_res->w2.compcode);
866 [ # # ]: 0 : if (zip_res->w2.compcode == NITROX_CC_STOP ||
867 : : zip_res->w2.compcode == NITROX_CC_DTRUNC)
868 : 0 : op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
869 : : else
870 : 0 : op->status = RTE_COMP_OP_STATUS_ERROR;
871 : :
872 : 0 : op->consumed = 0;
873 : 0 : op->produced = 0;
874 : 0 : return -EFAULT;
875 : : }
876 : :
877 : 0 : output_unused_bytes = sr->dst.total_bytes - zip_res->w1.tbyteswritten;
878 [ # # # # ]: 0 : if (unlikely(xform->op == NITROX_COMP_OP_DECOMPRESS &&
879 : : output_unused_bytes < NITROX_ZIP_MAX_ONFSIZE)) {
880 : 0 : NITROX_LOG_LINE(ERR, "TOL %d, Total bytes written %d",
881 : : sr->dst.total_bytes, zip_res->w1.tbyteswritten);
882 : 0 : sr->op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
883 : 0 : sr->op->consumed = 0;
884 : 0 : sr->op->produced = sr->dst.total_bytes - NITROX_ZIP_MAX_ONFSIZE;
885 : 0 : return -EIO;
886 : : }
887 : :
888 [ # # ]: 0 : if (xform->chksum_type == NITROX_CHKSUM_TYPE_CRC32)
889 : 0 : sr->op->output_chksum = zip_res->w0.crc32;
890 [ # # ]: 0 : else if (xform->chksum_type == NITROX_CHKSUM_TYPE_ADLER32)
891 : 0 : sr->op->output_chksum = zip_res->w0.adler32;
892 : :
893 : 0 : sr->op->consumed = RTE_MIN(sr->op->src.length,
894 : : (uint32_t)zip_res->w1.tbytesread);
895 : 0 : sr->op->produced = zip_res->w1.tbyteswritten;
896 : 0 : sr->op->status = RTE_COMP_OP_STATUS_SUCCESS;
897 : 0 : return 0;
898 : : }
899 : :
900 : 0 : static int update_history(struct rte_mbuf *mbuf, uint32_t off, uint16_t datalen,
901 : : uint8_t *dst)
902 : : {
903 : : struct rte_mbuf *m;
904 : : uint32_t mlen;
905 : : uint16_t copied = 0;
906 : :
907 [ # # # # ]: 0 : for (m = mbuf; m && off > rte_pktmbuf_data_len(m); m = m->next)
908 : 0 : off -= rte_pktmbuf_data_len(m);
909 : :
910 [ # # ]: 0 : if (unlikely(!m)) {
911 : 0 : NITROX_LOG_LINE(ERR, "Failed to update history. Invalid mbuf");
912 : 0 : return -EINVAL;
913 : : }
914 : :
915 : 0 : mlen = rte_pktmbuf_data_len(m) - off;
916 : 0 : if (datalen <= mlen)
917 : : mlen = datalen;
918 : :
919 : 0 : memcpy(&dst[copied], rte_pktmbuf_mtod_offset(m, char *, off), mlen);
920 : 0 : copied += mlen;
921 : 0 : datalen -= mlen;
922 [ # # ]: 0 : for (m = m->next; m && datalen; m = m->next) {
923 : 0 : mlen = rte_pktmbuf_data_len(m) < datalen ?
924 : 0 : rte_pktmbuf_data_len(m) : datalen;
925 : 0 : memcpy(&dst[copied], rte_pktmbuf_mtod(m, char *), mlen);
926 : 0 : copied += mlen;
927 : 0 : datalen -= mlen;
928 : : }
929 : :
930 [ # # ]: 0 : if (unlikely(datalen != 0)) {
931 : 0 : NITROX_LOG_LINE(ERR, "Failed to update history. Invalid datalen");
932 : 0 : return -EINVAL;
933 : : }
934 : :
935 : : return 0;
936 : : }
937 : :
938 : : static void reset_nitrox_xform(struct nitrox_comp_xform *xform)
939 : : {
940 : 0 : xform->hlen = 0;
941 : 0 : xform->exn = 0;
942 : 0 : xform->exbits = 0;
943 : 0 : xform->bf = true;
944 : 0 : }
945 : :
946 : 0 : static int post_process_zip_stateful(struct nitrox_softreq *sr,
947 : : struct nitrox_comp_xform *xform,
948 : : struct nitrox_zip_result *zip_res)
949 : : {
950 : : uint32_t bytesread = 0;
951 : : uint32_t chksum = 0;
952 : :
953 [ # # ]: 0 : if (unlikely(zip_res->w2.compcode == NITROX_CC_DTRUNC)) {
954 : 0 : sr->op->consumed = 0;
955 : 0 : sr->op->produced = 0;
956 : 0 : xform->hlen = 0;
957 : 0 : sr->op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE;
958 : 0 : NITROX_LOG_LINE(ERR, "Dequeue compress DTRUNC error");
959 : 0 : return 0;
960 [ # # ]: 0 : } else if (unlikely(zip_res->w2.compcode == NITROX_CC_STOP)) {
961 : 0 : sr->op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE;
962 : 0 : NITROX_LOG_LINE(NOTICE, "Dequeue decompress dynamic STOP");
963 [ # # ]: 0 : } else if (zip_res->w2.compcode == NITROX_CC_SUCCESS) {
964 : 0 : sr->op->status = RTE_COMP_OP_STATUS_SUCCESS;
965 : : } else {
966 : 0 : xform->hlen = 0;
967 : 0 : xform->exn = 0;
968 : 0 : xform->exbits = 0;
969 : 0 : xform->bf = true;
970 : 0 : sr->op->status = RTE_COMP_OP_STATUS_ERROR;
971 : 0 : NITROX_LOG_LINE(ERR, "Dequeue error 0x%x",
972 : : zip_res->w2.compcode);
973 : 0 : return -EFAULT;
974 : : }
975 : :
976 [ # # ]: 0 : if (xform->op == NITROX_COMP_OP_COMPRESS) {
977 [ # # ]: 0 : if (zip_res->w1.tbytesread < xform->hlen) {
978 : 0 : NITROX_LOG_LINE(ERR, "Invalid bytesread");
979 : : reset_nitrox_xform(xform);
980 : 0 : sr->op->status = RTE_COMP_OP_STATUS_ERROR;
981 : 0 : return -EFAULT;
982 : : }
983 : :
984 : 0 : bytesread = zip_res->w1.tbytesread - xform->hlen;
985 : : } else {
986 : 0 : bytesread = RTE_MIN(sr->op->src.length,
987 : : (uint32_t)zip_res->w1.tbytesread);
988 : : }
989 : :
990 [ # # ]: 0 : if ((xform->op == NITROX_COMP_OP_COMPRESS &&
991 [ # # ]: 0 : (sr->op->flush_flag == RTE_COMP_FLUSH_NONE ||
992 [ # # ]: 0 : sr->op->flush_flag == RTE_COMP_FLUSH_SYNC)) ||
993 [ # # ]: 0 : (xform->op == NITROX_COMP_OP_DECOMPRESS && !zip_res->w2.ef)) {
994 : : struct rte_mbuf *mbuf;
995 : : uint32_t pktlen, m_off;
996 : : int err;
997 : :
998 [ # # ]: 0 : if (xform->op == NITROX_COMP_OP_COMPRESS) {
999 : 0 : mbuf = sr->op->m_src;
1000 : : pktlen = bytesread;
1001 : 0 : m_off = sr->op->src.offset;
1002 : : } else {
1003 : 0 : mbuf = sr->op->m_dst;
1004 : 0 : pktlen = zip_res->w1.tbyteswritten;
1005 : 0 : m_off = sr->op->dst.offset;
1006 : : }
1007 : :
1008 [ # # ]: 0 : if (pktlen >= xform->window_size) {
1009 : 0 : m_off += pktlen - xform->window_size;
1010 : 0 : err = update_history(mbuf, m_off, xform->window_size,
1011 : : xform->history_window);
1012 : 0 : xform->hlen = xform->window_size;
1013 [ # # ]: 0 : } else if ((xform->hlen + pktlen) <= xform->window_size) {
1014 : 0 : err = update_history(mbuf, m_off, pktlen,
1015 : 0 : &xform->history_window[xform->hlen]);
1016 : 0 : xform->hlen += pktlen;
1017 : : } else {
1018 : : uint16_t shift_off, shift_len;
1019 : :
1020 : 0 : shift_off = pktlen + xform->hlen - xform->window_size;
1021 : 0 : shift_len = xform->hlen - shift_off;
1022 : 0 : memmove(xform->history_window,
1023 : 0 : &xform->history_window[shift_off],
1024 : : shift_len);
1025 : 0 : err = update_history(mbuf, m_off, pktlen,
1026 : 0 : &xform->history_window[shift_len]);
1027 : 0 : xform->hlen = xform->window_size;
1028 : :
1029 : : }
1030 : :
1031 [ # # ]: 0 : if (unlikely(err)) {
1032 : 0 : sr->op->status = RTE_COMP_OP_STATUS_ERROR;
1033 : 0 : return err;
1034 : : }
1035 : :
1036 [ # # ]: 0 : if (xform->op == NITROX_COMP_OP_COMPRESS) {
1037 : 0 : xform->exn = zip_res->w2.exn;
1038 : 0 : xform->exbits = zip_res->w2.exbits;
1039 : : }
1040 : :
1041 : 0 : xform->bf = false;
1042 : : } else {
1043 : : reset_nitrox_xform(xform);
1044 : : }
1045 : :
1046 [ # # ]: 0 : if (xform->chksum_type == NITROX_CHKSUM_TYPE_CRC32)
1047 : 0 : chksum = zip_res->w0.crc32;
1048 [ # # ]: 0 : else if (xform->chksum_type == NITROX_CHKSUM_TYPE_ADLER32)
1049 : 0 : chksum = zip_res->w0.adler32;
1050 : :
1051 [ # # ]: 0 : if (xform->bf)
1052 : 0 : sr->op->output_chksum = chksum;
1053 : : else
1054 : 0 : xform->chksum = chksum;
1055 : :
1056 : 0 : sr->op->consumed = bytesread;
1057 : 0 : sr->op->produced = zip_res->w1.tbyteswritten;
1058 : 0 : return 0;
1059 : : }
1060 : :
1061 : : int
1062 : 0 : nitrox_check_comp_req(struct nitrox_softreq *sr, struct rte_comp_op **op)
1063 : : {
1064 : : struct nitrox_zip_result zip_res;
1065 : : struct nitrox_comp_xform *xform;
1066 : : int err = 0;
1067 : :
1068 : 0 : zip_res = zip_result_to_cpu64(&sr->zip_res);
1069 [ # # ]: 0 : if (zip_res.w2.compcode == NITROX_CC_NOTDONE) {
1070 [ # # ]: 0 : if (rte_get_timer_cycles() >= sr->timeout) {
1071 : 0 : NITROX_LOG_LINE(ERR, "Op timedout");
1072 : 0 : sr->op->status = RTE_COMP_OP_STATUS_ERROR;
1073 : : err = -ETIMEDOUT;
1074 : 0 : goto exit;
1075 : : } else {
1076 : : return -EAGAIN;
1077 : : }
1078 : : }
1079 : :
1080 : 0 : xform = sr->op->private_xform;
1081 [ # # ]: 0 : if (sr->op->op_type == RTE_COMP_OP_STATELESS)
1082 : 0 : err = post_process_zip_stateless(sr, xform, &zip_res);
1083 : : else
1084 : 0 : err = post_process_zip_stateful(sr, xform, &zip_res);
1085 : :
1086 [ # # ]: 0 : if (sr->op->status == RTE_COMP_OP_STATUS_SUCCESS &&
1087 [ # # ]: 0 : xform->op == NITROX_COMP_OP_COMPRESS &&
1088 [ # # # # ]: 0 : sr->op->flush_flag == RTE_COMP_FLUSH_FINAL &&
1089 : : zip_res.w2.exn) {
1090 : 0 : uint32_t datalen = zip_res.w1.tbyteswritten;
1091 : 0 : uint32_t off = sr->op->dst.offset;
1092 : 0 : struct rte_mbuf *m = sr->op->m_dst;
1093 : : uint32_t mlen;
1094 : : uint8_t *last_byte;
1095 : :
1096 [ # # # # ]: 0 : for (; m && off > rte_pktmbuf_data_len(m); m = m->next)
1097 : 0 : off -= rte_pktmbuf_data_len(m);
1098 : :
1099 [ # # ]: 0 : if (unlikely(m == NULL)) {
1100 : : err = -EINVAL;
1101 : 0 : goto exit;
1102 : : }
1103 : :
1104 : 0 : mlen = rte_pktmbuf_data_len(m) - off;
1105 [ # # ]: 0 : for (; m && (datalen > mlen); m = m->next)
1106 : 0 : datalen -= mlen;
1107 : :
1108 [ # # ]: 0 : if (unlikely(m == NULL)) {
1109 : : err = -EINVAL;
1110 : 0 : goto exit;
1111 : : }
1112 : :
1113 : 0 : last_byte = rte_pktmbuf_mtod_offset(m, uint8_t *, datalen - 1);
1114 : 0 : *last_byte = zip_res.w2.exbits & 0xFF;
1115 : : }
1116 : :
1117 : 0 : exit:
1118 : 0 : *op = sr->op;
1119 : : nitrox_dump_zip_result(&sr->instr, &zip_res);
1120 : : nitrox_dump_databuf("OUT after", sr->op->m_dst, sr->op->dst.offset,
1121 : : sr->op->produced);
1122 : 0 : return err;
1123 : : }
1124 : :
1125 : : void *
1126 : 0 : nitrox_comp_instr_addr(struct nitrox_softreq *sr)
1127 : : {
1128 : 0 : return &sr->instr;
1129 : : }
1130 : :
1131 : 0 : static void req_pool_obj_free(struct rte_mempool *mp, void *opaque, void *obj,
1132 : : unsigned int obj_idx)
1133 : : {
1134 : : struct nitrox_softreq *sr;
1135 : :
1136 : : RTE_SET_USED(mp);
1137 : : RTE_SET_USED(opaque);
1138 : : RTE_SET_USED(obj_idx);
1139 : : sr = obj;
1140 : 0 : rte_free(sr->src.sgl);
1141 : 0 : sr->src.sgl = NULL;
1142 : 0 : rte_free(sr->dst.sgl);
1143 : 0 : sr->dst.sgl = NULL;
1144 : 0 : }
1145 : :
1146 : : void
1147 : 0 : nitrox_comp_req_pool_free(struct rte_mempool *mp)
1148 : : {
1149 : 0 : rte_mempool_obj_iter(mp, req_pool_obj_free, NULL);
1150 : 0 : rte_mempool_free(mp);
1151 : 0 : }
1152 : :
1153 : 0 : static void req_pool_obj_init(struct rte_mempool *mp, void *arg, void *obj,
1154 : : unsigned int obj_idx)
1155 : : {
1156 : : struct nitrox_softreq *sr;
1157 : : int *err = arg;
1158 : :
1159 : : RTE_SET_USED(mp);
1160 : : RTE_SET_USED(obj_idx);
1161 : : sr = obj;
1162 : 0 : sr->src.sgl = rte_zmalloc_socket(NULL,
1163 : : sizeof(*sr->src.sgl) * NITROX_ZIP_SGL_COUNT,
1164 : : 8, mp->socket_id);
1165 : 0 : sr->dst.sgl = rte_zmalloc_socket(NULL,
1166 : : sizeof(*sr->dst.sgl) * NITROX_ZIP_SGL_COUNT,
1167 : : 8, mp->socket_id);
1168 [ # # # # ]: 0 : if (sr->src.sgl == NULL || sr->dst.sgl == NULL) {
1169 : 0 : NITROX_LOG_LINE(ERR, "Failed to allocate zip_sgl memory");
1170 : 0 : *err = -ENOMEM;
1171 : : }
1172 : :
1173 : 0 : sr->src.nb_sgls = NITROX_ZIP_SGL_COUNT;
1174 : 0 : sr->src.filled_sgls = 0;
1175 : 0 : sr->dst.nb_sgls = NITROX_ZIP_SGL_COUNT;
1176 : 0 : sr->dst.filled_sgls = 0;
1177 : 0 : }
1178 : :
1179 : : struct rte_mempool *
1180 : 0 : nitrox_comp_req_pool_create(struct rte_compressdev *dev, uint32_t nobjs,
1181 : : uint16_t qp_id, int socket_id)
1182 : : {
1183 : : char softreq_pool_name[RTE_RING_NAMESIZE];
1184 : : struct rte_mempool *mp;
1185 : 0 : int err = 0;
1186 : :
1187 : 0 : snprintf(softreq_pool_name, RTE_RING_NAMESIZE, "%s_sr_%d",
1188 : 0 : dev->data->name, qp_id);
1189 : 0 : mp = rte_mempool_create(softreq_pool_name,
1190 : 0 : RTE_ALIGN_MUL_CEIL(nobjs, 64),
1191 : : sizeof(struct nitrox_softreq),
1192 : : 64, 0, NULL, NULL, req_pool_obj_init, &err,
1193 : : socket_id, 0);
1194 [ # # ]: 0 : if (unlikely(!mp))
1195 : 0 : NITROX_LOG_LINE(ERR, "Failed to create req pool, qid %d, err %d",
1196 : : qp_id, rte_errno);
1197 : :
1198 [ # # ]: 0 : if (unlikely(err)) {
1199 : 0 : nitrox_comp_req_pool_free(mp);
1200 : 0 : return NULL;
1201 : : }
1202 : :
1203 : : return mp;
1204 : : }
|