Create compression PMD for Intel QuickAssist devices
Currently only the C62x device is supported.

The qat comp PMD supports
 - stateless compression and
   decompression using the deflate algorithm.
 - checksum generation: Adler32, CRC32 and combined.

The compression service is hosted on a QuickAssist VF PCI
device, which is managed by code in the
drivers/common/qat directory.

This patch depends on the following patchset:
crypto/qat: move files to drivers/common directory

Signed-off-by: Fiona Trahe <fiona.tr...@intel.com>
Signed-off-by: Tomasz Jozwiak <tomaszx.jozw...@intel.com>
---
 MAINTAINERS                                  |    5 +
 config/common_base                           |    2 +
 doc/guides/compressdevs/features/qat.ini     |   22 +
 drivers/common/qat/Makefile                  |   60 ++-
 drivers/common/qat/qat_adf/icp_qat_fw_comp.h |  586 ++++++++++++++++++++++++++
 drivers/common/qat/qat_common.c              |   17 +-
 drivers/common/qat/qat_common.h              |   18 +-
 drivers/common/qat/qat_device.c              |    3 +
 drivers/common/qat/qat_device.h              |   10 +
 drivers/common/qat/qat_qp.c                  |   11 +-
 drivers/common/qat/qat_qp.h                  |    5 +
 drivers/compress/qat/qat_comp.c              |  383 +++++++++++++++++
 drivers/compress/qat/qat_comp.h              |   78 ++++
 drivers/compress/qat/qat_comp_pmd.c          |  479 +++++++++++++++++++++
 drivers/compress/qat/qat_comp_pmd.h          |   40 ++
 drivers/crypto/qat/qat_sym.c                 |   12 +-
 drivers/crypto/qat/qat_sym.h                 |   14 +-
 17 files changed, 1702 insertions(+), 43 deletions(-)
 create mode 100644 doc/guides/compressdevs/features/qat.ini
 create mode 100644 drivers/common/qat/qat_adf/icp_qat_fw_comp.h
 create mode 100644 drivers/compress/qat/qat_comp.c
 create mode 100644 drivers/compress/qat/qat_comp.h
 create mode 100644 drivers/compress/qat/qat_comp_pmd.c
 create mode 100644 drivers/compress/qat/qat_comp_pmd.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7cc8860..5381f0c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -831,6 +831,11 @@ F: drivers/compress/isal/
 F: doc/guides/compressdevs/isal.rst
 F: doc/guides/compressdevs/features/isal.ini
 
+Intel QuickAssist
+M: Fiona Trahe <fiona.tr...@intel.com>
+F: drivers/compress/qat/
+F: drivers/common/qat/
+F: doc/guides/compressdevs/features/qat.ini
 
 Eventdev Drivers
 ----------------
diff --git a/config/common_base b/config/common_base
index f456f95..b85c990 100644
--- a/config/common_base
+++ b/config/common_base
@@ -487,6 +487,8 @@ CONFIG_RTE_LIBRTE_PMD_QAT=y
 # Max. number of QuickAssist devices, which can be detected and attached
 #
 CONFIG_RTE_PMD_QAT_MAX_PCI_DEVICES=48
+CONFIG_RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS=16
+CONFIG_RTE_PMD_QAT_COMP_IM_BUFFER_SIZE=131072
 #
 # Compile PMD for virtio crypto devices
 #
diff --git a/doc/guides/compressdevs/features/qat.ini 
b/doc/guides/compressdevs/features/qat.ini
new file mode 100644
index 0000000..d99b5de
--- /dev/null
+++ b/doc/guides/compressdevs/features/qat.ini
@@ -0,0 +1,22 @@
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+; Supported features of 'QAT' compression driver.
+;
+[Features]
+HW Accelerated = Y
+CPU SSE        =
+CPU AVX        =
+CPU AVX2       =
+CPU AVX512     =
+CPU NEON       =
+Stateful       =
+By-Pass        =
+Chained mbufs  = Y
+Deflate        = Y
+LZS            =
+Adler32        = Y
+Crc32          = Y
+Adler32&Crc32  = Y
+Fixed          = Y
+Dynamic        = Y
diff --git a/drivers/common/qat/Makefile b/drivers/common/qat/Makefile
index c023c34..a8545f4 100644
--- a/drivers/common/qat/Makefile
+++ b/drivers/common/qat/Makefile
@@ -6,29 +6,24 @@ include $(RTE_SDK)/mk/rte.vars.mk
 # libcrypto detection
 LIBCRYPTO := $(shell pkg-config --exists libcrypto 1>&2 2> /dev/null; echo $$?)
 
-# library name
-LIB = librte_pmd_qat.a
-
-# library version
-LIBABIVER := 1
-
-# build flags
-CFLAGS += $(WERROR_FLAGS)
-CFLAGS += -O3
-
 # build directories
 QAT_CRYPTO_DIR := $(RTE_SDK)/drivers/crypto/qat
+QAT_COMPRESS_DIR := $(RTE_SDK)/drivers/compress/qat
 
 # external library include paths
 CFLAGS += -I$(SRCDIR)/qat_adf
 CFLAGS += -I$(SRCDIR)
+
 CFLAGS += -I$(QAT_CRYPTO_DIR)
+CFLAGS += -I$(QAT_COMPRESS_DIR)
 
-# library common source files
-SRCS-y += qat_device.c
-SRCS-y += qat_common.c
-SRCS-y += qat_logs.c
-SRCS-y += qat_qp.c
+ifeq ($(CONFIG_RTE_LIBRTE_COMPRESSDEV),y)
+       CFLAGS += -DALLOW_EXPERIMENTAL_API
+       LDLIBS += -lrte_compressdev
+       SRCS-y += $(QAT_COMPRESS_DIR)/qat_comp.c
+       SRCS-y += $(QAT_COMPRESS_DIR)/qat_comp_pmd.c
+       build_qat = yes
+endif
 
 ifeq ($(LIBCRYPTO),0)
        LDLIBS += -lrte_cryptodev
@@ -37,15 +32,38 @@ ifeq ($(LIBCRYPTO),0)
        SRCS-y += $(QAT_CRYPTO_DIR)/qat_sym.c
        SRCS-y += $(QAT_CRYPTO_DIR)/qat_sym_session.c
        SRCS-y += $(QAT_CRYPTO_DIR)/qat_sym_pmd.c
+       build_qat = yes
 endif
 
-LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
-LDLIBS += -lrte_pci -lrte_bus_pci
 
-# export include files
-SYMLINK-y-include +=
 
