[V3 PATCH 15/16] crypto/nx: Get NX capabilities for GZIP coprocessor type

Haren Myneni
2021-04-17T21:13:05Z

phyp provides NX capabilities which gives recommended minimum
compression / decompression length and maximum request buffer size
in bytes.

Changes to get NX overall capabilities which points to the specific
features phyp supports. Then retrieve NXGZIP specific capabilities.

Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
drivers/crypto/nx/nx-common-pseries.c | 83 +++++++++++++++++++++++++++
1 file changed, 83 insertions(+)

diff --git a/drivers/crypto/nx/nx-common-pseries.c b/drivers/crypto/nx/nx-common-pseries.c
index 9a40fca8a9e6..49224870d05e 100644
--- a/drivers/crypto/nx/nx-common-pseries.c
+++ b/drivers/crypto/nx/nx-common-pseries.c
@@ -9,6 +9,7 @@
*/

#include <asm/vio.h>
+#include <asm/hvcall.h>
#include <asm/vas.h>

#include "nx-842.h"
@@ -20,6 +21,24 @@ MODULE_DESCRIPTION("842 H/W Compression driver for IBM Power processors");
MODULE_ALIAS_CRYPTO("842");
MODULE_ALIAS_CRYPTO("842-nx");

+struct nx_ct_capabs_be {
+ __be64 descriptor;
+ __be64 req_max_processed_len; /* Max bytes in one GZIP request */
+ __be64 min_compress_len; /* Min compression size in bytes */
+ __be64 min_decompress_len; /* Min decompression size in bytes */
+} __packed __aligned(0x1000);
+
+struct nx_ct_capabs {
+ char name[VAS_DESCR_LEN + 1];
+ u64 descriptor;
+ u64 req_max_processed_len; /* Max bytes in one GZIP request */
+ u64 min_compress_len; /* Min compression in bytes */
+ u64 min_decompress_len; /* Min decompression in bytes */
+};
+
+u64 capab_feat = 0;
+struct nx_ct_capabs nx_ct_capab;
+
static struct nx842_constraints nx842_pseries_constraints = {
.alignment = DDE_BUFFER_ALIGN,
.multiple = DDE_BUFFER_LAST_MULT,
@@ -1066,6 +1085,66 @@ static void nx842_remove(struct vio_dev *viodev)
kfree(old_devdata);
}

+/*
+ * Get NX capabilities from pHyp.
+ * Only NXGZIP capabilities are available right now and these values
+ * are available through sysfs.
+ */
+static void __init nxct_get_capabilities(void)
+{
+ struct vas_all_capabs_be *capabs_be;
+ struct nx_ct_capabs_be *nxc_be;
+ int rc;
+
+ capabs_be = kmalloc(sizeof(*capabs_be), GFP_KERNEL);
+ if (!capabs_be)
+ return;
+ /*
+ * Get NX overall capabilities with feature type=0
+ */
+ rc = plpar_vas_query_capabilities(H_QUERY_NX_CAPABILITIES, 0,
+ (u64)virt_to_phys(capabs_be));
+ if (rc)
+ goto out;
+
+ capab_feat = be64_to_cpu(capabs_be->feat_type);
+ /*
+ * NX-GZIP feature available
+ */
+ if (capab_feat & VAS_NX_GZIP_FEAT_BIT) {
+ nxc_be = kmalloc(sizeof(*nxc_be), GFP_KERNEL);
+ if (!nxc_be)
+ goto out;
+ /*
+ * Get capabilities for NX-GZIP feature
+ */
+ rc = plpar_vas_query_capabilities(H_QUERY_NX_CAPABILITIES,
+ VAS_NX_GZIP_FEAT,
+ (u64)virt_to_phys(nxc_be));
+ } else {
+ pr_err("NX-GZIP feature is not available\n");
+ rc = -EINVAL;
+ }
+
+ if (!rc) {
+ snprintf(nx_ct_capab.name, VAS_DESCR_LEN + 1, "%.8s",
+ (char *)&nxc_be->descriptor);
+ nx_ct_capab.descriptor = be64_to_cpu(nxc_be->descriptor);
+ nx_ct_capab.req_max_processed_len =
+ be64_to_cpu(nxc_be->req_max_processed_len);
+ nx_ct_capab.min_compress_len =
+ be64_to_cpu(nxc_be->min_compress_len);
+ nx_ct_capab.min_decompress_len =
+ be64_to_cpu(nxc_be->min_decompress_len);
+ } else {
+ capab_feat = 0;
+ }
+
+ kfree(nxc_be);
+out:
+ kfree(capabs_be);
+}
+
static const struct vio_device_id nx842_vio_driver_ids[] = {
{"ibm,compression-v1", "ibm,compression"},
{"", ""},
@@ -1093,6 +1172,10 @@ static int __init nx842_pseries_init(void)
return -ENOMEM;

RCU_INIT_POINTER(devdata, new_devdata);
+ /*
+ * Get NX capabilities from pHyp which is used for NX-GZIP.
+ */
+ nxct_get_capabilities();

ret = vio_register_driver(&nx842_vio_driver);
if (ret) {
--
2.18.2