1313#include "qat_compression.h"
1414#include "qat_algs_send.h"
1515
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+
1625static DEFINE_MUTEX (algs_lock );
1726static unsigned int active_devs ;
1827
@@ -21,9 +30,12 @@ enum direction {
2130 COMPRESSION = 1 ,
2231};
2332
33+ struct qat_compression_req ;
34+
2435struct qat_compression_ctx {
2536 u8 comp_ctx [QAT_COMP_CTX_SIZE ];
2637 struct qat_compression_instance * inst ;
38+ int (* qat_comp_callback )(struct qat_compression_req * qat_req , void * resp );
2739};
2840
2941struct qat_dst {
@@ -97,6 +109,69 @@ static void qat_comp_resubmit(struct work_struct *work)
97109 areq -> base .complete (& areq -> base , ret );
98110}
99111
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+
100175static void qat_comp_generic_callback (struct qat_compression_req * qat_req ,
101176 void * resp )
102177{
@@ -167,6 +242,9 @@ static void qat_comp_generic_callback(struct qat_compression_req *qat_req,
167242 res = 0 ;
168243 areq -> dlen = produced ;
169244
245+ if (ctx -> qat_comp_callback )
246+ res = ctx -> qat_comp_callback (qat_req , resp );
247+
170248end :
171249 qat_bl_free_bufl (accel_dev , & qat_req -> buf );
172250 areq -> base .complete (& areq -> base , res );
@@ -215,26 +293,38 @@ static void qat_comp_alg_exit_tfm(struct crypto_acomp *acomp_tfm)
215293 memset (ctx , 0 , sizeof (* ctx ));
216294}
217295
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 )
220311{
221312 struct qat_compression_req * qat_req = acomp_request_ctx (areq );
222313 struct crypto_acomp * acomp_tfm = crypto_acomp_reqtfm (areq );
223314 struct crypto_tfm * tfm = crypto_acomp_tfm (acomp_tfm );
224315 struct qat_compression_ctx * ctx = crypto_tfm_ctx (tfm );
225316 struct qat_compression_instance * inst = ctx -> inst ;
226- struct qat_sgl_to_bufl_params * p_params = NULL ;
227317 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 ;
231321 dma_addr_t sfbuf , dfbuf ;
232322 u8 * req = qat_req -> req ;
233323 size_t ovf_buff_sz ;
234324 int ret ;
235325
236- params .sskip = 0 ;
237- params .dskip = 0 ;
326+ params .sskip = shdr ;
327+ params .dskip = dhdr ;
238328
239329 if (!areq -> src || !slen )
240330 return - EINVAL ;
@@ -257,6 +347,7 @@ static int qat_comp_alg_compress_decompress(struct acomp_req *areq,
257347 if (!areq -> dst )
258348 return - ENOMEM ;
259349
350+ dlen -= dhdr + dftr ;
260351 areq -> dlen = dlen ;
261352 qat_req -> dst .resubmitted = false;
262353 }
@@ -265,11 +356,10 @@ static int qat_comp_alg_compress_decompress(struct acomp_req *areq,
265356 params .extra_dst_buff = inst -> dc_data -> ovf_buff_p ;
266357 ovf_buff_sz = inst -> dc_data -> ovf_buff_sz ;
267358 params .sz_extra_dst_buff = ovf_buff_sz ;
268- p_params = & params ;
269359 }
270360
271361 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 );
273363 if (unlikely (ret ))
274364 return ret ;
275365
@@ -302,12 +392,49 @@ static int qat_comp_alg_compress_decompress(struct acomp_req *areq,
302392
303393static int qat_comp_alg_compress (struct acomp_req * req )
304394{
305- return qat_comp_alg_compress_decompress (req , COMPRESSION );
395+ return qat_comp_alg_compress_decompress (req , COMPRESSION , 0 , 0 , 0 , 0 );
306396}
307397
308398static int qat_comp_alg_decompress (struct acomp_req * req )
309399{
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 );
311438}
312439
313440static struct acomp_alg qat_acomp [] = { {
@@ -325,6 +452,21 @@ static struct acomp_alg qat_acomp[] = { {
325452 .decompress = qat_comp_alg_decompress ,
326453 .dst_free = sgl_free ,
327454 .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 ),
328470} };
329471
330472int qat_comp_algs_register (void )
0 commit comments