13
13
#include "qat_compression.h"
14
14
#include "qat_algs_send.h"
15
15
16
+ #define QAT_RFC_1950_HDR_SIZE 2
17
+ #define QAT_RFC_1950_FOOTER_SIZE 4
18
+ #define QAT_RFC_1950_CM_DEFLATE 8
19
+ #define QAT_RFC_1950_CM_DEFLATE_CINFO_32K 7
20
+ #define QAT_RFC_1950_CM_MASK 0x0f
21
+ #define QAT_RFC_1950_CM_OFFSET 4
22
+ #define QAT_RFC_1950_DICT_MASK 0x20
23
+ #define QAT_RFC_1950_COMP_HDR 0x785e
24
+
16
25
static DEFINE_MUTEX (algs_lock );
17
26
static unsigned int active_devs ;
18
27
@@ -21,9 +30,12 @@ enum direction {
21
30
COMPRESSION = 1 ,
22
31
};
23
32
33
+ struct qat_compression_req ;
34
+
24
35
struct qat_compression_ctx {
25
36
u8 comp_ctx [QAT_COMP_CTX_SIZE ];
26
37
struct qat_compression_instance * inst ;
38
+ int (* qat_comp_callback )(struct qat_compression_req * qat_req , void * resp );
27
39
};
28
40
29
41
struct qat_dst {
@@ -97,6 +109,69 @@ static void qat_comp_resubmit(struct work_struct *work)
97
109
areq -> base .complete (& areq -> base , ret );
98
110
}
99
111
112
+ static int parse_zlib_header (u16 zlib_h )
113
+ {
114
+ int ret = - EINVAL ;
115
+ __be16 header ;
116
+ u8 * header_p ;
117
+ u8 cmf , flg ;
118
+
119
+ header = cpu_to_be16 (zlib_h );
120
+ header_p = (u8 * )& header ;
121
+
122
+ flg = header_p [0 ];
123
+ cmf = header_p [1 ];
124
+
125
+ if (cmf >> QAT_RFC_1950_CM_OFFSET > QAT_RFC_1950_CM_DEFLATE_CINFO_32K )
126
+ return ret ;
127
+
128
+ if ((cmf & QAT_RFC_1950_CM_MASK ) != QAT_RFC_1950_CM_DEFLATE )
129
+ return ret ;
130
+
131
+ if (flg & QAT_RFC_1950_DICT_MASK )
132
+ return ret ;
133
+
134
+ return 0 ;
135
+ }
136
+
137
+ static int qat_comp_rfc1950_callback (struct qat_compression_req * qat_req ,
138
+ void * resp )
139
+ {
140
+ struct acomp_req * areq = qat_req -> acompress_req ;
141
+ enum direction dir = qat_req -> dir ;
142
+ __be32 qat_produced_adler ;
143
+
144
+ qat_produced_adler = cpu_to_be32 (qat_comp_get_produced_adler32 (resp ));
145
+
146
+ if (dir == COMPRESSION ) {
147
+ __be16 zlib_header ;
148
+
149
+ zlib_header = cpu_to_be16 (QAT_RFC_1950_COMP_HDR );
150
+ scatterwalk_map_and_copy (& zlib_header , areq -> dst , 0 , QAT_RFC_1950_HDR_SIZE , 1 );
151
+ areq -> dlen += QAT_RFC_1950_HDR_SIZE ;
152
+
153
+ scatterwalk_map_and_copy (& qat_produced_adler , areq -> dst , areq -> dlen ,
154
+ QAT_RFC_1950_FOOTER_SIZE , 1 );
155
+ areq -> dlen += QAT_RFC_1950_FOOTER_SIZE ;
156
+ } else {
157
+ __be32 decomp_adler ;
158
+ int footer_offset ;
159
+ int consumed ;
160
+
161
+ consumed = qat_comp_get_consumed_ctr (resp );
162
+ footer_offset = consumed + QAT_RFC_1950_HDR_SIZE ;
163
+ if (footer_offset + QAT_RFC_1950_FOOTER_SIZE > areq -> slen )
164
+ return - EBADMSG ;
165
+
166
+ scatterwalk_map_and_copy (& decomp_adler , areq -> src , footer_offset ,
167
+ QAT_RFC_1950_FOOTER_SIZE , 0 );
168
+
169
+ if (qat_produced_adler != decomp_adler )
170
+ return - EBADMSG ;
171
+ }
172
+ return 0 ;
173
+ }
174
+
100
175
static void qat_comp_generic_callback (struct qat_compression_req * qat_req ,
101
176
void * resp )
102
177
{
@@ -167,6 +242,9 @@ static void qat_comp_generic_callback(struct qat_compression_req *qat_req,
167
242
res = 0 ;
168
243
areq -> dlen = produced ;
169
244
245
+ if (ctx -> qat_comp_callback )
246
+ res = ctx -> qat_comp_callback (qat_req , resp );
247
+
170
248
end :
171
249
qat_bl_free_bufl (accel_dev , & qat_req -> buf );
172
250
areq -> base .complete (& areq -> base , res );
@@ -215,26 +293,38 @@ static void qat_comp_alg_exit_tfm(struct crypto_acomp *acomp_tfm)
215
293
memset (ctx , 0 , sizeof (* ctx ));
216
294
}
217
295
218
- static int qat_comp_alg_compress_decompress (struct acomp_req * areq ,
219
- enum direction dir )
296
+ static int qat_comp_alg_rfc1950_init_tfm (struct crypto_acomp * acomp_tfm )
297
+ {
298
+ struct crypto_tfm * tfm = crypto_acomp_tfm (acomp_tfm );
299
+ struct qat_compression_ctx * ctx = crypto_tfm_ctx (tfm );
300
+ int ret ;
301
+
302
+ ret = qat_comp_alg_init_tfm (acomp_tfm );
303
+ ctx -> qat_comp_callback = & qat_comp_rfc1950_callback ;
304
+
305
+ return ret ;
306
+ }
307
+
308
+ static int qat_comp_alg_compress_decompress (struct acomp_req * areq , enum direction dir ,
309
+ unsigned int shdr , unsigned int sftr ,
310
+ unsigned int dhdr , unsigned int dftr )
220
311
{
221
312
struct qat_compression_req * qat_req = acomp_request_ctx (areq );
222
313
struct crypto_acomp * acomp_tfm = crypto_acomp_reqtfm (areq );
223
314
struct crypto_tfm * tfm = crypto_acomp_tfm (acomp_tfm );
224
315
struct qat_compression_ctx * ctx = crypto_tfm_ctx (tfm );
225
316
struct qat_compression_instance * inst = ctx -> inst ;
226
- struct qat_sgl_to_bufl_params * p_params = NULL ;
227
317
gfp_t f = qat_algs_alloc_flags (& areq -> base );
228
- struct qat_sgl_to_bufl_params params ;
229
- unsigned int slen = areq -> slen ;
230
- unsigned int dlen = areq -> dlen ;
318
+ struct qat_sgl_to_bufl_params params = { 0 } ;
319
+ int slen = areq -> slen - shdr - sftr ;
320
+ int dlen = areq -> dlen - dhdr - dftr ;
231
321
dma_addr_t sfbuf , dfbuf ;
232
322
u8 * req = qat_req -> req ;
233
323
size_t ovf_buff_sz ;
234
324
int ret ;
235
325
236
- params .sskip = 0 ;
237
- params .dskip = 0 ;
326
+ params .sskip = shdr ;
327
+ params .dskip = dhdr ;
238
328
239
329
if (!areq -> src || !slen )
240
330
return - EINVAL ;
@@ -257,6 +347,7 @@ static int qat_comp_alg_compress_decompress(struct acomp_req *areq,
257
347
if (!areq -> dst )
258
348
return - ENOMEM ;
259
349
350
+ dlen -= dhdr + dftr ;
260
351
areq -> dlen = dlen ;
261
352
qat_req -> dst .resubmitted = false;
262
353
}
@@ -265,11 +356,10 @@ static int qat_comp_alg_compress_decompress(struct acomp_req *areq,
265
356
params .extra_dst_buff = inst -> dc_data -> ovf_buff_p ;
266
357
ovf_buff_sz = inst -> dc_data -> ovf_buff_sz ;
267
358
params .sz_extra_dst_buff = ovf_buff_sz ;
268
- p_params = & params ;
269
359
}
270
360
271
361
ret = qat_bl_sgl_to_bufl (ctx -> inst -> accel_dev , areq -> src , areq -> dst ,
272
- & qat_req -> buf , p_params , f );
362
+ & qat_req -> buf , & params , f );
273
363
if (unlikely (ret ))
274
364
return ret ;
275
365
@@ -302,12 +392,49 @@ static int qat_comp_alg_compress_decompress(struct acomp_req *areq,
302
392
303
393
static int qat_comp_alg_compress (struct acomp_req * req )
304
394
{
305
- return qat_comp_alg_compress_decompress (req , COMPRESSION );
395
+ return qat_comp_alg_compress_decompress (req , COMPRESSION , 0 , 0 , 0 , 0 );
306
396
}
307
397
308
398
static int qat_comp_alg_decompress (struct acomp_req * req )
309
399
{
310
- return qat_comp_alg_compress_decompress (req , DECOMPRESSION );
400
+ return qat_comp_alg_compress_decompress (req , DECOMPRESSION , 0 , 0 , 0 , 0 );
401
+ }
402
+
403
+ static int qat_comp_alg_rfc1950_compress (struct acomp_req * req )
404
+ {
405
+ if (!req -> dst && req -> dlen != 0 )
406
+ return - EINVAL ;
407
+
408
+ if (req -> dst && req -> dlen <= QAT_RFC_1950_HDR_SIZE + QAT_RFC_1950_FOOTER_SIZE )
409
+ return - EINVAL ;
410
+
411
+ return qat_comp_alg_compress_decompress (req , COMPRESSION , 0 , 0 ,
412
+ QAT_RFC_1950_HDR_SIZE ,
413
+ QAT_RFC_1950_FOOTER_SIZE );
414
+ }
415
+
416
+ static int qat_comp_alg_rfc1950_decompress (struct acomp_req * req )
417
+ {
418
+ struct crypto_acomp * acomp_tfm = crypto_acomp_reqtfm (req );
419
+ struct crypto_tfm * tfm = crypto_acomp_tfm (acomp_tfm );
420
+ struct qat_compression_ctx * ctx = crypto_tfm_ctx (tfm );
421
+ struct adf_accel_dev * accel_dev = ctx -> inst -> accel_dev ;
422
+ u16 zlib_header ;
423
+ int ret ;
424
+
425
+ if (req -> slen <= QAT_RFC_1950_HDR_SIZE + QAT_RFC_1950_FOOTER_SIZE )
426
+ return - EBADMSG ;
427
+
428
+ scatterwalk_map_and_copy (& zlib_header , req -> src , 0 , QAT_RFC_1950_HDR_SIZE , 0 );
429
+
430
+ ret = parse_zlib_header (zlib_header );
431
+ if (ret ) {
432
+ dev_dbg (& GET_DEV (accel_dev ), "Error parsing zlib header\n" );
433
+ return ret ;
434
+ }
435
+
436
+ return qat_comp_alg_compress_decompress (req , DECOMPRESSION , QAT_RFC_1950_HDR_SIZE ,
437
+ QAT_RFC_1950_FOOTER_SIZE , 0 , 0 );
311
438
}
312
439
313
440
static struct acomp_alg qat_acomp [] = { {
@@ -325,6 +452,21 @@ static struct acomp_alg qat_acomp[] = { {
325
452
.decompress = qat_comp_alg_decompress ,
326
453
.dst_free = sgl_free ,
327
454
.reqsize = sizeof (struct qat_compression_req ),
455
+ }, {
456
+ .base = {
457
+ .cra_name = "zlib-deflate" ,
458
+ .cra_driver_name = "qat_zlib_deflate" ,
459
+ .cra_priority = 4001 ,
460
+ .cra_flags = CRYPTO_ALG_ASYNC ,
461
+ .cra_ctxsize = sizeof (struct qat_compression_ctx ),
462
+ .cra_module = THIS_MODULE ,
463
+ },
464
+ .init = qat_comp_alg_rfc1950_init_tfm ,
465
+ .exit = qat_comp_alg_exit_tfm ,
466
+ .compress = qat_comp_alg_rfc1950_compress ,
467
+ .decompress = qat_comp_alg_rfc1950_decompress ,
468
+ .dst_free = sgl_free ,
469
+ .reqsize = sizeof (struct qat_compression_req ),
328
470
} };
329
471
330
472
int qat_comp_algs_register (void )
0 commit comments