-# versioning export map
-EXPORT_MAP := qat/rte_pmd_qat_version.map
+ifdef build_qat
+
+       # library name
+       LIB = librte_pmd_qat.a
+
+       # library version
+       LIBABIVER := 1
+
+       # build flags
+       CFLAGS += $(WERROR_FLAGS)
+       CFLAGS += -O3
+
+       # library common source files
+       SRCS-y += qat_device.c
+       SRCS-y += qat_common.c
+       SRCS-y += qat_logs.c
+       SRCS-y += qat_qp.c
+
+       LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+       LDLIBS += -lrte_pci -lrte_bus_pci
+
+       # export include files
+       SYMLINK-y-include +=
+
+       # versioning export map
+       EXPORT_MAP := qat/rte_pmd_qat_version.map
+
+endif
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/common/qat/qat_adf/icp_qat_fw_comp.h 
b/drivers/common/qat/qat_adf/icp_qat_fw_comp.h
new file mode 100644
index 0000000..4ad1d30
--- /dev/null
+++ b/drivers/common/qat/qat_adf/icp_qat_fw_comp.h
@@ -0,0 +1,586 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2015-2018 Intel Corporation
+ */
+#ifndef _ICP_QAT_FW_COMP_H_
+#define _ICP_QAT_FW_COMP_H_
+
+#include "icp_qat_fw.h"
+
+/* Next curr slice */
+#define ICP_QAT_FW_COMN_NEXT_ID_BITPOS 4
+#define ICP_QAT_FW_COMN_NEXT_ID_MASK 0xF0
+#define ICP_QAT_FW_COMN_CURR_ID_BITPOS 0
+#define ICP_QAT_FW_COMN_CURR_ID_MASK 0x0F
+
+#define ICP_QAT_FW_COMN_NEXT_ID_SET_2(next_curr_id, val)                       
\
+       do {                                                                   \
+               (next_curr_id) =                                               \
+                   (((next_curr_id)&ICP_QAT_FW_COMN_CURR_ID_MASK) |           \
+                    (((val) << ICP_QAT_FW_COMN_NEXT_ID_BITPOS) &              \
+                     ICP_QAT_FW_COMN_NEXT_ID_MASK))                           \
+       } while (0)
+
+#define ICP_QAT_FW_COMN_CURR_ID_SET_2(next_curr_id, val)                       
\
+       do {                                                                   \
+               (next_curr_id) =                                               \
+                   (((next_curr_id)&ICP_QAT_FW_COMN_NEXT_ID_MASK) |           \
+                    ((val)&ICP_QAT_FW_COMN_CURR_ID_MASK))                     \
+       } while (0)
+
+/* Private defines */
+#define QAT_COMPRESSION_DIR_BITPOS 4
+/**< @ingroup icp_qat_hw_defs
+ * Define for the compression direction bit position
+ */
+
+#define QAT_COMPRESSION_DIR_MASK 0x7
+/**< @ingroup icp_qat_hw_defs
+ * Define for the compression direction mask (three bits)
+ */
+
+#define QAT_COMPRESSION_DELAYED_MATCH_BITPOS 16
+/**< @ingroup icp_qat_hw_defs
+ * Define for the compression delayed match bit position
+ */
+
+#define QAT_COMPRESSION_DELAYED_MATCH_MASK 0x1
+/**< @ingroup icp_qat_hw_defs
+ * Define for the delayed match mask (one bit)
+ */
+
+#define QAT_COMPRESSION_ALGO_BITPOS 31
+/**< @ingroup icp_qat_hw_defs
+ * Define for the compression algorithm bit position
+ */
+
+#define QAT_COMPRESSION_ALGO_MASK 0x1
+/**< @ingroup icp_qat_hw_defs
+ * Define for the compression algorithm mask (one bit)
+ */
+
+#define QAT_COMPRESSION_DEPTH_BITPOS 28
+/**< @ingroup icp_qat_hw_defs
+ * Define for the compression depth bit position
+ */
+
+#define QAT_COMPRESSION_DEPTH_MASK 0x7
+/**< @ingroup icp_qat_hw_defs
+ * Define for the compression depth mask (three bits)
+ */
+
+#define QAT_COMPRESSION_FILE_TYPE_BITPOS 24
+/**< @ingroup icp_qat_hw_defs
+ * Define for the compression file type bit position
+ */
+
+#define QAT_COMPRESSION_FILE_TYPE_MASK 0xF
+/**< @ingroup icp_qat_hw_defs
+ * Define for the compression file type mask (four bits)
+ */
+
+#define ICP_QAT_FW_COMP_NOT_SOP 0
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that a request is NOT Start of Packet
+ */
+
+#define ICP_QAT_FW_COMP_SOP 1
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that a request IS Start of Packet
+ */
+
+#define ICP_QAT_FW_COMP_NOT_EOP 0
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that a request is NOT Start of Packet
+ */
+
+#define ICP_QAT_FW_COMP_EOP 1
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that a request IS End of Packet
+ */
+
+#define ICP_QAT_FW_COMP_NOT_BFINAL 0
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing to indicate firmware this is not the last block
+ */
+
+#define ICP_QAT_FW_COMP_BFINAL 1
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing to indicate firmware this is the last block
+ */
+
+#define ICP_QAT_FW_COMP_NO_MCA 0
+/**< @ingroup icp_qat_fw_comp
+ * Flag indicating that NO mca check is to be performed on the request
+ */
+
+#define ICP_QAT_FW_COMP_MCA 1
+/**< @ingroup icp_qat_fw_comp
+ * Flag indicating that an mca check IS to be performed on the request
+ */
+
+#define ICP_QAT_FW_COMP_SOP_BITPOS 0
+/**< @ingroup icp_qat_fw_comp
+ * Starting bit position for SOP
+ */
+
+#define ICP_QAT_FW_COMP_SOP_MASK 0x1
+/**< @ingroup icp_qat_fw_comp
+ *  One bit mask used to determine SOP
+ */
+
+#define ICP_QAT_FW_COMP_EOP_BITPOS 1
+/**< @ingroup icp_qat_fw_comp
+ *  Starting bit position for EOP
+ */
+
+#define ICP_QAT_FW_COMP_EOP_MASK 0x1
+/**< @ingroup icp_qat_fw_comp
+ *  One bit mask used to determine EOP
+ */
+
+#define ICP_QAT_FW_COMP_BFINAL_MASK 0x1
+/**< @ingroup icp_qat_fw_comp
+ *  One bit mask for the bfinal bit
+ */
+
+#define ICP_QAT_FW_COMP_BFINAL_BITPOS 6
+/**< @ingroup icp_qat_fw_comp
+ *  Starting bit position for the bfinal bit
+ */
+
+#define ICP_QAT_FW_COMP_MCA_MASK 0x1
+/**< @ingroup icp_qat_fw_comp
+ *  One bit mask for the MCA bit
+ */
+
+#define ICP_QAT_FW_COMP_MCA_BITPOS 16
+/**< @ingroup icp_qat_fw_comp
+ *  Starting bit position for the MCA bit
+ */
+
+#define ICP_QAT_HW_COMPRESSION_CONFIG_BUILD(dir, delayed, algo, depth,         
\
+                                           filetype)                          \
+       ((((dir)&QAT_COMPRESSION_DIR_MASK) << QAT_COMPRESSION_DIR_BITPOS) |    \
+        (((delayed)&QAT_COMPRESSION_DELAYED_MATCH_MASK)                       \
+         << QAT_COMPRESSION_DELAYED_MATCH_BITPOS) |                           \
+        (((algo)&QAT_COMPRESSION_ALGO_MASK) << QAT_COMPRESSION_ALGO_BITPOS) | \
+        (((depth)&QAT_COMPRESSION_DEPTH_MASK)                                 \
+         << QAT_COMPRESSION_DEPTH_BITPOS) |                                   \
+        (((filetype)&QAT_COMPRESSION_FILE_TYPE_MASK)                          \
+         << QAT_COMPRESSION_FILE_TYPE_BITPOS))
+
+/**< Flag usage */
+
+#define ICP_QAT_FW_COMP_STATELESS_SESSION 0
+/**< @ingroup icp_qat_fw_comp
+ *  Flag representing that session is stateless
+ */
+
+#define ICP_QAT_FW_COMP_STATEFUL_SESSION 1
+/**< @ingroup icp_qat_fw_comp
+ *  Flag representing that session is stateful
+ */
+
+#define ICP_QAT_FW_COMP_NOT_AUTO_SELECT_BEST 0
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that autoselectbest is NOT used
+ */
+
+#define ICP_QAT_FW_COMP_AUTO_SELECT_BEST 1
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that autoselectbest is used
+ */
+
+#define ICP_QAT_FW_COMP_NOT_ENH_AUTO_SELECT_BEST 0
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that enhanced autoselectbest is NOT used
+ */
+
+#define ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST 1
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that enhanced autoselectbest is used
+ */
+
+#define ICP_QAT_FW_COMP_NOT_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST 0
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that enhanced autoselectbest is NOT used
+ */
+
+#define ICP_QAT_FW_COMP_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST 1
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing that enhanced autoselectbest is used
+ */
+
+#define ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_USED_AS_INTMD_BUF 1
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing secure RAM from being used as
+ * an intermediate buffer is DISABLED.
+ */
+
+#define ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF 0
+/**< @ingroup icp_qat_fw_comp
+ * Flag representing secure RAM from being used as
+ * an intermediate buffer is ENABLED.
+ */
+
+/**< Flag mask & bit position */
+
+#define ICP_QAT_FW_COMP_SESSION_TYPE_BITPOS 2
+/**< @ingroup icp_qat_fw_comp
+ * Starting bit position for the session type
+ */
+
+#define ICP_QAT_FW_COMP_SESSION_TYPE_MASK 0x1
+/**< @ingroup icp_qat_fw_comp
+ * One bit mask used to determine the session type
+ */
+
+#define ICP_QAT_FW_COMP_AUTO_SELECT_BEST_BITPOS 3
+/**< @ingroup icp_qat_fw_comp
+ * Starting bit position for auto select best
+ */
+
+#define ICP_QAT_FW_COMP_AUTO_SELECT_BEST_MASK 0x1
+/**< @ingroup icp_qat_fw_comp
+ * One bit mask for auto select best
+ */
+
+#define ICP_QAT_FW_COMP_ENHANCED_AUTO_SELECT_BEST_BITPOS 4
+/**< @ingroup icp_qat_fw_comp
+ * Starting bit position for enhanced auto select best
+ */
+
+#define ICP_QAT_FW_COMP_ENHANCED_AUTO_SELECT_BEST_MASK 0x1
+/**< @ingroup icp_qat_fw_comp
+ * One bit mask for enhanced auto select best
+ */
+
+#define ICP_QAT_FW_COMP_RET_DISABLE_TYPE0_HEADER_DATA_BITPOS 5
+/**< @ingroup icp_qat_fw_comp
+ * Starting bit position for disabling type zero header write back
+ * when Enhanced autoselect best is enabled. If set firmware does
+ * not return type0 store block header, only copies src to dest.
+ * (if best output is Type0)
+ */
+
+#define ICP_QAT_FW_COMP_RET_DISABLE_TYPE0_HEADER_DATA_MASK 0x1
+/**< @ingroup icp_qat_fw_comp
+ * One bit mask for auto select best
+ */
+
+#define ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_AS_INTMD_BUF_BITPOS 7
+/**< @ingroup icp_qat_fw_comp
+ * Starting bit position for flag used to disable secure ram from
+ *  being used as an intermediate buffer.
+ */
+
+#define ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_AS_INTMD_BUF_MASK 0x1
+/**< @ingroup icp_qat_fw_comp
+ * One bit mask for disable secure ram for use as an intermediate
+ * buffer.
+ */
+
+#define ICP_QAT_FW_COMP_FLAGS_BUILD(sesstype, autoselect, enhanced_asb,        
\
+                                   ret_uncomp, secure_ram)                    \
+       ((((sesstype)&ICP_QAT_FW_COMP_SESSION_TYPE_MASK)                       \
+         << ICP_QAT_FW_COMP_SESSION_TYPE_BITPOS) |                            \
+        (((autoselect)&ICP_QAT_FW_COMP_AUTO_SELECT_BEST_MASK)                 \
+         << ICP_QAT_FW_COMP_AUTO_SELECT_BEST_BITPOS) |                        \
+        (((enhanced_asb)&ICP_QAT_FW_COMP_ENHANCED_AUTO_SELECT_BEST_MASK)      \
+         << ICP_QAT_FW_COMP_ENHANCED_AUTO_SELECT_BEST_BITPOS) |               \
+        (((ret_uncomp)&ICP_QAT_FW_COMP_RET_DISABLE_TYPE0_HEADER_DATA_MASK)    \
+         << ICP_QAT_FW_COMP_RET_DISABLE_TYPE0_HEADER_DATA_BITPOS) |           \
+        (((secure_ram)&ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_AS_INTMD_BUF_MASK)  \
+         << ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_AS_INTMD_BUF_BITPOS))
+
+enum icp_qat_hw_compression_algo {
+       ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE = 0,  /*!< Deflate compression */
+       ICP_QAT_HW_COMPRESSION_ALGO_LZS = 1,      /*!< LZS compression */
+       ICP_QAT_HW_COMPRESSION_ALGO_DELIMITER = 2 /**< Delimiter type */
+};
+
+enum icp_qat_hw_compression_file_type {
+       ICP_QAT_HW_COMPRESSION_FILE_TYPE_0 = 0,
+       /*!< Use Static Trees */
+
+       ICP_QAT_HW_COMPRESSION_FILE_TYPE_1 = 1,
+       /*!< Use Semi-Dynamic Trees at offset 0 */
+
+       ICP_QAT_HW_COMPRESSION_FILE_TYPE_2 = 2,
+       /*!< Use Semi-Dynamic Trees at offset 320 */
+
+       ICP_QAT_HW_COMPRESSION_FILE_TYPE_3 = 3,
+       /*!< Use Semi-Dynamic Trees at offset 640 */
+
+       ICP_QAT_HW_COMPRESSION_FILE_TYPE_4 = 4,
+       /*!< Use Semi-Dynamic Trees at offset 960 */
+
+       ICP_QAT_HW_COMPRESSION_FILE_TYPE_DELIMITER = 5
+       /**< Delimiter type */
+};
+
+enum icp_qat_hw_compression_depth {
+       ICP_QAT_HW_COMPRESSION_DEPTH_1 = 0,
+       /*!< Search depth 1 (Fastest least exhaustive) */
+
+       ICP_QAT_HW_COMPRESSION_DEPTH_4 = 1,
+       /*!< Search depth 4 */
+
+       ICP_QAT_HW_COMPRESSION_DEPTH_8 = 2,
+       /*!< Search depth 8 */
+
+       ICP_QAT_HW_COMPRESSION_DEPTH_16 = 3,
+       /*!< Search depth 16 (Slowest, most exhaustive) */
+
+       ICP_QAT_HW_COMPRESSION_DEPTH_DELIMITER = 4
+       /**< Delimiter type */
+};
+
+enum icp_qat_hw_compression_delayed_match {
+       ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_DISABLED = 0,
+       /*!< Delayed match disabled */
+
+       ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED = 1,
+       /*!< Delayed match enabled
+        * Note: This is the only valid mode - refer to CPM1.6 SAS
+        */
+
+       ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_DELIMITER = 2
+       /**< Delimiter type */
+};
+
+enum icp_qat_fw_comp_cmd_id {
+       ICP_QAT_FW_COMP_CMD_STATIC = 0,
+       /*!< Static Compress Request */
+
+       ICP_QAT_FW_COMP_CMD_DYNAMIC = 1,
+       /*!< Dynamic Compress Request */
+
+       ICP_QAT_FW_COMP_CMD_DECOMPRESS = 2,
+       /*!< Decompress Request */
+
+       ICP_QAT_FW_COMP_CMD_DELIMITER
+       /**< Delimiter type */
+};
+
+enum { ICP_QAT_HW_COMPRESSION_DIR_COMPRESS = 0,    /*!< Compression */
+       ICP_QAT_HW_COMPRESSION_DIR_DECOMPRESS = 1, /*!< Decompression */
+       ICP_QAT_HW_COMPRESSION_DIR_DELIMITER = 2   /**< Delimiter type */
+} icp_qat_hw_compression_direction;
+
+enum qat_comp_request {
+       QAT_COMP_REQUEST_STATIC_COMP_STATELESS,
+       QAT_COMP_REQUEST_DYNAMIC_COMP_STATELESS,
+       QAT_COMP_REQUEST_DECOMPRESS,
+       REQ_COMP_END
+};
+
+union icp_qat_fw_comp_req_hdr_cd_pars {
+       /**< LWs 2-5 */
+       struct {
+               uint64_t content_desc_addr;
+               /**< Address of the content descriptor */
+
+               uint16_t content_desc_resrvd1;
+               /**< Content descriptor reserved field */
+
+               uint8_t content_desc_params_sz;
+               /**< Size of the content descriptor parameters in quad words.
+                * These parameters describe the session setup configuration
+                * info for the slices that this request relies upon i.e.
+                * the configuration word and cipher key needed by the cipher
+                * slice if there is a request for cipher processing.
+                */
+
+               uint8_t   content_desc_hdr_resrvd2;
+               /**< Content descriptor reserved field */
+
+               uint32_t        content_desc_resrvd3;
+               /**< Content descriptor reserved field */
+       } s;
+
+       struct {
+               uint32_t comp_slice_cfg_word[ICP_QAT_FW_NUM_LONGWORDS_2];
+               /* Compression Slice Config Word */
+
+               uint32_t content_desc_resrvd4;
+               /**< Content descriptor reserved field */
+
+       } sl;
+
+};
+
+struct icp_qat_fw_comp_req_params {
+       /**< LW 14 */
+       uint32_t comp_len;
+       /**< Size of input to process in bytes Note:  Only EOP requests can be
+        * odd for decompression. IA must set LSB to zero for odd sized
+        * intermediate inputs
+        */
+
+       /**< LW 15 */
+       uint32_t out_buffer_sz;
+       /**< Size of output buffer in bytes */
+
+       /**< LW 16 */
+       uint32_t initial_crc32;
+       /**< CRC of previously processed bytes */
+
+       /**< LW 17 */
+       uint32_t initial_adler;
+       /**< Adler of previously processed bytes */
+
+       /**< LW 18 */
+       uint32_t req_par_flags;
+
+       /**< LW 19 */
+       uint32_t rsrvd;
+};
+
+struct icp_qat_fw_xlt_req_params {
+       /**< LWs 20-21 */
+       uint64_t inter_buff_ptr;
+       /**< This field specifies the physical address of an intermediate
+        *  buffer SGL array. The array contains a pair of 64-bit
+        *  intermediate buffer pointers to SGL buffer descriptors, one pair
+        *  per CPM. Please refer to the CPM1.6 Firmware Interface HLD
+        *  specification for more details.
+        */
+};
+
+struct icp_qat_fw_comp_cd_hdr {
+       /**< LW 24 */
+       uint16_t ram_bank_flags;
+       /**< Flags to show which ram banks to access */
+
+       uint8_t comp_cfg_offset;
+       /**< Quad word offset from the content descriptor parameters address
+        * to the parameters for the compression processing
+        */
+
+       uint8_t next_curr_id;
+       /**< This field combines the next and current id (each four bits) -
+        * the next id is the most significant nibble.
+        * Next Id:  Set to the next slice to pass the compressed data through.
+        * Set to ICP_QAT_FW_SLICE_DRAM_WR if the data is not to go through
+        * anymore slices after compression
+        * Current Id: Initialised with the compression slice type
+        */
+
+       /**< LW 25 */
+       uint32_t resrvd;
+
+       /**< LWs 26-27 */
+       uint64_t comp_state_addr;
+       /**< Pointer to compression state */
+
+       /**< LWs 28-29 */
+       uint64_t ram_banks_addr;
+       /**< Pointer to banks */
+
+};
+
+struct icp_qat_fw_xlt_cd_hdr {
+       /**< LW 30 */
+       uint16_t resrvd1;
+       /**< Reserved field and assumed set to 0 */
+
+       uint8_t resrvd2;
+       /**< Reserved field and assumed set to 0 */
+
+       uint8_t next_curr_id;
+       /**< This field combines the next and current id (each four bits) -
+        * the next id is the most significant nibble.
+        * Next Id:  Set to the next slice to pass the translated data through.
+        * Set to ICP_QAT_FW_SLICE_DRAM_WR if the data is not to go through
+        * any more slices after compression
+        * Current Id: Initialised with the translation slice type
+        */
+
+       /**< LW 31 */
+       uint32_t resrvd3;
+       /**< Reserved and should be set to zero, needed for quadword
+        * alignment
+        */
+};
+
+struct icp_qat_fw_comp_req {
+       /**< LWs 0-1 */
+       struct icp_qat_fw_comn_req_hdr comn_hdr;
+       /**< Common request header - for Service Command Id,
+        * use service-specific Compression Command Id.
+        * Service Specific Flags - use Compression Command Flags
+        */
+
+       /**< LWs 2-5 */
+       union icp_qat_fw_comp_req_hdr_cd_pars cd_pars;
+       /**< Compression service-specific content descriptor field which points
+        * either to a content descriptor parameter block or contains the
+        * compression slice config word.
+        */
+
+       /**< LWs 6-13 */
+       struct icp_qat_fw_comn_req_mid comn_mid;
+       /**< Common request middle section */
+
+       /**< LWs 14-19 */
+       struct icp_qat_fw_comp_req_params comp_pars;
+       /**< Compression request Parameters block */
+
+       /**< LWs 20-21 */
+       union {
+               struct icp_qat_fw_xlt_req_params xlt_pars;
+               /**< Translation request Parameters block */
+
+               uint32_t resrvd1[ICP_QAT_FW_NUM_LONGWORDS_2];
+               /**< Reserved if not used for translation */
+
+       } u1;
+
+       /**< LWs 22-23 */
+       union {
+               uint32_t resrvd2[ICP_QAT_FW_NUM_LONGWORDS_2];
+               /**< Reserved - not used if Batch and Pack is disabled.*/
+
+               uint64_t bnp_res_table_addr;
+               /**< A generic pointer to the unbounded list of
+                * icp_qat_fw_resp_comp_pars_t members. This pointer is only
+                * used when the Batch and Pack is enabled.
+                */
+       } u3;
+
+       /**< LWs 24-29 */
+       struct icp_qat_fw_comp_cd_hdr comp_cd_ctrl;
+       /**< Compression request content descriptor control block header */
+
+       /**< LWs 30-31 */
+       union {
+               struct icp_qat_fw_xlt_cd_hdr xlt_cd_ctrl;
+               /**< Translation request content descriptor
+                * control block header
+                */
+
+               uint32_t resrvd3[ICP_QAT_FW_NUM_LONGWORDS_2];
+               /**< Reserved if not used for translation */
+       } u2;
+};
+
+struct qat_comp_res_data {
+       uint32_t consumed;
+       uint32_t produced;
+       union {
+               uint64_t curr_chksum;
+               struct {
+                       uint32_t curr_crc;
+                       uint32_t curr_adler;
+               };
+       };
+};
+
+#define ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(sop, eop, bfinal, mca)           
\
+       ((((sop)&ICP_QAT_FW_COMP_SOP_MASK) << ICP_QAT_FW_COMP_SOP_BITPOS) |    \
+        (((eop)&ICP_QAT_FW_COMP_EOP_MASK) << ICP_QAT_FW_COMP_EOP_BITPOS) |    \
+        (((bfinal)&ICP_QAT_FW_COMP_BFINAL_MASK)                               \
+         << ICP_QAT_FW_COMP_BFINAL_BITPOS) |                                  \
+        (((mca)&ICP_QAT_FW_COMP_MCA_MASK) << ICP_QAT_FW_COMP_MCA_BITPOS))
+#endif
diff --git a/drivers/common/qat/qat_common.c b/drivers/common/qat/qat_common.c
index c206d3b..b05c09f 100644
--- a/drivers/common/qat/qat_common.c
+++ b/drivers/common/qat/qat_common.c
@@ -8,11 +8,12 @@
 
 int
 qat_sgl_fill_array(struct rte_mbuf *buf, uint64_t buf_start,
-               struct qat_sgl *list, uint32_t data_len)
+               void *lst, uint32_t data_len,
+               const int32_t max_segs)
 {
        int nr = 1;
-
-       uint32_t buf_len = rte_pktmbuf_iova(buf) -
+       struct qat_sgl *list = (struct qat_sgl *)lst;
+       uint32_t buf_len = rte_pktmbuf_mtophys(buf) -
                        buf_start + rte_pktmbuf_data_len(buf);
 
        list->buffers[0].addr = buf_start;
@@ -27,16 +28,16 @@
 
        buf = buf->next;
        while (buf) {
-               if (unlikely(nr == QAT_SGL_MAX_NUMBER)) {
-                       QAT_LOG(ERR,
-                               "QAT PMD exceeded size of QAT SGL entry(%u)",
-                                       QAT_SGL_MAX_NUMBER);
+               if (unlikely(nr == max_segs)) {
+                       QAT_LOG(ERR, "QAT PMD exceeded size of QAT SGL"
+                                       " entry(%u)",
+                                       max_segs);
                        return -EINVAL;
                }
 
                list->buffers[nr].len = rte_pktmbuf_data_len(buf);
                list->buffers[nr].resrvd = 0;
-               list->buffers[nr].addr = rte_pktmbuf_iova(buf);
+               list->buffers[nr].addr = rte_pktmbuf_mtophys(buf);
 
                buf_len += list->buffers[nr].len;
                buf = buf->next;
diff --git a/drivers/common/qat/qat_common.h b/drivers/common/qat/qat_common.h
index db85d54..a011f5a 100644
--- a/drivers/common/qat/qat_common.h
+++ b/drivers/common/qat/qat_common.h
@@ -31,6 +31,7 @@ enum qat_service_type {
        QAT_SERVICE_COMPRESSION,
        QAT_SERVICE_INVALID
 };
+
 #define QAT_MAX_SERVICES               (QAT_SERVICE_INVALID)
 
 /**< Common struct for scatter-gather list operations */
@@ -40,11 +41,17 @@ struct qat_flat_buf {
        uint64_t addr;
 } __rte_packed;
 
+#define qat_sgl_hdr  struct { \
+       uint64_t resrvd; \
+       uint32_t num_bufs; \
+       uint32_t num_mapped_bufs; \
+}
+
+__extension__
 struct qat_sgl {
-       uint64_t resrvd;
-       uint32_t num_bufs;
-       uint32_t num_mapped_bufs;
-       struct qat_flat_buf buffers[QAT_SGL_MAX_NUMBER];
+       qat_sgl_hdr;
+       /* flexible array of flat buffers*/
+       struct qat_flat_buf buffers[0];
 } __rte_packed __rte_cache_aligned;
 
 /** Common, i.e. not service-specific, statistics */
@@ -64,7 +71,8 @@ struct qat_common_stats {
 
 int
 qat_sgl_fill_array(struct rte_mbuf *buf, uint64_t buf_start,
-               struct qat_sgl *list, uint32_t data_len);
+               void *lst, uint32_t data_len,
+               const int32_t max_segs);
 void
 qat_stats_get(struct qat_pci_device *dev,
                struct qat_common_stats *stats,
diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c
index 64f236e..0dadc8f 100644
--- a/drivers/common/qat/qat_device.c
+++ b/drivers/common/qat/qat_device.c
@@ -5,6 +5,7 @@
 #include "qat_device.h"
 #include "adf_transport_access_macros.h"
 #include "qat_sym_pmd.h"
+#include "qat_comp_pmd.h"
 
 /* Hardware device information per generation */
 __extension__
@@ -12,11 +13,13 @@ struct qat_gen_hw_data qat_gen_config[] =  {
        [QAT_GEN1] = {
                .dev_gen = QAT_GEN1,
                .qp_hw_data = qat_gen1_qps,
+               .comp_num_im_bufs_required = QAT_NUM_INTERM_BUFS_GEN1
        },
        [QAT_GEN2] = {
                .dev_gen = QAT_GEN2,
                .qp_hw_data = qat_gen1_qps,
                /* gen2 has same ring layout as gen1 */
+               .comp_num_im_bufs_required = QAT_NUM_INTERM_BUFS_GEN2
        },
 };
 
diff --git a/drivers/common/qat/qat_device.h b/drivers/common/qat/qat_device.h
index 0cb370c..41f874b 100644
--- a/drivers/common/qat/qat_device.h
+++ b/drivers/common/qat/qat_device.h
@@ -16,6 +16,11 @@
 
 #define QAT_DEV_NAME_MAX_LEN   64
 
+enum qat_comp_num_im_buffers {
+       QAT_NUM_INTERM_BUFS_GEN1 = 12,
+       QAT_NUM_INTERM_BUFS_GEN2 = 20
+};
+
 /*
  * This struct holds all the data about a QAT pci device
  * including data about all services it supports.
@@ -25,6 +30,8 @@
  *  - runtime data
  */
 struct qat_sym_dev_private;
+struct qat_comp_dev_private;
+
 struct qat_pci_device {
 
        /* Data used by all services */
@@ -55,6 +62,8 @@ struct qat_pci_device {
         */
 
        /* Data relating to compression service */
+       struct qat_comp_dev_private *comp_dev;
+       /**< link back to compressdev private data */
 
        /* Data relating to asymmetric crypto service */
 
@@ -63,6 +72,7 @@ struct qat_pci_device {
 struct qat_gen_hw_data {
        enum qat_device_gen dev_gen;
        const struct qat_qp_hw_data (*qp_hw_data)[ADF_MAX_QPS_ON_ANY_SERVICE];
+       enum qat_comp_num_im_buffers comp_num_im_bufs_required;
 };
 
 extern struct qat_gen_hw_data qat_gen_config[];
diff --git a/drivers/common/qat/qat_qp.c b/drivers/common/qat/qat_qp.c
index 32c1759..7ca7a45 100644
--- a/drivers/common/qat/qat_qp.c
+++ b/drivers/common/qat/qat_qp.c
@@ -15,6 +15,7 @@
 #include "qat_device.h"
 #include "qat_qp.h"
 #include "qat_sym.h"
+#include "qat_comp.h"
 #include "adf_transport_access_macros.h"
 
 
@@ -606,8 +607,8 @@ void rxq_free_desc(struct qat_qp *qp, struct qat_queue *q)
 
                if (tmp_qp->service_type == QAT_SERVICE_SYMMETRIC)
                        qat_sym_process_response(ops, resp_msg);
-               /* add qat_asym_process_response here */
-               /* add qat_comp_process_response here */
+               else if (tmp_qp->service_type == QAT_SERVICE_COMPRESSION)
+                       qat_comp_process_response(ops, resp_msg);
 
                head = adf_modulo(head + rx_queue->msg_size,
                                  rx_queue->modulo_mask);
@@ -633,3 +634,9 @@ void rxq_free_desc(struct qat_qp *qp, struct qat_queue *q)
        }
        return resp_counter;
 }
+
+__attribute__((weak)) int
+qat_comp_process_response(void **op __rte_unused, uint8_t *resp __rte_unused)
+{
+       return  0;
+}
diff --git a/drivers/common/qat/qat_qp.h b/drivers/common/qat/qat_qp.h
index 59db945..69f8a61 100644
--- a/drivers/common/qat/qat_qp.h
+++ b/drivers/common/qat/qat_qp.h
@@ -103,4 +103,9 @@ struct qat_qp {
 int
 qat_qps_per_service(const struct qat_qp_hw_data *qp_hw_data,
                        enum qat_service_type service);
+
+/* Needed for weak function*/
+int
+qat_comp_process_response(void **op __rte_unused, uint8_t *resp __rte_unused);
+
 #endif /* _QAT_QP_H_ */
diff --git a/drivers/compress/qat/qat_comp.c b/drivers/compress/qat/qat_comp.c
new file mode 100644
index 0000000..813d841
--- /dev/null
+++ b/drivers/compress/qat/qat_comp.c
@@ -0,0 +1,383 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_hexdump.h>
+#include <rte_comp.h>
+#include <rte_bus_pci.h>
+#include <rte_byteorder.h>
+#include <rte_memcpy.h>
+#include <rte_common.h>
+#include <rte_spinlock.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "qat_logs.h"
+#include "qat_comp.h"
+#include "qat_comp_pmd.h"
+
+int
+qat_comp_build_request(void *in_op, uint8_t *out_msg, void *op_cookie,
+                      enum qat_device_gen qat_dev_gen __rte_unused)
+{
+       struct rte_comp_op *op = in_op;
+       struct qat_comp_op_cookie *cookie =
+                       (struct qat_comp_op_cookie *)op_cookie;
+       struct qat_comp_xform *qat_xform = op->private_xform;
+       const uint8_t *tmpl = (uint8_t *)&qat_xform->qat_comp_req_tmpl;
+       struct icp_qat_fw_comp_req *comp_req =
+           (struct icp_qat_fw_comp_req *)out_msg;
+
+       if (unlikely(op->op_type != RTE_COMP_OP_STATELESS)) {
+               QAT_DP_LOG(ERR, "QAT PMD only supports stateless compression "
+                               "operation requests, op (%p) is not a "
+                               "stateless operation.", op);
+               return -EINVAL;
+       }
+
+       rte_mov128(out_msg, tmpl);
+       comp_req->comn_mid.opaque_data = (uint64_t)(uintptr_t)op;
+
+       /* common for sgl and flat buffers */
+       comp_req->comp_pars.comp_len = op->src.length;
+       comp_req->comp_pars.out_buffer_sz = rte_pktmbuf_pkt_len(op->m_dst);
+
+       /* sgl */
+       if (op->m_src->next != NULL || op->m_dst->next != NULL) {
+               if (unlikely(op->m_src->next == NULL ||
+                            op->m_dst->next == NULL)) {
+                       QAT_DP_LOG(ERR, "QAT PMD doesn't support SGL on one "
+                                   "side only: src->next (%p), dst->next (%p)",
+                                   op->m_src->next, op->m_dst->next);
+                       return -EINVAL;
+               }
+
+               int ret = 0;
+
+               ICP_QAT_FW_COMN_PTR_TYPE_SET(comp_req->comn_hdr.comn_req_flags,
+                               QAT_COMN_PTR_TYPE_SGL);
+               ret = qat_sgl_fill_array(op->m_src,
+                               rte_pktmbuf_mtophys_offset(op->m_src,
+                                                       op->src.offset),
+                               &cookie->qat_sgl_src,
+                               op->src.length,
+                               RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS);
+               if (ret) {
+                       QAT_DP_LOG(ERR, "QAT PMD Cannot fill sgl array");
+                       return ret;
+               }
+
+               ret = qat_sgl_fill_array(op->m_dst,
+                               rte_pktmbuf_mtophys_offset(op->m_dst,
+                                                       op->dst.offset),
+                               &cookie->qat_sgl_dst,
+                               comp_req->comp_pars.out_buffer_sz,
+                               RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS);
+               if (ret) {
+                       QAT_DP_LOG(ERR, "QAT PMD Cannot fill sgl array");
+                       return ret;
+               }
+
+               comp_req->comn_mid.src_data_addr =
+                               cookie->qat_sgl_src_phys_addr;
+               comp_req->comn_mid.dest_data_addr =
+                               cookie->qat_sgl_dst_phys_addr;
+               comp_req->comn_mid.src_length = 0;
+               comp_req->comn_mid.dst_length = 0;
+
+       } else {
+               ICP_QAT_FW_COMN_PTR_TYPE_SET(comp_req->comn_hdr.comn_req_flags,
+                               QAT_COMN_PTR_TYPE_FLAT);
+               comp_req->comn_mid.src_length = rte_pktmbuf_data_len(op->m_src);
+               comp_req->comn_mid.dst_length = rte_pktmbuf_data_len(op->m_dst);
+
+               comp_req->comn_mid.src_data_addr =
+                   rte_pktmbuf_mtophys_offset(op->m_src, op->src.offset);
+               comp_req->comn_mid.dest_data_addr =
+                   rte_pktmbuf_mtophys_offset(op->m_dst, op->dst.offset);
+       }
+
+#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
+       QAT_DP_HEXDUMP_LOG(DEBUG, "qat compression message:", comp_req,
+                   sizeof(struct icp_qat_fw_comp_req));
+#endif
+       return 0;
+}
+
+int
+qat_comp_process_response(void **op, uint8_t *resp)
+{
+       struct icp_qat_fw_comn_resp *resp_msg =
+                       (struct icp_qat_fw_comn_resp *)resp;
+       struct rte_comp_op *rx_op = (struct rte_comp_op *)(uintptr_t)
+                       (resp_msg->opaque_data);
+
+#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
+       QAT_DP_HEXDUMP_LOG(DEBUG,  "qat_response:", (uint8_t *)resp_msg,
+                       sizeof(struct icp_qat_fw_comn_resp));
+#endif
+
+       if ((ICP_QAT_FW_COMN_RESP_CMP_STAT_GET(resp_msg->comn_hdr.comn_status) |
+                               ICP_QAT_FW_COMN_RESP_XLAT_STAT_GET(
+                                       resp_msg->comn_hdr.comn_status)) !=
+                               ICP_QAT_FW_COMN_STATUS_FLAG_OK) {
+
+               rx_op->status = RTE_COMP_OP_STATUS_ERROR;
+               rx_op->debug_status =
+                               *((uint16_t *)(&resp_msg->comn_hdr.comn_error));
+       } else {
+               struct qat_comp_xform *qat_xform = rx_op->private_xform;
+               struct qat_comp_res_data *comp_resp =
+                   (struct qat_comp_res_data *)&resp_msg->resrvd;
+
+               rx_op->status = RTE_COMP_OP_STATUS_SUCCESS;
+               rx_op->consumed = comp_resp->consumed;
+               rx_op->produced = comp_resp->produced;
+
+               if (qat_xform->checksum_type != RTE_COMP_CHECKSUM_NONE) {
+                       if (qat_xform->checksum_type == RTE_COMP_CHECKSUM_CRC32)
+                               rx_op->output_chksum = comp_resp->curr_crc;
+                       else if (qat_xform->checksum_type ==
+                                RTE_COMP_CHECKSUM_ADLER32)
+                               rx_op->output_chksum = comp_resp->curr_adler;
+                       else
+                               rx_op->output_chksum = comp_resp->curr_chksum;
+               }
+       }
+       *op = (void *)rx_op;
+
+       return 0;
+}
+
+unsigned int
+qat_comp_xform_size(void)
+{
+       return RTE_ALIGN_CEIL(sizeof(struct qat_comp_xform), 8);
+}
+
+static void qat_comp_create_req_hdr(struct icp_qat_fw_comn_req_hdr *header,
+                                   enum qat_comp_request request)
+{
+       if (request == QAT_COMP_REQUEST_FIXED_COMP_STATELESS)
+               header->service_cmd_id = ICP_QAT_FW_COMP_CMD_STATIC;
+       else if (request == QAT_COMP_REQUEST_DYNAMIC_COMP_STATELESS)
+               header->service_cmd_id = ICP_QAT_FW_COMP_CMD_DYNAMIC;
+       else if (request == QAT_COMP_REQUEST_DECOMPRESS)
+               header->service_cmd_id = ICP_QAT_FW_COMP_CMD_DECOMPRESS;
+
+       header->service_type = ICP_QAT_FW_COMN_REQ_CPM_FW_COMP;
+       header->hdr_flags =
+           ICP_QAT_FW_COMN_HDR_FLAGS_BUILD(ICP_QAT_FW_COMN_REQ_FLAG_SET);
+
+       header->comn_req_flags = ICP_QAT_FW_COMN_FLAGS_BUILD(
+           QAT_COMN_CD_FLD_TYPE_16BYTE_DATA, QAT_COMN_PTR_TYPE_FLAT);
+}
+
+static int qat_comp_create_templates(struct qat_comp_xform *qat_xform,
+                                    const struct rte_memzone *interm_buff_mz,
+                                    const struct rte_comp_xform *xform)
+{
+       struct icp_qat_fw_comp_req *comp_req;
+       int comp_level, algo;
+       int direction = ICP_QAT_HW_COMPRESSION_DIR_COMPRESS;
+
+       if (unlikely(qat_xform == NULL)) {
+               QAT_LOG(ERR, "Session was not created for this device");
+               return -EINVAL;
+       }
+
+       if (qat_xform->qat_comp_request == QAT_COMP_REQUEST_DECOMPRESS) {
+               direction = ICP_QAT_HW_COMPRESSION_DIR_DECOMPRESS;
+               comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_1;
+
+       } else {
+               if (xform->compress.level == RTE_COMP_LEVEL_PMD_DEFAULT)
+                       comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_8;
+               else if (xform->compress.level == 1)
+                       comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_1;
+               else if (xform->compress.level == 2)
+                       comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_4;
+               else if (xform->compress.level == 3)
+                       comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_8;
+               else if (xform->compress.level >= 4 &&
+                        xform->compress.level <= 9)
+                       comp_level = ICP_QAT_HW_COMPRESSION_DEPTH_16;
+               else {
+                       QAT_LOG(ERR, "compression level not supported");
+                       return -EINVAL;
+               }
+       }
+
+       switch (xform->compress.algo) {
+       case RTE_COMP_ALGO_DEFLATE:
+               algo = ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE;
+               break;
+       case RTE_COMP_ALGO_LZS:
+       default:
+               /* RTE_COMP_NULL */
+               QAT_LOG(ERR, "compression algorithm not supported");
+               return -EINVAL;
+       }
+
+       comp_req = &qat_xform->qat_comp_req_tmpl;
+
+       /* Initialize header */
+       qat_comp_create_req_hdr(&comp_req->comn_hdr,
+                                       qat_xform->qat_comp_request);
+
+       comp_req->comn_hdr.serv_specif_flags = ICP_QAT_FW_COMP_FLAGS_BUILD(
+           ICP_QAT_FW_COMP_STATELESS_SESSION,
+           ICP_QAT_FW_COMP_NOT_AUTO_SELECT_BEST,
+           ICP_QAT_FW_COMP_NOT_ENH_AUTO_SELECT_BEST,
+           ICP_QAT_FW_COMP_NOT_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST,
+           ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_USED_AS_INTMD_BUF);
+
+       comp_req->cd_pars.sl.comp_slice_cfg_word[0] =
+           ICP_QAT_HW_COMPRESSION_CONFIG_BUILD(
+               direction,
+               /* In CPM 1.6 only valid mode ! */
+               ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED, algo,
+               /* Translate level to depth */
+               comp_level, ICP_QAT_HW_COMPRESSION_FILE_TYPE_0);
+
+       comp_req->comp_pars.initial_adler = 1;
+       comp_req->comp_pars.initial_crc32 = 0;
+       comp_req->comp_pars.req_par_flags =
+           ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(
+               ICP_QAT_FW_COMP_SOP, ICP_QAT_FW_COMP_EOP,
+               ICP_QAT_FW_COMP_BFINAL, ICP_QAT_FW_COMP_NO_MCA);
+
+       if (qat_xform->qat_comp_request == QAT_COMP_REQUEST_FIXED_COMP_STATELESS
+               || qat_xform->qat_comp_request == QAT_COMP_REQUEST_DECOMPRESS) {
+               ICP_QAT_FW_COMN_NEXT_ID_SET(&comp_req->comp_cd_ctrl,
+                                           ICP_QAT_FW_SLICE_DRAM_WR);
+               ICP_QAT_FW_COMN_CURR_ID_SET(&comp_req->comp_cd_ctrl,
+                                           ICP_QAT_FW_SLICE_COMP);
+       } else if (qat_xform->qat_comp_request ==
+                  QAT_COMP_REQUEST_DYNAMIC_COMP_STATELESS) {
+
+               ICP_QAT_FW_COMN_NEXT_ID_SET(&comp_req->comp_cd_ctrl,
+                                           ICP_QAT_FW_SLICE_XLAT);
+               ICP_QAT_FW_COMN_CURR_ID_SET(&comp_req->comp_cd_ctrl,
+                                           ICP_QAT_FW_SLICE_COMP);
+
+               ICP_QAT_FW_COMN_NEXT_ID_SET(&comp_req->u2.xlt_cd_ctrl,
+                                           ICP_QAT_FW_SLICE_DRAM_WR);
+               ICP_QAT_FW_COMN_CURR_ID_SET(&comp_req->u2.xlt_cd_ctrl,
+                                           ICP_QAT_FW_SLICE_XLAT);
+
+               comp_req->u1.xlt_pars.inter_buff_ptr =
+                               interm_buff_mz->phys_addr;
+       }
+
+#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
+       QAT_DP_HEXDUMP_LOG(DEBUG, "qat compression message template:", comp_req,
+                   sizeof(struct icp_qat_fw_comp_req));
+#endif
+       return 0;
+}
+
+/**
+ * Create driver private_xform data.
+ *
+ * @param dev
+ *   Compressdev device
+ * @param xform
+ *   xform data from application
+ * @param private_xform
+ *   ptr where handle of pmd's private_xform data should be stored
+ * @return
+ *  - if successful returns 0
+ *    and valid private_xform handle
+ *  - <0 in error cases
+ *  - Returns -EINVAL if input parameters are invalid.
+ *  - Returns -ENOTSUP if comp device does not support the comp transform.
+ *  - Returns -ENOMEM if the private_xform could not be allocated.
+ */
+int
+qat_comp_private_xform_create(struct rte_compressdev *dev,
+                             const struct rte_comp_xform *xform,
+                             void **private_xform)
+{
+       struct qat_comp_dev_private *qat = dev->data->dev_private;
+
+       if (unlikely(private_xform == NULL)) {
+               QAT_LOG(ERR, "QAT: private_xform parameter is NULL");
+               return -EINVAL;
+       }
+       if (unlikely(qat->xformpool == NULL)) {
+               QAT_LOG(ERR, "QAT device has no private_xform mempool");
+               return -ENOMEM;
+       }
+       if (rte_mempool_get(qat->xformpool, private_xform)) {
+               QAT_LOG(ERR, "Couldn't get object from qat xform mempool");
+               return -ENOMEM;
+       }
+
+       struct qat_comp_xform *qat_xform =
+                       (struct qat_comp_xform *)*private_xform;
+
+       if (xform->type == RTE_COMP_COMPRESS) {
+               if (xform->compress.deflate.huffman == RTE_COMP_HUFFMAN_FIXED ||
+                 ((xform->compress.deflate.huffman == RTE_COMP_HUFFMAN_DEFAULT)
+                                  && qat->interm_buff_mz == NULL))
+
+                       qat_xform->qat_comp_request =
+                                       QAT_COMP_REQUEST_FIXED_COMP_STATELESS;
+               else if ((xform->compress.deflate.huffman ==
+                                               RTE_COMP_HUFFMAN_DYNAMIC ||
+                       xform->compress.deflate.huffman ==
+                                               RTE_COMP_HUFFMAN_DEFAULT) &&
+                       qat->interm_buff_mz != NULL)
+
+                       qat_xform->qat_comp_request =
+                                       QAT_COMP_REQUEST_DYNAMIC_COMP_STATELESS;
+               else {
+                       QAT_LOG(ERR,
+             "IM buffers needed for dynamic deflate. Set size in config file");
+                       return -EINVAL;
+               }
+
+       } else {
+               qat_xform->qat_comp_request = QAT_COMP_REQUEST_DECOMPRESS;
+       }
+
+       qat_xform->checksum_type = xform->compress.chksum;
+
+       if (qat_comp_create_templates(qat_xform, qat->interm_buff_mz, xform)) {
+               QAT_LOG(ERR, "QAT: Problem with setting compression");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/**
+ * Free driver private_xform data.
+ *
+ * @param dev
+ *   Compressdev device
+ * @param private_xform
+ *   handle of pmd's private_xform data
+ * @return
+ *  - 0 if successful
+ *  - <0 in error cases
+ *  - Returns -EINVAL if input parameters are invalid.
+ */
+int
+qat_comp_private_xform_free(struct rte_compressdev *dev __rte_unused,
+                           void *private_xform)
+{
+       struct qat_comp_xform *qat_xform =
+                       (struct qat_comp_xform *)private_xform;
+
+       if (qat_xform) {
+               memset(qat_xform, 0, qat_comp_xform_size());
+               struct rte_mempool *mp = rte_mempool_from_obj(qat_xform);
+
+               rte_mempool_put(mp, qat_xform);
+               return 0;
+       }
+       return -EINVAL;
+}
diff --git a/drivers/compress/qat/qat_comp.h b/drivers/compress/qat/qat_comp.h
new file mode 100644
index 0000000..ba3beec
--- /dev/null
+++ b/drivers/compress/qat/qat_comp.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2015-2018 Intel Corporation
+ */
+
+#ifndef _QAT_COMP_H_
+#define _QAT_COMP_H_
+
+#ifdef RTE_LIBRTE_COMPRESSDEV
+
+#include <rte_compressdev.h>
+#include <rte_compressdev_pmd.h>
+
+#include "qat_common.h"
+#include "icp_qat_hw.h"
+#include "icp_qat_fw_comp.h"
+#include "icp_qat_fw_la.h"
+
+/*
+ * This macro rounds up a number to a be a multiple of
+ * the alignment when the alignment is a power of 2
+ */
+#define ALIGN_POW2_ROUNDUP(num, align) \
+       (((num) + (align) - 1) & ~((align) - 1))
+#define QAT_64_BYTE_ALIGN_MASK (~0x3f)
+#define QAT_64_BYTE_ALIGN (64)
+#define QAT_NUM_BUFS_IN_IM_SGL 2
+/* Use correct Deflate terminology */
+#define QAT_COMP_REQUEST_FIXED_COMP_STATELESS 
QAT_COMP_REQUEST_STATIC_COMP_STATELESS
+
+
+struct array_of_ptrs {
+       phys_addr_t pointer[0];
+};
+
+struct qat_inter_sgl {
+       qat_sgl_hdr;
+       struct qat_flat_buf buffers[QAT_NUM_BUFS_IN_IM_SGL];
+} __rte_packed __rte_cache_aligned;
+
+struct qat_comp_sgl {
+       qat_sgl_hdr;
+       struct qat_flat_buf buffers[RTE_PMD_QAT_COMP_SGL_MAX_SEGMENTS];
+} __rte_packed __rte_cache_aligned;
+
+struct qat_comp_op_cookie {
+       struct qat_comp_sgl qat_sgl_src;
+       struct qat_comp_sgl qat_sgl_dst;
+       phys_addr_t qat_sgl_src_phys_addr;
+       phys_addr_t qat_sgl_dst_phys_addr;
+};
+
+struct qat_comp_xform {
+       struct icp_qat_fw_comp_req qat_comp_req_tmpl;
+       enum qat_comp_request qat_comp_request;
+       enum rte_comp_checksum_type checksum_type;
+};
+
+int
+qat_comp_build_request(void *in_op, uint8_t *out_msg, void *op_cookie,
+                      enum qat_device_gen qat_dev_gen __rte_unused);
+
+int
+qat_comp_process_response(void **op, uint8_t *resp);
+
+
+int
+qat_comp_private_xform_create(struct rte_compressdev *dev,
+                             const struct rte_comp_xform *xform,
+                             void **private_xform);
+
+int
+qat_comp_private_xform_free(struct rte_compressdev *dev, void *private_xform);
+
+unsigned int
+qat_comp_xform_size(void);
+
+#endif
+#endif
diff --git a/drivers/compress/qat/qat_comp_pmd.c 
b/drivers/compress/qat/qat_comp_pmd.c
new file mode 100644
index 0000000..6006e03
--- /dev/null
+++ b/drivers/compress/qat/qat_comp_pmd.c
@@ -0,0 +1,479 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2015-2018 Intel Corporation
+ */
+
+#include <rte_bus_pci.h>
+#include <rte_common.h>
+#include <rte_dev.h>
+#include <rte_malloc.h>
+#include <rte_pci.h>
+
+#include "qat_logs.h"
+#include "qat_comp.h"
+#include "qat_comp_pmd.h"
+
+uint8_t compressdev_qat_driver_id;
+
+static const struct rte_compressdev_capabilities qat_comp_gen_capabilities[] = 
{
+       {/* COMPRESSION - deflate */
+        .algo = RTE_COMP_ALGO_DEFLATE,
+        .comp_feature_flags = RTE_COMP_FF_MBUF_SCATTER_GATHER |
+                              RTE_COMP_FF_MULTI_PKT_CHECKSUM |
+                              RTE_COMP_FF_CRC32_ADLER32_CHECKSUM,
+        .window_size = {.min = 15, .max = 15, .increment = 0} },
+       {RTE_COMP_ALGO_LIST_END, 0, {0, 0, 0} } };
+
+static void
+qat_comp_stats_get(struct rte_compressdev *dev,
+               struct rte_compressdev_stats *stats)
+{
+       struct qat_common_stats qat_stats = {0};
+       struct qat_comp_dev_private *qat_priv;
+
+       if (stats == NULL || dev == NULL) {
+               QAT_LOG(ERR, "invalid ptr: stats %p, dev %p", stats, dev);
+               return;
+       }
+       qat_priv = dev->data->dev_private;
+
+       qat_stats_get(qat_priv->qat_dev, &qat_stats, QAT_SERVICE_COMPRESSION);
+       stats->enqueued_count = qat_stats.enqueued_count;
+       stats->dequeued_count = qat_stats.dequeued_count;
+       stats->enqueue_err_count = qat_stats.enqueue_err_count;
+       stats->dequeue_err_count = qat_stats.dequeue_err_count;
+}
+
+static void
+qat_comp_stats_reset(struct rte_compressdev *dev)
+{
+       struct qat_comp_dev_private *qat_priv;
+
+       if (dev == NULL) {
+               QAT_LOG(ERR, "invalid compressdev ptr %p", dev);
+               return;
+       }
+       qat_priv = dev->data->dev_private;
+
+       qat_stats_reset(qat_priv->qat_dev, QAT_SERVICE_COMPRESSION);
+
+}
+
+static int
+qat_comp_qp_release(struct rte_compressdev *dev, uint16_t queue_pair_id)
+{
+       struct qat_comp_dev_private *qat_private = dev->data->dev_private;
+
+       QAT_LOG(DEBUG, "Release comp qp %u on device %d",
+                               queue_pair_id, dev->data->dev_id);
+
+       qat_private->qat_dev->qps_in_use[QAT_SERVICE_COMPRESSION][queue_pair_id]
+                                               = NULL;
+
+       return qat_qp_release((struct qat_qp **)
+                       &(dev->data->queue_pairs[queue_pair_id]));
+}
+
+static int
+qat_comp_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
+                 uint32_t max_inflight_ops, int socket_id)
+{
+       struct qat_qp *qp;
+       int ret = 0;
+       uint32_t i;
+       struct qat_qp_config qat_qp_conf;
+
+       struct qat_qp **qp_addr =
+                       (struct qat_qp **)&(dev->data->queue_pairs[qp_id]);
+       struct qat_comp_dev_private *qat_private = dev->data->dev_private;
+       const struct qat_qp_hw_data *comp_hw_qps =
+                       qat_gen_config[qat_private->qat_dev->qat_dev_gen]
+                                     .qp_hw_data[QAT_SERVICE_COMPRESSION];
+       const struct qat_qp_hw_data *qp_hw_data = comp_hw_qps + qp_id;
+
+       /* If qp is already in use free ring memory and qp metadata. */
+       if (*qp_addr != NULL) {
+               ret = qat_comp_qp_release(dev, qp_id);
+               if (ret < 0)
+                       return ret;
+       }
+       if (qp_id >= qat_qps_per_service(comp_hw_qps,
+                                        QAT_SERVICE_COMPRESSION)) {
+               QAT_LOG(ERR, "qp_id %u invalid for this device", qp_id);
+               return -EINVAL;
+       }
+
+       qat_qp_conf.hw = qp_hw_data;
+       qat_qp_conf.build_request = qat_comp_build_request;
+       qat_qp_conf.cookie_size = sizeof(struct qat_comp_op_cookie);
+       qat_qp_conf.nb_descriptors = max_inflight_ops;
+       qat_qp_conf.socket_id = socket_id;
+       qat_qp_conf.service_str = "comp";
+
+       ret = qat_qp_setup(qat_private->qat_dev, qp_addr, qp_id, &qat_qp_conf);
+       if (ret != 0)
+               return ret;
+
+       /* store a link to the qp in the qat_pci_device */
+       qat_private->qat_dev->qps_in_use[QAT_SERVICE_COMPRESSION][qp_id]
+                                                       = *qp_addr;
+
+       qp = (struct qat_qp *)*qp_addr;
+
+       for (i = 0; i < qp->nb_descriptors; i++) {
+
+               struct qat_comp_op_cookie *cookie =
+                               qp->op_cookies[i];
+
+               cookie->qat_sgl_src_phys_addr =
+                               rte_mempool_virt2iova(cookie) +
+                               offsetof(struct qat_comp_op_cookie,
+                               qat_sgl_src);
+
+               cookie->qat_sgl_dst_phys_addr =
+                               rte_mempool_virt2iova(cookie) +
+                               offsetof(struct qat_comp_op_cookie,
+                               qat_sgl_dst);
+       }
+
+       return ret;
+}
+
+static const struct rte_memzone *
+qat_comp_setup_inter_buffers(struct qat_comp_dev_private *comp_dev,
+                             uint32_t buff_size)
+{
+       char inter_buff_mz_name[RTE_MEMZONE_NAMESIZE];
+       const struct rte_memzone *memzone;
+       uint8_t *mz_start = NULL;
+       phys_addr_t mz_start_phys = 0;
+       struct array_of_ptrs *array_of_pointers;
+       int size_of_ptr_array;
+       uint32_t full_size;
+       uint32_t offset_of_sgls, offset_of_flat_buffs = 0;
+       int i;
+       int num_im_sgls = qat_gen_config[comp_dev->qat_dev->qat_dev_gen].
+                                               comp_num_im_bufs_required;
+
+       QAT_LOG(DEBUG, "QAT COMP device %s needs %d sgls",
+                               comp_dev->qat_dev->name, num_im_sgls);
+       snprintf(inter_buff_mz_name, RTE_MEMZONE_NAMESIZE,
+                               "%s_inter_buff", comp_dev->qat_dev->name);
+       memzone = rte_memzone_lookup(inter_buff_mz_name);
+       if (memzone != NULL) {
+               QAT_LOG(DEBUG, "QAT COMP im buffer memzone created already");
+               return memzone;
+       }
+
+       /* Create a memzone to hold intermediate buffers and associated
+        * meta-data needed by the firmware. The memzone contains:
+        *  - a list of num_im_sgls physical pointers to sgls
+        *  - the num_im_sgl sgl structures, each pointing to 2 flat buffers
+        *  - the flat buffers: num_im_sgl * 2
+        * where num_im_sgls depends on the hardware generation of the device
+        */
+
+       size_of_ptr_array = num_im_sgls * sizeof(phys_addr_t);
+       offset_of_sgls = (size_of_ptr_array + (~QAT_64_BYTE_ALIGN_MASK))
+                       & QAT_64_BYTE_ALIGN_MASK;
+       offset_of_flat_buffs =
+           offset_of_sgls + num_im_sgls * sizeof(struct qat_inter_sgl);
+       full_size = offset_of_flat_buffs +
+                       num_im_sgls * buff_size * QAT_NUM_BUFS_IN_IM_SGL;
+
+       memzone = rte_memzone_reserve_aligned(inter_buff_mz_name, full_size,
+                       comp_dev->compressdev->data->socket_id,
+                       RTE_MEMZONE_2MB, QAT_64_BYTE_ALIGN);
+       if (memzone == NULL) {
+               QAT_LOG(ERR, "Can't allocate intermediate buffers"
+                               " for device %s", comp_dev->qat_dev->name);
+               return NULL;
+       }
+
+       mz_start = (uint8_t *)memzone->addr;
+       mz_start_phys = memzone->phys_addr;
+       QAT_LOG(DEBUG, "Memzone %s: addr = %p, phys = %lx, size required %d,"
+                       "size created %ld",
+                       inter_buff_mz_name, mz_start, mz_start_phys,
+                       full_size, memzone->len);
+
+       array_of_pointers = (struct array_of_ptrs *)mz_start;
+       for (i = 0; i < num_im_sgls; i++) {
+               uint32_t curr_sgl_offset =
+                   offset_of_sgls + i * sizeof(struct qat_inter_sgl);
+               struct qat_inter_sgl *sgl =
+                   (struct qat_inter_sgl *)(mz_start + curr_sgl_offset);
+               array_of_pointers->pointer[i] = mz_start_phys + curr_sgl_offset;
+
+               sgl->num_bufs = QAT_NUM_BUFS_IN_IM_SGL;
+               sgl->num_mapped_bufs = 0;
+               sgl->resrvd = 0;
+               sgl->buffers[0].addr = mz_start_phys + offset_of_flat_buffs +
+                               i * buff_size * QAT_NUM_BUFS_IN_IM_SGL;
+               sgl->buffers[1].addr = mz_start_phys + offset_of_flat_buffs +
+                               buff_size * (QAT_NUM_BUFS_IN_IM_SGL * i + 1);
+               sgl->buffers[0].len = sgl->buffers[1].len = buff_size;
+               sgl->buffers[0].resrvd = sgl->buffers[1].resrvd = 0;
+
+               QAT_LOG(DEBUG, "  : array_of_pointers->pointer[i]"
+                           "= %lx", array_of_pointers->pointer[i]);
+               QAT_LOG(DEBUG, "  : sgl[%i] = %p", i, sgl);
+               QAT_LOG(DEBUG, "  : sgl->buffers[0].addr = %lx, len=%d",
+                               sgl->buffers[0].addr, sgl->buffers[0].len);
+               QAT_LOG(DEBUG, "  : sgl->buffers[1].addr = %lx, len=%d",
+                               sgl->buffers[1].addr, sgl->buffers[1].len);
+       }
+       return memzone;
+}
+
+static struct rte_mempool *
+qat_comp_create_xform_pool(struct qat_comp_dev_private *comp_dev,
+                             uint32_t num_elements)
+{
+       char xform_pool_name[RTE_MEMPOOL_NAMESIZE];
+       struct rte_mempool *mp;
+
+       snprintf(xform_pool_name, RTE_MEMPOOL_NAMESIZE,
+                       "%s_xforms", comp_dev->qat_dev->name);
+
+       QAT_LOG(DEBUG, "xformpool: %s", xform_pool_name);
+       mp = rte_mempool_lookup(xform_pool_name);
+
+       if (mp != NULL) {
+               QAT_LOG(DEBUG, "xformpool already created");
+               if (mp->size != num_elements) {
+                       QAT_LOG(DEBUG, "xformpool wrong size - delete it");
+                       rte_mempool_free(mp);
+                       mp = NULL;
+                       comp_dev->xformpool = NULL;
+               }
+       }
+
+       if (mp == NULL)
+               mp = rte_mempool_create(xform_pool_name,
+                               num_elements,
+                               qat_comp_xform_size(), 0, 0,
+                               NULL, NULL, NULL, NULL, rte_socket_id(),
+                               0);
+       if (mp == NULL) {
+               QAT_LOG(ERR, "Err creating mempool %s w %d elements of size %d",
+                       xform_pool_name, num_elements, qat_comp_xform_size());
+               return NULL;
+       }
+
+       return mp;
+}
+
+static void
+_qat_comp_dev_config_clear(struct qat_comp_dev_private *comp_dev)
+{
+       /* Free intermediate buffers */
+       if (comp_dev->interm_buff_mz) {
+               rte_memzone_free(comp_dev->interm_buff_mz);
+               comp_dev->interm_buff_mz = NULL;
+       }
+       /* Free private_xform pool */
+       if (comp_dev->xformpool) {
+               /* Free internal mempool for private xforms */
+               rte_mempool_free(comp_dev->xformpool);
+               comp_dev->xformpool = NULL;
+       }
+}
+
+static int
+qat_comp_dev_config(struct rte_compressdev *dev,
+               struct rte_compressdev_config *config)
+{
+       struct qat_comp_dev_private *comp_dev = dev->data->dev_private;
+       int ret = 0;
+
+       if (config->max_nb_streams != 0) {
+               QAT_LOG(ERR,
+       "QAT device does not support STATEFUL so max_nb_streams must be 0");
+               return -EINVAL;
+       }
+
+       if (RTE_PMD_QAT_COMP_IM_BUFFER_SIZE == 0) {
+               QAT_LOG(WARNING,
+                       "RTE_PMD_QAT_COMP_IM_BUFFER_SIZE = 0 in config file, so"
+                       " QAT device can't be used for Dynamic Deflate. "
+                       "Did you really intend to do this?");
+       } else {
+               comp_dev->interm_buff_mz =
+                               qat_comp_setup_inter_buffers(comp_dev,
+                                       RTE_PMD_QAT_COMP_IM_BUFFER_SIZE);
+               if (comp_dev->interm_buff_mz == NULL) {
+                       ret = -ENOMEM;
+                       goto error_out;
+               }
+       }
+
+       comp_dev->xformpool = qat_comp_create_xform_pool(comp_dev,
+                                       config->max_nb_priv_xforms);
+       if (comp_dev->xformpool == NULL) {
+
+               ret = -ENOMEM;
+               goto error_out;
+       }
+       return 0;
+
+error_out:
+       _qat_comp_dev_config_clear(comp_dev);
+       return ret;
+}
+
+static int
+qat_comp_dev_start(struct rte_compressdev *dev __rte_unused)
+{
+       return 0;
+}
+
+static void
+qat_comp_dev_stop(struct rte_compressdev *dev __rte_unused)
+{
+
+}
+
+static int
+qat_comp_dev_close(struct rte_compressdev *dev)
+{
+       int i;
+       int ret = 0;
+       struct qat_comp_dev_private *comp_dev = dev->data->dev_private;
+
+       for (i = 0; i < dev->data->nb_queue_pairs; i++) {
+               ret = qat_comp_qp_release(dev, i);
+               if (ret < 0)
+                       return ret;
+       }
+
+       _qat_comp_dev_config_clear(comp_dev);
+
+       return ret;
+}
+
+static void
+qat_comp_dev_info_get(struct rte_compressdev *dev,
+                       struct rte_compressdev_info *info)
+{
+       struct qat_comp_dev_private *comp_dev = dev->data->dev_private;
+       const struct qat_qp_hw_data *comp_hw_qps =
+               qat_gen_config[comp_dev->qat_dev->qat_dev_gen]
+                             .qp_hw_data[QAT_SERVICE_COMPRESSION];
+
+       if (info != NULL) {
+               info->max_nb_queue_pairs =
+                       qat_qps_per_service(comp_hw_qps,
+                                           QAT_SERVICE_COMPRESSION);
+               info->feature_flags = dev->feature_flags;
+               info->capabilities = comp_dev->qat_dev_capabilities;
+       }
+}
+
+static uint16_t
+qat_comp_pmd_enqueue_op_burst(void *qp, struct rte_comp_op **ops,
+               uint16_t nb_ops)
+{
+       return qat_enqueue_op_burst(qp, (void **)ops, nb_ops);
+}
+
+static uint16_t
+qat_comp_pmd_dequeue_op_burst(void *qp, struct rte_comp_op **ops,
+                             uint16_t nb_ops)
+{
+       return qat_dequeue_op_burst(qp, (void **)ops, nb_ops);
+}
+
+static struct rte_compressdev_ops compress_qat_ops = {
+
+       /* Device related operations */
+       .dev_configure          = qat_comp_dev_config,
+       .dev_start              = qat_comp_dev_start,
+       .dev_stop               = qat_comp_dev_stop,
+       .dev_close              = qat_comp_dev_close,
+       .dev_infos_get          = qat_comp_dev_info_get,
+
+       .stats_get              = qat_comp_stats_get,
+       .stats_reset            = qat_comp_stats_reset,
+       .queue_pair_setup       = qat_comp_qp_setup,
+       .queue_pair_release     = qat_comp_qp_release,
+
+       /* Compression related operations */
+       .private_xform_create   = qat_comp_private_xform_create,
+       .private_xform_free     = qat_comp_private_xform_free
+};
+
+int
+qat_comp_dev_create(struct qat_pci_device *qat_pci_dev)
+{
+       struct rte_compressdev_pmd_init_params init_params = {
+               .name = "",
+               .socket_id = qat_pci_dev->pci_dev->device.numa_node,
+       };
+       char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
+       struct rte_compressdev *compressdev;
+       struct qat_comp_dev_private *comp_dev;
+
+       snprintf(name, RTE_COMPRESSDEV_NAME_MAX_LEN, "%s_%s",
+                       qat_pci_dev->name, "comp");
+       QAT_LOG(DEBUG, "Creating QAT COMP device %s", name);
+
+       compressdev = rte_compressdev_pmd_create(name,
+                       &qat_pci_dev->pci_dev->device,
+                       sizeof(struct qat_comp_dev_private),
+                       &init_params);
+
+       if (compressdev == NULL)
+               return -ENODEV;
+
+       compressdev->driver_id = compressdev_qat_driver_id;
+       compressdev->dev_ops = &compress_qat_ops;
+
+       compressdev->enqueue_burst = qat_comp_pmd_enqueue_op_burst;
+       compressdev->dequeue_burst = qat_comp_pmd_dequeue_op_burst;
+
+       compressdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;
+
+       comp_dev = compressdev->data->dev_private;
+       comp_dev->qat_dev = qat_pci_dev;
+       comp_dev->compressdev = compressdev;
+       qat_pci_dev->comp_dev = comp_dev;
+
+       switch (qat_pci_dev->qat_dev_gen) {
+       case QAT_GEN1:
+       case QAT_GEN2:
+               comp_dev->qat_dev_capabilities = qat_comp_gen_capabilities;
+               break;
+       default:
+               comp_dev->qat_dev_capabilities = qat_comp_gen_capabilities;
+               QAT_LOG(DEBUG,
+                       "QAT gen %d capabilities unknown, default to GEN1",
+                                       qat_pci_dev->qat_dev_gen);
+               break;
+       }
+
+       QAT_LOG(DEBUG,
+                   "Created QAT COMP device %s as compressdev instance %d",
+                       name, compressdev->data->dev_id);
+       return 0;
+}
+
+int
+qat_comp_dev_destroy(struct qat_pci_device *qat_pci_dev)
+{
+       struct qat_comp_dev_private *comp_dev;
+
+       if (qat_pci_dev == NULL)
+               return -ENODEV;
+
+       comp_dev = qat_pci_dev->comp_dev;
+       if (comp_dev == NULL)
+               return 0;
+
+       /* clean up any resources used by the device */
+       qat_comp_dev_close(comp_dev->compressdev);
+
+       rte_compressdev_pmd_destroy(comp_dev->compressdev);
+       qat_pci_dev->comp_dev = NULL;
+
+       return 0;
+}
diff --git a/drivers/compress/qat/qat_comp_pmd.h 
b/drivers/compress/qat/qat_comp_pmd.h
new file mode 100644
index 0000000..11ea467
--- /dev/null
+++ b/drivers/compress/qat/qat_comp_pmd.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2015-2018 Intel Corporation
+ */
+
+#ifndef _QAT_COMP_PMD_H_
+#define _QAT_COMP_PMD_H_
+
+#ifdef RTE_LIBRTE_COMPRESSDEV
+
+#include <rte_compressdev.h>
+#include <rte_compressdev_pmd.h>
+
+#include "qat_device.h"
+
+/**< Intel(R) QAT Compression PMD device name */
+#define COMPRESSDEV_NAME_QAT_PMD       comp_qat
+
+/** private data structure for a QAT compression device.
+ * This QAT device is a device offering only a compression service,
+ * there can be one of these on each qat_pci_device (VF).
+ */
+struct qat_comp_dev_private {
+       struct qat_pci_device *qat_dev;
+       /**< The qat pci device hosting the service */
+       struct rte_compressdev *compressdev;
+       /**< The pointer to this compression device structure */
+       const struct rte_compressdev_capabilities *qat_dev_capabilities;
+       /* QAT device compression capabilities */
+       const struct rte_memzone *interm_buff_mz;
+       struct rte_mempool *xformpool;
+};
+
+int
+qat_comp_dev_create(struct qat_pci_device *qat_pci_dev);
+
+int
+qat_comp_dev_destroy(struct qat_pci_device *qat_pci_dev);
+
+#endif
+#endif /* _QAT_COMP_PMD_H_ */
diff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c
index 17d63eb..3e3c3ac 100644
--- a/drivers/crypto/qat/qat_sym.c
+++ b/drivers/crypto/qat/qat_sym.c
@@ -495,8 +495,9 @@
                ICP_QAT_FW_COMN_PTR_TYPE_SET(qat_req->comn_hdr.comn_req_flags,
                                QAT_COMN_PTR_TYPE_SGL);
                ret = qat_sgl_fill_array(op->sym->m_src, src_buf_start,
-                               &cookie->qat_sgl_src,
-                               qat_req->comn_mid.src_length);
+                                       &cookie->qat_sgl_src,
+                                       qat_req->comn_mid.src_length,
+                                       QAT_SYM_SGL_MAX_NUMBER);
 
                if (unlikely(ret)) {
                        QAT_DP_LOG(ERR, "QAT PMD Cannot fill sgl array");
@@ -509,9 +510,10 @@
                                cookie->qat_sgl_src_phys_addr;
                else {
                        ret = qat_sgl_fill_array(op->sym->m_dst,
-                                       dst_buf_start,
-                                       &cookie->qat_sgl_dst,
-                                               qat_req->comn_mid.dst_length);
+                                                dst_buf_start,
+                                                &cookie->qat_sgl_dst,
+                                                qat_req->comn_mid.dst_length,
+                                                QAT_SYM_SGL_MAX_NUMBER);
 
                        if (unlikely(ret)) {
                                QAT_DP_LOG(ERR, "QAT PMD can't fill sgl array");
diff --git a/drivers/crypto/qat/qat_sym.h b/drivers/crypto/qat/qat_sym.h
index 3c8ec5b..53c3275 100644
--- a/drivers/crypto/qat/qat_sym.h
+++ b/drivers/crypto/qat/qat_sym.h
@@ -22,11 +22,21 @@
  */
 #define BPI_MAX_ENCR_IV_LEN ICP_QAT_HW_AES_BLK_SZ
 
+/*
+ * Maximum number of SGL entries
+ */
+#define QAT_SYM_SGL_MAX_NUMBER 16
+
 struct qat_sym_session;
 
+struct qat_sym_sgl {
+       qat_sgl_hdr;
+       struct qat_flat_buf buffers[QAT_SYM_SGL_MAX_NUMBER];
+} __rte_packed __rte_cache_aligned;
+
 struct qat_sym_op_cookie {
-       struct qat_sgl qat_sgl_src;
-       struct qat_sgl qat_sgl_dst;
+       struct qat_sym_sgl qat_sgl_src;
+       struct qat_sym_sgl qat_sgl_dst;
        phys_addr_t qat_sgl_src_phys_addr;
        phys_addr_t qat_sgl_dst_phys_addr;
 };
-- 
1.7.0.7

Reply via email to