Skip to content

Commit

Permalink
crypto: nx - add NX-842 platform frontend driver
Browse files Browse the repository at this point in the history
Add NX-842 frontend that allows using either the pSeries platform or
PowerNV platform driver (to be added by later patch) for the NX-842
hardware.  Update the MAINTAINERS file to include the new filenames.
Update Kconfig files to clarify titles and descriptions, and correct
dependencies.

Signed-off-by: Dan Streetman <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
ddstreet authored and herbertx committed May 11, 2015
1 parent fdd05e4 commit 7011a12
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 49 deletions.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4861,7 +4861,7 @@ F: drivers/crypto/nx/
IBM Power 842 compression accelerator
M: Dan Streetman <[email protected]>
S: Supported
F: drivers/crypto/nx/nx-842.c
F: drivers/crypto/nx/nx-842*
F: include/linux/nx842.h
F: include/linux/sw842.h
F: crypto/842.c
Expand Down
10 changes: 6 additions & 4 deletions drivers/crypto/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -330,11 +330,13 @@ config CRYPTO_DEV_S5P
algorithms execution.

config CRYPTO_DEV_NX
bool "Support for IBM Power7+ in-Nest cryptographic acceleration"
depends on PPC64 && IBMVIO && !CPU_LITTLE_ENDIAN
default n
bool "Support for IBM PowerPC Nest (NX) cryptographic acceleration"
depends on PPC64
help
Support for Power7+ in-Nest cryptographic acceleration.
This enables support for the NX hardware cryptographic accelerator
coprocessor that is in IBM PowerPC P7+ or later processors. This
does not actually enable any drivers, it only allows you to select
which acceleration type (encryption and/or compression) to enable.

if CRYPTO_DEV_NX
source "drivers/crypto/nx/Kconfig"
Expand Down
35 changes: 26 additions & 9 deletions drivers/crypto/nx/Kconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

config CRYPTO_DEV_NX_ENCRYPT
tristate "Encryption acceleration support"
depends on PPC64 && IBMVIO
tristate "Encryption acceleration support on pSeries platform"
depends on PPC_PSERIES && IBMVIO && !CPU_LITTLE_ENDIAN
default y
select CRYPTO_ALGAPI
select CRYPTO_AES
select CRYPTO_CBC
select CRYPTO_ECB
Expand All @@ -12,15 +14,30 @@ config CRYPTO_DEV_NX_ENCRYPT
select CRYPTO_SHA256
select CRYPTO_SHA512
help
Support for Power7+ in-Nest encryption acceleration. This
module supports acceleration for AES and SHA2 algorithms. If you
choose 'M' here, this module will be called nx_crypto.
Support for PowerPC Nest (NX) encryption acceleration. This
module supports acceleration for AES and SHA2 algorithms on
the pSeries platform. If you choose 'M' here, this module
will be called nx_crypto.

config CRYPTO_DEV_NX_COMPRESS
tristate "Compression acceleration support"
depends on PPC64 && IBMVIO
default y
help
Support for Power7+ in-Nest compression acceleration. This
module supports acceleration for AES and SHA2 algorithms. If you
choose 'M' here, this module will be called nx_compress.
Support for PowerPC Nest (NX) compression acceleration. This
module supports acceleration for compressing memory with the 842
algorithm. One of the platform drivers must be selected also.
If you choose 'M' here, this module will be called nx_compress.

if CRYPTO_DEV_NX_COMPRESS

config CRYPTO_DEV_NX_COMPRESS_PSERIES
tristate "Compression acceleration support on pSeries platform"
depends on PPC_PSERIES && IBMVIO && !CPU_LITTLE_ENDIAN
default y
help
Support for PowerPC Nest (NX) compression acceleration. This
module supports acceleration for compressing memory with the 842
algorithm. This supports NX hardware on the pSeries platform.
If you choose 'M' here, this module will be called nx_compress_pseries.

endif
4 changes: 3 additions & 1 deletion drivers/crypto/nx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ nx-crypto-objs := nx.o \
nx-sha512.o

obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS) += nx-compress.o
nx-compress-objs := nx-842-pseries.o
obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o
nx-compress-objs := nx-842.o
nx-compress-pseries-objs := nx-842-pseries.o
57 changes: 27 additions & 30 deletions drivers/crypto/nx/nx-842-pseries.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,13 @@
* Seth Jennings <[email protected]>
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/nx842.h>
#include <linux/of.h>
#include <linux/slab.h>

#include <asm/page.h>
#include <asm/vio.h>

#include "nx-842.h"
#include "nx_csbcpb.h" /* struct nx_csbcpb */

