14fa9c49fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
291c1953dSRahul Lakkireddy /*
391c1953dSRahul Lakkireddy  *  Copyright (C) 2018 Chelsio Communications.  All rights reserved.
491c1953dSRahul Lakkireddy  */
591c1953dSRahul Lakkireddy 
691c1953dSRahul Lakkireddy #include <linux/zlib.h>
791c1953dSRahul Lakkireddy 
891c1953dSRahul Lakkireddy #include "cxgb4.h"
991c1953dSRahul Lakkireddy #include "cudbg_if.h"
1091c1953dSRahul Lakkireddy #include "cudbg_lib_common.h"
1191c1953dSRahul Lakkireddy #include "cudbg_zlib.h"
1291c1953dSRahul Lakkireddy 
cudbg_get_compress_hdr(struct cudbg_buffer * pdbg_buff,struct cudbg_buffer * pin_buff)1391c1953dSRahul Lakkireddy static int cudbg_get_compress_hdr(struct cudbg_buffer *pdbg_buff,
1491c1953dSRahul Lakkireddy 				  struct cudbg_buffer *pin_buff)
1591c1953dSRahul Lakkireddy {
1691c1953dSRahul Lakkireddy 	if (pdbg_buff->offset + sizeof(struct cudbg_compress_hdr) >
1791c1953dSRahul Lakkireddy 	    pdbg_buff->size)
1891c1953dSRahul Lakkireddy 		return CUDBG_STATUS_NO_MEM;
1991c1953dSRahul Lakkireddy 
2091c1953dSRahul Lakkireddy 	pin_buff->data = (char *)pdbg_buff->data + pdbg_buff->offset;
2191c1953dSRahul Lakkireddy 	pin_buff->offset = 0;
2291c1953dSRahul Lakkireddy 	pin_buff->size = sizeof(struct cudbg_compress_hdr);
2391c1953dSRahul Lakkireddy 	pdbg_buff->offset += sizeof(struct cudbg_compress_hdr);
2491c1953dSRahul Lakkireddy 	return 0;
2591c1953dSRahul Lakkireddy }
2691c1953dSRahul Lakkireddy 
cudbg_compress_buff(struct cudbg_init * pdbg_init,struct cudbg_buffer * pin_buff,struct cudbg_buffer * pout_buff)2791c1953dSRahul Lakkireddy int cudbg_compress_buff(struct cudbg_init *pdbg_init,
2891c1953dSRahul Lakkireddy 			struct cudbg_buffer *pin_buff,
2991c1953dSRahul Lakkireddy 			struct cudbg_buffer *pout_buff)
3091c1953dSRahul Lakkireddy {
3191c1953dSRahul Lakkireddy 	struct cudbg_buffer temp_buff = { 0 };
32325694e6SRahul Lakkireddy 	struct z_stream_s compress_stream;
3391c1953dSRahul Lakkireddy 	struct cudbg_compress_hdr *c_hdr;
3491c1953dSRahul Lakkireddy 	int rc;
3591c1953dSRahul Lakkireddy 
3691c1953dSRahul Lakkireddy 	/* Write compression header to output buffer before compression */
3791c1953dSRahul Lakkireddy 	rc = cudbg_get_compress_hdr(pout_buff, &temp_buff);
3891c1953dSRahul Lakkireddy 	if (rc)
3991c1953dSRahul Lakkireddy 		return rc;
4091c1953dSRahul Lakkireddy 
4191c1953dSRahul Lakkireddy 	c_hdr = (struct cudbg_compress_hdr *)temp_buff.data;
4291c1953dSRahul Lakkireddy 	c_hdr->compress_id = CUDBG_ZLIB_COMPRESS_ID;
4391c1953dSRahul Lakkireddy 
44325694e6SRahul Lakkireddy 	memset(&compress_stream, 0, sizeof(struct z_stream_s));
4591c1953dSRahul Lakkireddy 	compress_stream.workspace = pdbg_init->workspace;
4691c1953dSRahul Lakkireddy 	rc = zlib_deflateInit2(&compress_stream, Z_DEFAULT_COMPRESSION,
4791c1953dSRahul Lakkireddy 			       Z_DEFLATED, CUDBG_ZLIB_WIN_BITS,
4891c1953dSRahul Lakkireddy 			       CUDBG_ZLIB_MEM_LVL, Z_DEFAULT_STRATEGY);
4991c1953dSRahul Lakkireddy 	if (rc != Z_OK)
5091c1953dSRahul Lakkireddy 		return CUDBG_SYSTEM_ERROR;
5191c1953dSRahul Lakkireddy 
5291c1953dSRahul Lakkireddy 	compress_stream.next_in = pin_buff->data;
5391c1953dSRahul Lakkireddy 	compress_stream.avail_in = pin_buff->size;
5491c1953dSRahul Lakkireddy 	compress_stream.next_out = pout_buff->data + pout_buff->offset;
5591c1953dSRahul Lakkireddy 	compress_stream.avail_out = pout_buff->size - pout_buff->offset;
5691c1953dSRahul Lakkireddy 
5791c1953dSRahul Lakkireddy 	rc = zlib_deflate(&compress_stream, Z_FINISH);
5891c1953dSRahul Lakkireddy 	if (rc != Z_STREAM_END)
5991c1953dSRahul Lakkireddy 		return CUDBG_SYSTEM_ERROR;
6091c1953dSRahul Lakkireddy 
6191c1953dSRahul Lakkireddy 	rc = zlib_deflateEnd(&compress_stream);
6291c1953dSRahul Lakkireddy 	if (rc != Z_OK)
6391c1953dSRahul Lakkireddy 		return CUDBG_SYSTEM_ERROR;
6491c1953dSRahul Lakkireddy 
6591c1953dSRahul Lakkireddy 	c_hdr->compress_size = compress_stream.total_out;
6691c1953dSRahul Lakkireddy 	c_hdr->decompress_size = pin_buff->size;
6791c1953dSRahul Lakkireddy 	pout_buff->offset += compress_stream.total_out;
6891c1953dSRahul Lakkireddy 
6991c1953dSRahul Lakkireddy 	return 0;
7091c1953dSRahul Lakkireddy }
71