#define MODULE_NAME "nx-compress"
#define MODULE_NAME NX842_PSERIES_MODULE_NAME
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Jennings <[email protected]>");
MODULE_DESCRIPTION("842 H/W Compression driver for IBM Power processors");
Expand Down Expand Up @@ -236,18 +231,6 @@ struct nx842_workmem {
};
};

int nx842_get_workmem_size(void)
{
return sizeof(struct nx842_workmem) + NX842_HW_PAGE_SIZE;
}
EXPORT_SYMBOL_GPL(nx842_get_workmem_size);

int nx842_get_workmem_size_aligned(void)
{
return sizeof(struct nx842_workmem);
}
EXPORT_SYMBOL_GPL(nx842_get_workmem_size_aligned);

static int nx842_validate_result(struct device *dev,
struct cop_status_block *csb)
{
Expand Down Expand Up @@ -300,7 +283,7 @@ static int nx842_validate_result(struct device *dev,
}

/**
* nx842_compress - Compress data using the 842 algorithm
* nx842_pseries_compress - Compress data using the 842 algorithm
*
* Compression provide by the NX842 coprocessor on IBM Power systems.
* The input buffer is compressed and the result is stored in the
Expand All @@ -315,7 +298,7 @@ static int nx842_validate_result(struct device *dev,
* @out: Pointer to output buffer
* @outlen: Length of output buffer
* @wrkmem: ptr to buffer for working memory, size determined by
* nx842_get_workmem_size()
* NX842_MEM_COMPRESS
*
* Returns:
* 0 Success, output of length @outlen stored in the buffer at @out
Expand All @@ -325,8 +308,9 @@ static int nx842_validate_result(struct device *dev,
* -EIO Internal error
* -ENODEV Hardware unavailable
*/
int nx842_compress(const unsigned char *in, unsigned int inlen,
unsigned char *out, unsigned int *outlen, void *wmem)
static int nx842_pseries_compress(const unsigned char *in, unsigned int inlen,
unsigned char *out, unsigned int *outlen,
void *wmem)
{
struct nx842_header *hdr;
struct nx842_devdata *local_devdata;
Expand Down Expand Up @@ -493,13 +477,12 @@ int nx842_compress(const unsigned char *in, unsigned int inlen,
rcu_read_unlock();
return ret;
}
EXPORT_SYMBOL_GPL(nx842_compress);

static int sw842_decompress(const unsigned char *, int, unsigned char *, int *,
const void *);

/**
* nx842_decompress - Decompress data using the 842 algorithm
* nx842_pseries_decompress - Decompress data using the 842 algorithm
*
* Decompression provide by the NX842 coprocessor on IBM Power systems.
* The input buffer is decompressed and the result is stored in the
Expand All @@ -515,7 +498,7 @@ static int sw842_decompress(const unsigned char *, int, unsigned char *, int *,
* @out: Pointer to output buffer, must be page aligned
* @outlen: Length of output buffer, must be PAGE_SIZE
* @wrkmem: ptr to buffer for working memory, size determined by
* nx842_get_workmem_size()
* NX842_MEM_COMPRESS
*
* Returns:
* 0 Success, output of length @outlen stored in the buffer at @out
Expand All @@ -525,8 +508,9 @@ static int sw842_decompress(const unsigned char *, int, unsigned char *, int *,
* -EINVAL Bad input data encountered when attempting decompress
* -EIO Internal error
*/
int nx842_decompress(const unsigned char *in, unsigned int inlen,
unsigned char *out, unsigned int *outlen, void *wmem)
static int nx842_pseries_decompress(const unsigned char *in, unsigned int inlen,
unsigned char *out, unsigned int *outlen,
void *wmem)
{
struct nx842_header *hdr;
struct nx842_devdata *local_devdata;
Expand Down Expand Up @@ -694,7 +678,6 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen,
rcu_read_unlock();
return ret;
}
EXPORT_SYMBOL_GPL(nx842_decompress);

/**
* nx842_OF_set_defaults -- Set default (disabled) values for devdata
Expand Down Expand Up @@ -1130,6 +1113,12 @@ static struct attribute_group nx842_attribute_group = {
.attrs = nx842_sysfs_entries,
};

static struct nx842_driver nx842_pseries_driver = {
.owner = THIS_MODULE,
.compress = nx842_pseries_compress,
.decompress = nx842_pseries_decompress,
};

static int __init nx842_probe(struct vio_dev *viodev,
const struct vio_device_id *id)
{
Expand Down Expand Up @@ -1192,6 +1181,8 @@ static int __init nx842_probe(struct vio_dev *viodev,
goto error;
}

nx842_register_driver(&nx842_pseries_driver);

return 0;

error_unlock:
Expand Down Expand Up @@ -1222,11 +1213,14 @@ static int __exit nx842_remove(struct vio_dev *viodev)
if (old_devdata)
kfree(old_devdata->counters);
kfree(old_devdata);

nx842_unregister_driver(&nx842_pseries_driver);

return 0;
}

static struct vio_device_id nx842_driver_ids[] = {
{"ibm,compression-v1", "ibm,compression"},
{NX842_PSERIES_COMPAT_NAME "-v1", NX842_PSERIES_COMPAT_NAME},
{"", ""},
};

Expand All @@ -1243,6 +1237,8 @@ static int __init nx842_init(void)
struct nx842_devdata *new_devdata;
pr_info("Registering IBM Power 842 compression driver\n");

BUILD_BUG_ON(sizeof(struct nx842_workmem) > NX842_MEM_COMPRESS);

RCU_INIT_POINTER(devdata, NULL);
new_devdata = kzalloc(sizeof(*new_devdata), GFP_KERNEL);
if (!new_devdata) {
Expand Down Expand Up @@ -1272,6 +1268,7 @@ static void __exit nx842_exit(void)
if (old_devdata)
dev_set_drvdata(old_devdata->dev, NULL);
kfree(old_devdata);
nx842_unregister_driver(&nx842_pseries_driver);
vio_unregister_driver(&nx842_driver);
}

Expand Down
144 changes: 144 additions & 0 deletions drivers/crypto/nx/nx-842.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* Driver frontend for IBM Power 842 compression accelerator
*
* Copyright (C) 2015 Dan Streetman, IBM Corp
*
* Designer of the Power data compression engine:
* Bulent Abali <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include "nx-842.h"

#define MODULE_NAME "nx-compress"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dan Streetman <[email protected]>");
MODULE_DESCRIPTION("842 H/W Compression driver for IBM Power processors");

/* Only one driver is expected, based on the HW platform */
static struct nx842_driver *nx842_driver;
static DEFINE_SPINLOCK(nx842_driver_lock); /* protects driver pointers */

void nx842_register_driver(struct nx842_driver *driver)
{
spin_lock(&nx842_driver_lock);

if (nx842_driver) {
pr_err("can't register driver %s, already using driver %s\n",
driver->owner->name, nx842_driver->owner->name);
} else {
pr_info("registering driver %s\n", driver->owner->name);
nx842_driver = driver;
}

spin_unlock(&nx842_driver_lock);
}
EXPORT_SYMBOL_GPL(nx842_register_driver);

void nx842_unregister_driver(struct nx842_driver *driver)
{
spin_lock(&nx842_driver_lock);

if (nx842_driver == driver) {
pr_info("unregistering driver %s\n", driver->owner->name);
nx842_driver = NULL;
} else if (nx842_driver) {
pr_err("can't unregister driver %s, using driver %s\n",
driver->owner->name, nx842_driver->owner->name);
} else {
pr_err("can't unregister driver %s, no driver in use\n",
driver->owner->name);
}

spin_unlock(&nx842_driver_lock);
}
EXPORT_SYMBOL_GPL(nx842_unregister_driver);

static struct nx842_driver *get_driver(void)
{
struct nx842_driver *driver = NULL;

spin_lock(&nx842_driver_lock);

driver = nx842_driver;

if (driver && !try_module_get(driver->owner))
driver = NULL;

spin_unlock(&nx842_driver_lock);

return driver;
}

static void put_driver(struct nx842_driver *driver)
{
module_put(driver->owner);
}

int nx842_compress(const unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len,
void *wrkmem)
{
struct nx842_driver *driver = get_driver();
int ret;

if (!driver)
return -ENODEV;

ret = driver->compress(in, in_len, out, out_len, wrkmem);

put_driver(driver);

return ret;
}
EXPORT_SYMBOL_GPL(nx842_compress);

int nx842_decompress(const unsigned char *in, unsigned int in_len,
unsigned char *out, unsigned int *out_len,
void *wrkmem)
{
struct nx842_driver *driver = get_driver();
int ret;

if (!driver)
return -ENODEV;

ret = driver->decompress(in, in_len, out, out_len, wrkmem);

put_driver(driver);

return ret;
}
EXPORT_SYMBOL_GPL(nx842_decompress);

static __init int nx842_init(void)
{
pr_info("loading\n");

if (of_find_compatible_node(NULL, NULL, NX842_PSERIES_COMPAT_NAME))
request_module_nowait(NX842_PSERIES_MODULE_NAME);
else
pr_err("no nx842 driver found.\n");

pr_info("loaded\n");

return 0;
}
module_init(nx842_init);

static void __exit nx842_exit(void)
{
pr_info("NX842 unloaded\n");
}
module_exit(nx842_exit);
Loading

0 comments on commit 7011a12

Please sign in to comment.