* Re: [alsa-devel] [PATCH v11] ASoC: fsl: Add S/PDIF machine driver
From: Stephen Warren @ 2013-08-23 19:53 UTC (permalink / raw)
To: Mark Brown
Cc: mark.rutland, devicetree, alsa-devel, lars, s.hauer, Nicolin Chen,
tomasz.figa, rob.herring, p.zabel, shawn.guo, linuxppc-dev
In-Reply-To: <20130823191353.GK25263@sirena.org.uk>
On 08/23/2013 01:13 PM, Mark Brown wrote:
> On Fri, Aug 23, 2013 at 01:08:28PM -0600, Stephen Warren wrote:
>> On 08/23/2013 02:04 AM, Nicolin Chen wrote:
>>> This patch implements a device-tree-only machine driver for
>>> Freescale i.MX series Soc. It works with
>>> spdif_transmitter/spdif_receiver and fsl_spdif.c drivers.
>
>> The binding looks reasonable to me now. Thanks.
>
> Is that a Reviewed-by?
Sure, it can be,
Acked-by: Stephen Warren <swarren@nvidia.com>
^ permalink raw reply
* [PATCH 00/10] Series of fixes for NX driver
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Marcelo Cerri, linuxppc-dev, linux-kernel, linux-crypto
This series of patches contains fixes in several algorithms implemented
by the NX driver. The patches can be separated in three different
categories:
- Changes to split the data in several hyper calls to respect the
limits of data that the co-processador can handle. This affects
all AES modes.
- Fixes in how the driver handle zero length messages. This affects
XCBC and GCM.
- Fixes for SHA-2 when chunks bigger than the block size are provided.
Fionnuala Gunter (2):
crypto: nx - fix limits to sg lists for AES-XCBC
crypto: nx - fix limits to sg lists for AES-CCM
Marcelo Cerri (8):
crypto: nx - add offset to nx_build_sg_lists()
crypto: nx - fix limits to sg lists for AES-ECB
crypto: nx - fix limits to sg lists for AES-CBC
crypto: nx - fix limits to sg lists for AES-CTR
crypto: nx - fix limits to sg lists for AES-GCM
crypto: nx - fix XCBC for zero length messages
crypto: nx - fix GCM for zero length messages
crypto: nx - fix SHA-2 for chunks bigger than block size
drivers/crypto/nx/nx-aes-cbc.c | 50 ++++---
drivers/crypto/nx/nx-aes-ccm.c | 297 +++++++++++++++++++++++++++++-----------
drivers/crypto/nx/nx-aes-ctr.c | 50 ++++---
drivers/crypto/nx/nx-aes-ecb.c | 48 ++++---
drivers/crypto/nx/nx-aes-gcm.c | 292 ++++++++++++++++++++++++++++++---------
drivers/crypto/nx/nx-aes-xcbc.c | 191 +++++++++++++++++++-------
drivers/crypto/nx/nx-sha256.c | 2 +-
drivers/crypto/nx/nx-sha512.c | 2 +-
drivers/crypto/nx/nx.c | 9 +-
drivers/crypto/nx/nx.h | 2 +-
10 files changed, 683 insertions(+), 260 deletions(-)
--
1.7.12
^ permalink raw reply
* [PATCH 01/10] crypto: nx - add offset to nx_build_sg_lists()
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Marcelo Cerri, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
This patch includes one more parameter to nx_build_sg_lists() to skip
the given number of bytes from beginning of each sg list.
This is needed in order to implement the fixes for the AES modes to make
them able to process larger chunks of data.
Reviewed-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-aes-cbc.c | 2 +-
drivers/crypto/nx/nx-aes-ccm.c | 4 ++--
drivers/crypto/nx/nx-aes-ctr.c | 2 +-
drivers/crypto/nx/nx-aes-ecb.c | 2 +-
drivers/crypto/nx/nx-aes-gcm.c | 2 +-
drivers/crypto/nx/nx.c | 9 +++++++--
drivers/crypto/nx/nx.h | 2 +-
7 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/crypto/nx/nx-aes-cbc.c b/drivers/crypto/nx/nx-aes-cbc.c
index 9310982..f334a60 100644
--- a/drivers/crypto/nx/nx-aes-cbc.c
+++ b/drivers/crypto/nx/nx-aes-cbc.c
@@ -85,7 +85,7 @@ static int cbc_aes_nx_crypt(struct blkcipher_desc *desc,
else
NX_CPB_FDM(csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
- rc = nx_build_sg_lists(nx_ctx, desc, dst, src, nbytes,
+ rc = nx_build_sg_lists(nx_ctx, desc, dst, src, nbytes, 0,
csbcpb->cpb.aes_cbc.iv);
if (rc)
goto out;
diff --git a/drivers/crypto/nx/nx-aes-ccm.c b/drivers/crypto/nx/nx-aes-ccm.c
index 39d4224..666a35b 100644
--- a/drivers/crypto/nx/nx-aes-ccm.c
+++ b/drivers/crypto/nx/nx-aes-ccm.c
@@ -293,7 +293,7 @@ static int ccm_nx_decrypt(struct aead_request *req,
if (rc)
goto out;
- rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src, nbytes,
+ rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src, nbytes, 0,
csbcpb->cpb.aes_ccm.iv_or_ctr);
if (rc)
goto out;
@@ -339,7 +339,7 @@ static int ccm_nx_encrypt(struct aead_request *req,
if (rc)
goto out;
- rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src, nbytes,
+ rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src, nbytes, 0,
csbcpb->cpb.aes_ccm.iv_or_ctr);
if (rc)
goto out;
diff --git a/drivers/crypto/nx/nx-aes-ctr.c b/drivers/crypto/nx/nx-aes-ctr.c
index 762611b..80dee8d 100644
--- a/drivers/crypto/nx/nx-aes-ctr.c
+++ b/drivers/crypto/nx/nx-aes-ctr.c
@@ -98,7 +98,7 @@ static int ctr_aes_nx_crypt(struct blkcipher_desc *desc,
goto out;
}
- rc = nx_build_sg_lists(nx_ctx, desc, dst, src, nbytes,
+ rc = nx_build_sg_lists(nx_ctx, desc, dst, src, nbytes, 0,
csbcpb->cpb.aes_ctr.iv);
if (rc)
goto out;
diff --git a/drivers/crypto/nx/nx-aes-ecb.c b/drivers/crypto/nx/nx-aes-ecb.c
index 77dbe08..fe0d803 100644
--- a/drivers/crypto/nx/nx-aes-ecb.c
+++ b/drivers/crypto/nx/nx-aes-ecb.c
@@ -85,7 +85,7 @@ static int ecb_aes_nx_crypt(struct blkcipher_desc *desc,
else
NX_CPB_FDM(csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
- rc = nx_build_sg_lists(nx_ctx, desc, dst, src, nbytes, NULL);
+ rc = nx_build_sg_lists(nx_ctx, desc, dst, src, nbytes, 0, NULL);
if (rc)
goto out;
diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c
index 74feee1..c2d6f76 100644
--- a/drivers/crypto/nx/nx-aes-gcm.c
+++ b/drivers/crypto/nx/nx-aes-gcm.c
@@ -226,7 +226,7 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc)
csbcpb->cpb.aes_gcm.bit_length_data = nbytes * 8;
- rc = nx_build_sg_lists(nx_ctx, &desc, req->dst, req->src, nbytes,
+ rc = nx_build_sg_lists(nx_ctx, &desc, req->dst, req->src, nbytes, 0,
csbcpb->cpb.aes_gcm.iv_or_cnt);
if (rc)
goto out;
diff --git a/drivers/crypto/nx/nx.c b/drivers/crypto/nx/nx.c
index bdf4990..5533fe3 100644
--- a/drivers/crypto/nx/nx.c
+++ b/drivers/crypto/nx/nx.c
@@ -211,6 +211,8 @@ struct nx_sg *nx_walk_and_build(struct nx_sg *nx_dst,
* @dst: destination scatterlist
* @src: source scatterlist
* @nbytes: length of data described in the scatterlists
+ * @offset: number of bytes to fast-forward past at the beginning of
+ * scatterlists.
* @iv: destination for the iv data, if the algorithm requires it
*
* This is common code shared by all the AES algorithms. It uses the block
@@ -222,6 +224,7 @@ int nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx,
struct scatterlist *dst,
struct scatterlist *src,
unsigned int nbytes,
+ unsigned int offset,
u8 *iv)
{
struct nx_sg *nx_insg = nx_ctx->in_sg;
@@ -230,8 +233,10 @@ int nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx,
if (iv)
memcpy(iv, desc->info, AES_BLOCK_SIZE);
- nx_insg = nx_walk_and_build(nx_insg, nx_ctx->ap->sglen, src, 0, nbytes);
- nx_outsg = nx_walk_and_build(nx_outsg, nx_ctx->ap->sglen, dst, 0, nbytes);
+ nx_insg = nx_walk_and_build(nx_insg, nx_ctx->ap->sglen, src,
+ offset, nbytes);
+ nx_outsg = nx_walk_and_build(nx_outsg, nx_ctx->ap->sglen, dst,
+ offset, nbytes);
/* these lengths should be negative, which will indicate to phyp that
* the input and output parameters are scatterlists, not linear
diff --git a/drivers/crypto/nx/nx.h b/drivers/crypto/nx/nx.h
index 14bb97f..befda07 100644
--- a/drivers/crypto/nx/nx.h
+++ b/drivers/crypto/nx/nx.h
@@ -156,7 +156,7 @@ int nx_hcall_sync(struct nx_crypto_ctx *ctx, struct vio_pfo_op *op,
struct nx_sg *nx_build_sg_list(struct nx_sg *, u8 *, unsigned int, u32);
int nx_build_sg_lists(struct nx_crypto_ctx *, struct blkcipher_desc *,
struct scatterlist *, struct scatterlist *, unsigned int,
- u8 *);
+ unsigned int, u8 *);
struct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int,
struct scatterlist *, unsigned int,
unsigned int);
--
1.7.12
^ permalink raw reply related
* [PATCH 03/10] crypto: nx - fix limits to sg lists for AES-CBC
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Marcelo Cerri, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
This patch updates the nx-aes-cbc implementation to perform several
hyper calls if needed in order to always respect the length limits for
scatter/gather lists.
Two different limits are considered:
- "ibm,max-sg-len": maximum number of bytes of each scatter/gather
list.
- "ibm,max-sync-cop":
- The total number of bytes that a scatter/gather list can hold.
- The maximum number of elements that a scatter/gather list can have.
Reviewed-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-aes-cbc.c | 50 +++++++++++++++++++++++++-----------------
1 file changed, 30 insertions(+), 20 deletions(-)
diff --git a/drivers/crypto/nx/nx-aes-cbc.c b/drivers/crypto/nx/nx-aes-cbc.c
index f334a60..fa37df1 100644
--- a/drivers/crypto/nx/nx-aes-cbc.c
+++ b/drivers/crypto/nx/nx-aes-cbc.c
@@ -71,40 +71,50 @@ static int cbc_aes_nx_crypt(struct blkcipher_desc *desc,
struct nx_crypto_ctx *nx_ctx = crypto_blkcipher_ctx(desc->tfm);
struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
unsigned long irq_flags;
+ unsigned int processed = 0, to_process;
+ u32 max_sg_len;
int rc;
spin_lock_irqsave(&nx_ctx->lock, irq_flags);
- if (nbytes > nx_ctx->ap->databytelen) {
- rc = -EINVAL;
- goto out;
- }
+ max_sg_len = min_t(u32, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
if (enc)
NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT;
else
NX_CPB_FDM(csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
- rc = nx_build_sg_lists(nx_ctx, desc, dst, src, nbytes, 0,
- csbcpb->cpb.aes_cbc.iv);
- if (rc)
- goto out;
+ do {
+ to_process = min_t(u64, nbytes - processed,
+ nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
+ to_process = to_process & ~(AES_BLOCK_SIZE - 1);
- if (!nx_ctx->op.inlen || !nx_ctx->op.outlen) {
- rc = -EINVAL;
- goto out;
- }
+ rc = nx_build_sg_lists(nx_ctx, desc, dst, src, to_process,
+ processed, csbcpb->cpb.aes_cbc.iv);
+ if (rc)
+ goto out;
- rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
- desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
- if (rc)
- goto out;
+ if (!nx_ctx->op.inlen || !nx_ctx->op.outlen) {
+ rc = -EINVAL;
+ goto out;
+ }
- memcpy(desc->info, csbcpb->cpb.aes_cbc.cv, AES_BLOCK_SIZE);
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ goto out;
- atomic_inc(&(nx_ctx->stats->aes_ops));
- atomic64_add(csbcpb->csb.processed_byte_count,
- &(nx_ctx->stats->aes_bytes));
+ memcpy(desc->info, csbcpb->cpb.aes_cbc.cv, AES_BLOCK_SIZE);
+
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(csbcpb->csb.processed_byte_count,
+ &(nx_ctx->stats->aes_bytes));
+
+ processed += to_process;
+ } while (processed < nbytes);
out:
spin_unlock_irqrestore(&nx_ctx->lock, irq_flags);
return rc;
--
1.7.12
^ permalink raw reply related
* [PATCH 04/10] crypto: nx - fix limits to sg lists for AES-CTR
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Marcelo Cerri, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
This patch updates the nx-aes-ctr implementation to perform several
hyper calls if needed in order to always respect the length limits for
scatter/gather lists.
Two different limits are considered:
- "ibm,max-sg-len": maximum number of bytes of each scatter/gather
list.
- "ibm,max-sync-cop":
- The total number of bytes that a scatter/gather list can hold.
- The maximum number of elements that a scatter/gather list can have.
Reviewed-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-aes-ctr.c | 50 ++++++++++++++++++++++++++----------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/drivers/crypto/nx/nx-aes-ctr.c b/drivers/crypto/nx/nx-aes-ctr.c
index 80dee8d..a37d009 100644
--- a/drivers/crypto/nx/nx-aes-ctr.c
+++ b/drivers/crypto/nx/nx-aes-ctr.c
@@ -89,33 +89,45 @@ static int ctr_aes_nx_crypt(struct blkcipher_desc *desc,
struct nx_crypto_ctx *nx_ctx = crypto_blkcipher_ctx(desc->tfm);
struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
unsigned long irq_flags;
+ unsigned int processed = 0, to_process;
+ u32 max_sg_len;
int rc;
spin_lock_irqsave(&nx_ctx->lock, irq_flags);
- if (nbytes > nx_ctx->ap->databytelen) {
- rc = -EINVAL;
- goto out;
- }
+ max_sg_len = min_t(u32, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
- rc = nx_build_sg_lists(nx_ctx, desc, dst, src, nbytes, 0,
- csbcpb->cpb.aes_ctr.iv);
- if (rc)
- goto out;
+ do {
+ to_process = min_t(u64, nbytes - processed,
+ nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
+ to_process = to_process & ~(AES_BLOCK_SIZE - 1);
- if (!nx_ctx->op.inlen || !nx_ctx->op.outlen) {
- rc = -EINVAL;
- goto out;
- }
+ rc = nx_build_sg_lists(nx_ctx, desc, dst, src, to_process,
+ processed, csbcpb->cpb.aes_ctr.iv);
+ if (rc)
+ goto out;
- rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
- desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
- if (rc)
- goto out;
+ if (!nx_ctx->op.inlen || !nx_ctx->op.outlen) {
+ rc = -EINVAL;
+ goto out;
+ }
- atomic_inc(&(nx_ctx->stats->aes_ops));
- atomic64_add(csbcpb->csb.processed_byte_count,
- &(nx_ctx->stats->aes_bytes));
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ goto out;
+
+ memcpy(desc->info, csbcpb->cpb.aes_cbc.cv, AES_BLOCK_SIZE);
+
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(csbcpb->csb.processed_byte_count,
+ &(nx_ctx->stats->aes_bytes));
+
+ processed += to_process;
+ } while (processed < nbytes);
out:
spin_unlock_irqrestore(&nx_ctx->lock, irq_flags);
return rc;
--
1.7.12
^ permalink raw reply related
* [PATCH 02/10] crypto: nx - fix limits to sg lists for AES-ECB
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Marcelo Cerri, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
This patch updates the nx-aes-ecb implementation to perform several
hyper calls if needed in order to always respect the length limits for
scatter/gather lists.
Two different limits are considered:
- "ibm,max-sg-len": maximum number of bytes of each scatter/gather
list.
- "ibm,max-sync-cop":
- The total number of bytes that a scatter/gather list can hold.
- The maximum number of elements that a scatter/gather list can have.
Reviewed-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-aes-ecb.c | 48 ++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 18 deletions(-)
diff --git a/drivers/crypto/nx/nx-aes-ecb.c b/drivers/crypto/nx/nx-aes-ecb.c
index fe0d803..85a8d23 100644
--- a/drivers/crypto/nx/nx-aes-ecb.c
+++ b/drivers/crypto/nx/nx-aes-ecb.c
@@ -71,37 +71,49 @@ static int ecb_aes_nx_crypt(struct blkcipher_desc *desc,
struct nx_crypto_ctx *nx_ctx = crypto_blkcipher_ctx(desc->tfm);
struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
unsigned long irq_flags;
+ unsigned int processed = 0, to_process;
+ u32 max_sg_len;
int rc;
spin_lock_irqsave(&nx_ctx->lock, irq_flags);
- if (nbytes > nx_ctx->ap->databytelen) {
- rc = -EINVAL;
- goto out;
- }
+ max_sg_len = min_t(u32, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
if (enc)
NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT;
else
NX_CPB_FDM(csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
- rc = nx_build_sg_lists(nx_ctx, desc, dst, src, nbytes, 0, NULL);
- if (rc)
- goto out;
+ do {
+ to_process = min_t(u64, nbytes - processed,
+ nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
+ to_process = to_process & ~(AES_BLOCK_SIZE - 1);
- if (!nx_ctx->op.inlen || !nx_ctx->op.outlen) {
- rc = -EINVAL;
- goto out;
- }
+ rc = nx_build_sg_lists(nx_ctx, desc, dst, src, to_process,
+ processed, NULL);
+ if (rc)
+ goto out;
- rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
- desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
- if (rc)
- goto out;
+ if (!nx_ctx->op.inlen || !nx_ctx->op.outlen) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ goto out;
+
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(csbcpb->csb.processed_byte_count,
+ &(nx_ctx->stats->aes_bytes));
+
+ processed += to_process;
+ } while (processed < nbytes);
- atomic_inc(&(nx_ctx->stats->aes_ops));
- atomic64_add(csbcpb->csb.processed_byte_count,
- &(nx_ctx->stats->aes_bytes));
out:
spin_unlock_irqrestore(&nx_ctx->lock, irq_flags);
return rc;
--
1.7.12
^ permalink raw reply related
* [PATCH 05/10] crypto: nx - fix limits to sg lists for AES-GCM
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Marcelo Cerri, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
This patch updates the nx-aes-gcm implementation to perform several
hyper calls if needed in order to always respect the length limits for
scatter/gather lists.
Two different limits are considered:
- "ibm,max-sg-len": maximum number of bytes of each scatter/gather
list.
- "ibm,max-sync-cop":
- The total number of bytes that a scatter/gather list can hold.
- The maximum number of elements that a scatter/gather list can have.
Reviewed-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-aes-gcm.c | 202 +++++++++++++++++++++++++++--------------
1 file changed, 136 insertions(+), 66 deletions(-)
diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c
index c2d6f76..9e89bdf 100644
--- a/drivers/crypto/nx/nx-aes-gcm.c
+++ b/drivers/crypto/nx/nx-aes-gcm.c
@@ -125,37 +125,101 @@ static int nx_gca(struct nx_crypto_ctx *nx_ctx,
struct aead_request *req,
u8 *out)
{
+ int rc;
struct nx_csbcpb *csbcpb_aead = nx_ctx->csbcpb_aead;
- int rc = -EINVAL;
struct scatter_walk walk;
struct nx_sg *nx_sg = nx_ctx->in_sg;
+ unsigned int nbytes = req->assoclen;
+ unsigned int processed = 0, to_process;
+ u32 max_sg_len;
- if (req->assoclen > nx_ctx->ap->databytelen)
- goto out;
-
- if (req->assoclen <= AES_BLOCK_SIZE) {
+ if (nbytes <= AES_BLOCK_SIZE) {
scatterwalk_start(&walk, req->assoc);
- scatterwalk_copychunks(out, &walk, req->assoclen,
- SCATTERWALK_FROM_SG);
+ scatterwalk_copychunks(out, &walk, nbytes, SCATTERWALK_FROM_SG);
scatterwalk_done(&walk, SCATTERWALK_FROM_SG, 0);
-
- rc = 0;
- goto out;
+ return 0;
}
- nx_sg = nx_walk_and_build(nx_sg, nx_ctx->ap->sglen, req->assoc, 0,
- req->assoclen);
- nx_ctx->op_aead.inlen = (nx_ctx->in_sg - nx_sg) * sizeof(struct nx_sg);
+ NX_CPB_FDM(csbcpb_aead) &= ~NX_FDM_CONTINUATION;
- rc = nx_hcall_sync(nx_ctx, &nx_ctx->op_aead,
- req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
- if (rc)
- goto out;
+ /* page_limit: number of sg entries that fit on one page */
+ max_sg_len = min_t(u32, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
- atomic_inc(&(nx_ctx->stats->aes_ops));
- atomic64_add(req->assoclen, &(nx_ctx->stats->aes_bytes));
+ do {
+ /*
+ * to_process: the data chunk to process in this update.
+ * This value is bound by sg list limits.
+ */
+ to_process = min_t(u64, nbytes - processed,
+ nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
+
+ if ((to_process + processed) < nbytes)
+ NX_CPB_FDM(csbcpb_aead) |= NX_FDM_INTERMEDIATE;
+ else
+ NX_CPB_FDM(csbcpb_aead) &= ~NX_FDM_INTERMEDIATE;
+
+ nx_sg = nx_walk_and_build(nx_ctx->in_sg, nx_ctx->ap->sglen,
+ req->assoc, processed, to_process);
+ nx_ctx->op_aead.inlen = (nx_ctx->in_sg - nx_sg)
+ * sizeof(struct nx_sg);
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op_aead,
+ req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ return rc;
+
+ memcpy(csbcpb_aead->cpb.aes_gca.in_pat,
+ csbcpb_aead->cpb.aes_gca.out_pat,
+ AES_BLOCK_SIZE);
+ NX_CPB_FDM(csbcpb_aead) |= NX_FDM_CONTINUATION;
+
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(req->assoclen, &(nx_ctx->stats->aes_bytes));
+
+ processed += to_process;
+ } while (processed < nbytes);
memcpy(out, csbcpb_aead->cpb.aes_gca.out_pat, AES_BLOCK_SIZE);
+
+ return rc;
+}
+
+static int gcm_empty(struct aead_request *req, struct blkcipher_desc *desc,
+ int enc)
+{
+ int rc;
+ struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm);
+ struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
+
+ /* For scenarios where the input message is zero length, AES CTR mode
+ * may be used. Set the source data to be a single block (16B) of all
+ * zeros, and set the input IV value to be the same as the GMAC IV
+ * value. - nx_wb 4.8.1.3 */
+ char src[AES_BLOCK_SIZE] = {};
+ struct scatterlist sg;
+
+ desc->tfm = crypto_alloc_blkcipher("ctr(aes)", 0, 0);
+ if (IS_ERR(desc->tfm)) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ crypto_blkcipher_setkey(desc->tfm, csbcpb->cpb.aes_gcm.key,
+ NX_CPB_KEY_SIZE(csbcpb) == NX_KS_AES_128 ? 16 :
+ NX_CPB_KEY_SIZE(csbcpb) == NX_KS_AES_192 ? 24 : 32);
+
+ sg_init_one(&sg, src, AES_BLOCK_SIZE);
+ if (enc)
+ rc = crypto_blkcipher_encrypt_iv(desc, req->dst, &sg,
+ AES_BLOCK_SIZE);
+ else
+ rc = crypto_blkcipher_decrypt_iv(desc, req->dst, &sg,
+ AES_BLOCK_SIZE);
+ crypto_free_blkcipher(desc->tfm);
+
out:
return rc;
}
@@ -166,79 +230,85 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc)
struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
struct blkcipher_desc desc;
unsigned int nbytes = req->cryptlen;
+ unsigned int processed = 0, to_process;
unsigned long irq_flags;
+ u32 max_sg_len;
int rc = -EINVAL;
spin_lock_irqsave(&nx_ctx->lock, irq_flags);
- if (nbytes > nx_ctx->ap->databytelen)
- goto out;
-
desc.info = nx_ctx->priv.gcm.iv;
/* initialize the counter */
*(u32 *)(desc.info + NX_GCM_CTR_OFFSET) = 1;
- /* For scenarios where the input message is zero length, AES CTR mode
- * may be used. Set the source data to be a single block (16B) of all
- * zeros, and set the input IV value to be the same as the GMAC IV
- * value. - nx_wb 4.8.1.3 */
if (nbytes == 0) {
- char src[AES_BLOCK_SIZE] = {};
- struct scatterlist sg;
-
- desc.tfm = crypto_alloc_blkcipher("ctr(aes)", 0, 0);
- if (IS_ERR(desc.tfm)) {
- rc = -ENOMEM;
- goto out;
- }
-
- crypto_blkcipher_setkey(desc.tfm, csbcpb->cpb.aes_gcm.key,
- NX_CPB_KEY_SIZE(csbcpb) == NX_KS_AES_128 ? 16 :
- NX_CPB_KEY_SIZE(csbcpb) == NX_KS_AES_192 ? 24 : 32);
-
- sg_init_one(&sg, src, AES_BLOCK_SIZE);
- if (enc)
- crypto_blkcipher_encrypt_iv(&desc, req->dst, &sg,
- AES_BLOCK_SIZE);
- else
- crypto_blkcipher_decrypt_iv(&desc, req->dst, &sg,
- AES_BLOCK_SIZE);
- crypto_free_blkcipher(desc.tfm);
-
- rc = 0;
+ rc = gcm_empty(req, &desc, enc);
goto out;
}
- desc.tfm = (struct crypto_blkcipher *)req->base.tfm;
-
+ /* Process associated data */
csbcpb->cpb.aes_gcm.bit_length_aad = req->assoclen * 8;
-
if (req->assoclen) {
rc = nx_gca(nx_ctx, req, csbcpb->cpb.aes_gcm.in_pat_or_aad);
if (rc)
goto out;
}
- if (enc)
+ /* Set flags for encryption */
+ NX_CPB_FDM(csbcpb) &= ~NX_FDM_CONTINUATION;
+ if (enc) {
NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT;
- else
+ } else {
+ NX_CPB_FDM(csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
nbytes -= crypto_aead_authsize(crypto_aead_reqtfm(req));
+ }
- csbcpb->cpb.aes_gcm.bit_length_data = nbytes * 8;
+ /* page_limit: number of sg entries that fit on one page */
+ max_sg_len = min_t(u32, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
- rc = nx_build_sg_lists(nx_ctx, &desc, req->dst, req->src, nbytes, 0,
- csbcpb->cpb.aes_gcm.iv_or_cnt);
- if (rc)
- goto out;
+ do {
+ /*
+ * to_process: the data chunk to process in this update.
+ * This value is bound by sg list limits.
+ */
+ to_process = min_t(u64, nbytes - processed,
+ nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
- rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
- req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
- if (rc)
- goto out;
+ if ((to_process + processed) < nbytes)
+ NX_CPB_FDM(csbcpb) |= NX_FDM_INTERMEDIATE;
+ else
+ NX_CPB_FDM(csbcpb) &= ~NX_FDM_INTERMEDIATE;
- atomic_inc(&(nx_ctx->stats->aes_ops));
- atomic64_add(csbcpb->csb.processed_byte_count,
- &(nx_ctx->stats->aes_bytes));
+ csbcpb->cpb.aes_gcm.bit_length_data = nbytes * 8;
+ desc.tfm = (struct crypto_blkcipher *) req->base.tfm;
+ rc = nx_build_sg_lists(nx_ctx, &desc, req->dst,
+ req->src, to_process, processed,
+ csbcpb->cpb.aes_gcm.iv_or_cnt);
+ if (rc)
+ goto out;
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ goto out;
+
+ memcpy(desc.info, csbcpb->cpb.aes_gcm.out_cnt, AES_BLOCK_SIZE);
+ memcpy(csbcpb->cpb.aes_gcm.in_pat_or_aad,
+ csbcpb->cpb.aes_gcm.out_pat_or_mac, AES_BLOCK_SIZE);
+ memcpy(csbcpb->cpb.aes_gcm.in_s0,
+ csbcpb->cpb.aes_gcm.out_s0, AES_BLOCK_SIZE);
+
+ NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;
+
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(csbcpb->csb.processed_byte_count,
+ &(nx_ctx->stats->aes_bytes));
+
+ processed += to_process;
+ } while (processed < nbytes);
if (enc) {
/* copy out the auth tag */
--
1.7.12
^ permalink raw reply related
* [PATCH 06/10] crypto: nx - fix limits to sg lists for AES-XCBC
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Fionnuala Gunter, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
From: Fionnuala Gunter <fin@linux.vnet.ibm.com>
This patch updates the NX driver to perform several hyper calls when necessary
so that the length limits of scatter/gather lists are respected.
Reviewed-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Reviewed-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
Signed-off-by: Fionnuala Gunter <fin@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-aes-xcbc.c | 107 +++++++++++++++++++++++-----------------
1 file changed, 63 insertions(+), 44 deletions(-)
diff --git a/drivers/crypto/nx/nx-aes-xcbc.c b/drivers/crypto/nx/nx-aes-xcbc.c
index 658da0f..1a5d9e3 100644
--- a/drivers/crypto/nx/nx-aes-xcbc.c
+++ b/drivers/crypto/nx/nx-aes-xcbc.c
@@ -88,78 +88,97 @@ static int nx_xcbc_update(struct shash_desc *desc,
struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&desc->tfm->base);
struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
struct nx_sg *in_sg;
- u32 to_process, leftover;
+ u32 to_process, leftover, total;
+ u32 max_sg_len;
unsigned long irq_flags;
int rc = 0;
spin_lock_irqsave(&nx_ctx->lock, irq_flags);
- if (NX_CPB_FDM(csbcpb) & NX_FDM_CONTINUATION) {
- /* we've hit the nx chip previously and we're updating again,
- * so copy over the partial digest */
- memcpy(csbcpb->cpb.aes_xcbc.cv,
- csbcpb->cpb.aes_xcbc.out_cv_mac, AES_BLOCK_SIZE);
- }
+
+ total = sctx->count + len;
/* 2 cases for total data len:
* 1: <= AES_BLOCK_SIZE: copy into state, return 0
* 2: > AES_BLOCK_SIZE: process X blocks, copy in leftover
*/
- if (len + sctx->count <= AES_BLOCK_SIZE) {
+ if (total <= AES_BLOCK_SIZE) {
memcpy(sctx->buffer + sctx->count, data, len);
sctx->count += len;
goto out;
}
- /* to_process: the AES_BLOCK_SIZE data chunk to process in this
- * update */
- to_process = (sctx->count + len) & ~(AES_BLOCK_SIZE - 1);
- leftover = (sctx->count + len) & (AES_BLOCK_SIZE - 1);
+ in_sg = nx_ctx->in_sg;
+ max_sg_len = min_t(u32, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
- /* the hardware will not accept a 0 byte operation for this algorithm
- * and the operation MUST be finalized to be correct. So if we happen
- * to get an update that falls on a block sized boundary, we must
- * save off the last block to finalize with later. */
- if (!leftover) {
- to_process -= AES_BLOCK_SIZE;
- leftover = AES_BLOCK_SIZE;
- }
+ do {
- if (sctx->count) {
- in_sg = nx_build_sg_list(nx_ctx->in_sg, sctx->buffer,
- sctx->count, nx_ctx->ap->sglen);
- in_sg = nx_build_sg_list(in_sg, (u8 *)data,
- to_process - sctx->count,
- nx_ctx->ap->sglen);
- nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) *
- sizeof(struct nx_sg);
- } else {
- in_sg = nx_build_sg_list(nx_ctx->in_sg, (u8 *)data, to_process,
- nx_ctx->ap->sglen);
+ /* to_process: the AES_BLOCK_SIZE data chunk to process in this
+ * update */
+ to_process = min_t(u64, total, nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
+ to_process = to_process & ~(AES_BLOCK_SIZE - 1);
+ leftover = total - to_process;
+
+ /* the hardware will not accept a 0 byte operation for this
+ * algorithm and the operation MUST be finalized to be correct.
+ * So if we happen to get an update that falls on a block sized
+ * boundary, we must save off the last block to finalize with
+ * later. */
+ if (!leftover) {
+ to_process -= AES_BLOCK_SIZE;
+ leftover = AES_BLOCK_SIZE;
+ }
+
+ if (sctx->count) {
+ in_sg = nx_build_sg_list(nx_ctx->in_sg,
+ (u8 *) sctx->buffer,
+ sctx->count,
+ max_sg_len);
+ }
+ in_sg = nx_build_sg_list(in_sg,
+ (u8 *) data,
+ to_process - sctx->count,
+ max_sg_len);
nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) *
sizeof(struct nx_sg);
- }
- NX_CPB_FDM(csbcpb) |= NX_FDM_INTERMEDIATE;
+ /* we've hit the nx chip previously and we're updating again,
+ * so copy over the partial digest */
+ if (NX_CPB_FDM(csbcpb) & NX_FDM_CONTINUATION) {
+ memcpy(csbcpb->cpb.aes_xcbc.cv,
+ csbcpb->cpb.aes_xcbc.out_cv_mac,
+ AES_BLOCK_SIZE);
+ }
- if (!nx_ctx->op.inlen || !nx_ctx->op.outlen) {
- rc = -EINVAL;
- goto out;
- }
+ NX_CPB_FDM(csbcpb) |= NX_FDM_INTERMEDIATE;
+ if (!nx_ctx->op.inlen || !nx_ctx->op.outlen) {
+ rc = -EINVAL;
+ goto out;
+ }
- rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
- if (rc)
- goto out;
+ if (rc)
+ goto out;
- atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+
+ /* everything after the first update is continuation */
+ NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;
+
+ total -= to_process;
+ data += to_process - sctx->count;
+ sctx->count = 0;
+ in_sg = nx_ctx->in_sg;
+ } while (leftover > AES_BLOCK_SIZE);
/* copy the leftover back into the state struct */
- memcpy(sctx->buffer, data + len - leftover, leftover);
+ memcpy(sctx->buffer, data, leftover);
sctx->count = leftover;
- /* everything after the first update is continuation */
- NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;
out:
spin_unlock_irqrestore(&nx_ctx->lock, irq_flags);
return rc;
--
1.7.12
^ permalink raw reply related
* [PATCH 07/10] crypto: nx - fix limits to sg lists for AES-CCM
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert
Cc: Joy Latten, Fionnuala Gunter, linuxppc-dev, linux-kernel,
linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
From: Fionnuala Gunter <fin@linux.vnet.ibm.com>
This patch updates the NX driver to perform several hyper calls when necessary
so that the length limits of scatter/gather lists are respected.
Reviewed-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
Signed-off-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Signed-off-by: Fionnuala Gunter <fin@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-aes-ccm.c | 297 +++++++++++++++++++++++++++++------------
1 file changed, 215 insertions(+), 82 deletions(-)
diff --git a/drivers/crypto/nx/nx-aes-ccm.c b/drivers/crypto/nx/nx-aes-ccm.c
index 666a35b..5ecd4c2 100644
--- a/drivers/crypto/nx/nx-aes-ccm.c
+++ b/drivers/crypto/nx/nx-aes-ccm.c
@@ -179,13 +179,26 @@ static int generate_pat(u8 *iv,
struct nx_sg *nx_insg = nx_ctx->in_sg;
struct nx_sg *nx_outsg = nx_ctx->out_sg;
unsigned int iauth_len = 0;
- struct vio_pfo_op *op = NULL;
u8 tmp[16], *b1 = NULL, *b0 = NULL, *result = NULL;
int rc;
/* zero the ctr value */
memset(iv + 15 - iv[0], 0, iv[0] + 1);
+ /* page 78 of nx_wb.pdf has,
+ * Note: RFC3610 allows the AAD data to be up to 2^64 -1 bytes
+ * in length. If a full message is used, the AES CCA implementation
+ * restricts the maximum AAD length to 2^32 -1 bytes.
+ * If partial messages are used, the implementation supports
+ * 2^64 -1 bytes maximum AAD length.
+ *
+ * However, in the cryptoapi's aead_request structure,
+ * assoclen is an unsigned int, thus it cannot hold a length
+ * value greater than 2^32 - 1.
+ * Thus the AAD is further constrained by this and is never
+ * greater than 2^32.
+ */
+
if (!req->assoclen) {
b0 = nx_ctx->csbcpb->cpb.aes_ccm.in_pat_or_b0;
} else if (req->assoclen <= 14) {
@@ -195,7 +208,46 @@ static int generate_pat(u8 *iv,
b0 = nx_ctx->csbcpb->cpb.aes_ccm.in_pat_or_b0;
b1 = nx_ctx->priv.ccm.iauth_tag;
iauth_len = req->assoclen;
+ } else if (req->assoclen <= 65280) {
+ /* if associated data is less than (2^16 - 2^8), we construct
+ * B1 differently and feed in the associated data to a CCA
+ * operation */
+ b0 = nx_ctx->csbcpb_aead->cpb.aes_cca.b0;
+ b1 = nx_ctx->csbcpb_aead->cpb.aes_cca.b1;
+ iauth_len = 14;
+ } else {
+ b0 = nx_ctx->csbcpb_aead->cpb.aes_cca.b0;
+ b1 = nx_ctx->csbcpb_aead->cpb.aes_cca.b1;
+ iauth_len = 10;
+ }
+ /* generate B0 */
+ rc = generate_b0(iv, req->assoclen, authsize, nbytes, b0);
+ if (rc)
+ return rc;
+
+ /* generate B1:
+ * add control info for associated data
+ * RFC 3610 and NIST Special Publication 800-38C
+ */
+ if (b1) {
+ memset(b1, 0, 16);
+ if (req->assoclen <= 65280) {
+ *(u16 *)b1 = (u16)req->assoclen;
+ scatterwalk_map_and_copy(b1 + 2, req->assoc, 0,
+ iauth_len, SCATTERWALK_FROM_SG);
+ } else {
+ *(u16 *)b1 = (u16)(0xfffe);
+ *(u32 *)&b1[2] = (u32)req->assoclen;
+ scatterwalk_map_and_copy(b1 + 6, req->assoc, 0,
+ iauth_len, SCATTERWALK_FROM_SG);
+ }
+ }
+
+ /* now copy any remaining AAD to scatterlist and call nx... */
+ if (!req->assoclen) {
+ return rc;
+ } else if (req->assoclen <= 14) {
nx_insg = nx_build_sg_list(nx_insg, b1, 16, nx_ctx->ap->sglen);
nx_outsg = nx_build_sg_list(nx_outsg, tmp, 16,
nx_ctx->ap->sglen);
@@ -210,56 +262,74 @@ static int generate_pat(u8 *iv,
NX_CPB_FDM(nx_ctx->csbcpb) |= NX_FDM_ENDE_ENCRYPT;
NX_CPB_FDM(nx_ctx->csbcpb) |= NX_FDM_INTERMEDIATE;
- op = &nx_ctx->op;
result = nx_ctx->csbcpb->cpb.aes_ccm.out_pat_or_mac;
- } else if (req->assoclen <= 65280) {
- /* if associated data is less than (2^16 - 2^8), we construct
- * B1 differently and feed in the associated data to a CCA
- * operation */
- b0 = nx_ctx->csbcpb_aead->cpb.aes_cca.b0;
- b1 = nx_ctx->csbcpb_aead->cpb.aes_cca.b1;
- iauth_len = 14;
-
- /* remaining assoc data must have scatterlist built for it */
- nx_insg = nx_walk_and_build(nx_insg, nx_ctx->ap->sglen,
- req->assoc, iauth_len,
- req->assoclen - iauth_len);
- nx_ctx->op_aead.inlen = (nx_ctx->in_sg - nx_insg) *
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ return rc;
+
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(req->assoclen, &(nx_ctx->stats->aes_bytes));
+
+ } else {
+ u32 max_sg_len;
+ unsigned int processed = 0, to_process;
+
+ /* page_limit: number of sg entries that fit on one page */
+ max_sg_len = min_t(u32,
+ nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
+
+ processed += iauth_len;
+
+ do {
+ to_process = min_t(u32, req->assoclen - processed,
+ nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
+
+ if ((to_process + processed) < req->assoclen) {
+ NX_CPB_FDM(nx_ctx->csbcpb_aead) |=
+ NX_FDM_INTERMEDIATE;
+ } else {
+ NX_CPB_FDM(nx_ctx->csbcpb_aead) &=
+ ~NX_FDM_INTERMEDIATE;
+ }
+
+ nx_insg = nx_walk_and_build(nx_ctx->in_sg,
+ nx_ctx->ap->sglen,
+ req->assoc, processed,
+ to_process);
+
+ nx_ctx->op_aead.inlen = (nx_ctx->in_sg - nx_insg) *
sizeof(struct nx_sg);
- op = &nx_ctx->op_aead;
+ result = nx_ctx->csbcpb_aead->cpb.aes_cca.out_pat_or_b0;
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op_aead,
+ req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ return rc;
+
+ memcpy(nx_ctx->csbcpb_aead->cpb.aes_cca.b0,
+ nx_ctx->csbcpb_aead->cpb.aes_cca.out_pat_or_b0,
+ AES_BLOCK_SIZE);
+
+ NX_CPB_FDM(nx_ctx->csbcpb_aead) |= NX_FDM_CONTINUATION;
+
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(req->assoclen,
+ &(nx_ctx->stats->aes_bytes));
+
+ processed += to_process;
+ } while (processed < req->assoclen);
+
result = nx_ctx->csbcpb_aead->cpb.aes_cca.out_pat_or_b0;
- } else {
- /* if associated data is less than (2^32), we construct B1
- * differently yet again and feed in the associated data to a
- * CCA operation */
- pr_err("associated data len is %u bytes (returning -EINVAL)\n",
- req->assoclen);
- rc = -EINVAL;
}
- rc = generate_b0(iv, req->assoclen, authsize, nbytes, b0);
- if (rc)
- goto done;
+ memcpy(out, result, AES_BLOCK_SIZE);
- if (b1) {
- memset(b1, 0, 16);
- *(u16 *)b1 = (u16)req->assoclen;
-
- scatterwalk_map_and_copy(b1 + 2, req->assoc, 0,
- iauth_len, SCATTERWALK_FROM_SG);
-
- rc = nx_hcall_sync(nx_ctx, op,
- req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
- if (rc)
- goto done;
-
- atomic_inc(&(nx_ctx->stats->aes_ops));
- atomic64_add(req->assoclen, &(nx_ctx->stats->aes_bytes));
-
- memcpy(out, result, AES_BLOCK_SIZE);
- }
-done:
return rc;
}
@@ -272,15 +342,12 @@ static int ccm_nx_decrypt(struct aead_request *req,
unsigned int authsize = crypto_aead_authsize(crypto_aead_reqtfm(req));
struct nx_ccm_priv *priv = &nx_ctx->priv.ccm;
unsigned long irq_flags;
+ unsigned int processed = 0, to_process;
+ u32 max_sg_len;
int rc = -1;
spin_lock_irqsave(&nx_ctx->lock, irq_flags);
- if (nbytes > nx_ctx->ap->databytelen) {
- rc = -EINVAL;
- goto out;
- }
-
nbytes -= authsize;
/* copy out the auth tag to compare with later */
@@ -293,22 +360,56 @@ static int ccm_nx_decrypt(struct aead_request *req,
if (rc)
goto out;
- rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src, nbytes, 0,
- csbcpb->cpb.aes_ccm.iv_or_ctr);
- if (rc)
- goto out;
+ /* page_limit: number of sg entries that fit on one page */
+ max_sg_len = min_t(u32, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
- NX_CPB_FDM(nx_ctx->csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
- NX_CPB_FDM(nx_ctx->csbcpb) &= ~NX_FDM_INTERMEDIATE;
+ do {
- rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ /* to_process: the AES_BLOCK_SIZE data chunk to process in this
+ * update. This value is bound by sg list limits.
+ */
+ to_process = min_t(u64, nbytes - processed,
+ nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
+
+ if ((to_process + processed) < nbytes)
+ NX_CPB_FDM(csbcpb) |= NX_FDM_INTERMEDIATE;
+ else
+ NX_CPB_FDM(csbcpb) &= ~NX_FDM_INTERMEDIATE;
+
+ NX_CPB_FDM(nx_ctx->csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
+
+ rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src,
+ to_process, processed,
+ csbcpb->cpb.aes_ccm.iv_or_ctr);
+ if (rc)
+ goto out;
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
- if (rc)
- goto out;
+ if (rc)
+ goto out;
- atomic_inc(&(nx_ctx->stats->aes_ops));
- atomic64_add(csbcpb->csb.processed_byte_count,
- &(nx_ctx->stats->aes_bytes));
+ /* for partial completion, copy following for next
+ * entry into loop...
+ */
+ memcpy(desc->info, csbcpb->cpb.aes_ccm.out_ctr, AES_BLOCK_SIZE);
+ memcpy(csbcpb->cpb.aes_ccm.in_pat_or_b0,
+ csbcpb->cpb.aes_ccm.out_pat_or_mac, AES_BLOCK_SIZE);
+ memcpy(csbcpb->cpb.aes_ccm.in_s0,
+ csbcpb->cpb.aes_ccm.out_s0, AES_BLOCK_SIZE);
+
+ NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;
+
+ /* update stats */
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(csbcpb->csb.processed_byte_count,
+ &(nx_ctx->stats->aes_bytes));
+
+ processed += to_process;
+ } while (processed < nbytes);
rc = memcmp(csbcpb->cpb.aes_ccm.out_pat_or_mac, priv->oauth_tag,
authsize) ? -EBADMSG : 0;
@@ -325,41 +426,73 @@ static int ccm_nx_encrypt(struct aead_request *req,
unsigned int nbytes = req->cryptlen;
unsigned int authsize = crypto_aead_authsize(crypto_aead_reqtfm(req));
unsigned long irq_flags;
+ unsigned int processed = 0, to_process;
+ u32 max_sg_len;
int rc = -1;
spin_lock_irqsave(&nx_ctx->lock, irq_flags);
- if (nbytes > nx_ctx->ap->databytelen) {
- rc = -EINVAL;
- goto out;
- }
-
rc = generate_pat(desc->info, req, nx_ctx, authsize, nbytes,
csbcpb->cpb.aes_ccm.in_pat_or_b0);
if (rc)
goto out;
- rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src, nbytes, 0,
- csbcpb->cpb.aes_ccm.iv_or_ctr);
- if (rc)
- goto out;
-
- NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT;
- NX_CPB_FDM(csbcpb) &= ~NX_FDM_INTERMEDIATE;
-
- rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
- req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
- if (rc)
- goto out;
-
- atomic_inc(&(nx_ctx->stats->aes_ops));
- atomic64_add(csbcpb->csb.processed_byte_count,
- &(nx_ctx->stats->aes_bytes));
+ /* page_limit: number of sg entries that fit on one page */
+ max_sg_len = min_t(u32, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
+
+ do {
+ /* to process: the AES_BLOCK_SIZE data chunk to process in this
+ * update. This value is bound by sg list limits.
+ */
+ to_process = min_t(u64, nbytes - processed,
+ nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
+
+ if ((to_process + processed) < nbytes)
+ NX_CPB_FDM(csbcpb) |= NX_FDM_INTERMEDIATE;
+ else
+ NX_CPB_FDM(csbcpb) &= ~NX_FDM_INTERMEDIATE;
+
+ NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT;
+
+ rc = nx_build_sg_lists(nx_ctx, desc, req->dst, req->src,
+ to_process, processed,
+ csbcpb->cpb.aes_ccm.iv_or_ctr);
+ if (rc)
+ goto out;
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ goto out;
+
+ /* for partial completion, copy following for next
+ * entry into loop...
+ */
+ memcpy(desc->info, csbcpb->cpb.aes_ccm.out_ctr, AES_BLOCK_SIZE);
+ memcpy(csbcpb->cpb.aes_ccm.in_pat_or_b0,
+ csbcpb->cpb.aes_ccm.out_pat_or_mac, AES_BLOCK_SIZE);
+ memcpy(csbcpb->cpb.aes_ccm.in_s0,
+ csbcpb->cpb.aes_ccm.out_s0, AES_BLOCK_SIZE);
+
+ NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;
+
+ /* update stats */
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(csbcpb->csb.processed_byte_count,
+ &(nx_ctx->stats->aes_bytes));
+
+ processed += to_process;
+
+ } while (processed < nbytes);
/* copy out the auth tag */
scatterwalk_map_and_copy(csbcpb->cpb.aes_ccm.out_pat_or_mac,
req->dst, nbytes, authsize,
SCATTERWALK_TO_SG);
+
out:
spin_unlock_irqrestore(&nx_ctx->lock, irq_flags);
return rc;
--
1.7.12
^ permalink raw reply related
* [PATCH 08/10] crypto: nx - fix XCBC for zero length messages
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Marcelo Cerri, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
The NX XCBC implementation doesn't support zero length messages and
because of that NX is currently returning a hard-coded hash for zero
length messages. However this approach is incorrect since the hash value
also depends on which key is used.
This patch removes the hard-coded hash and replace it with an
implementation based on the RFC 3566 using ECB.
Reviewed-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-aes-xcbc.c | 84 +++++++++++++++++++++++++++++++++++++----
1 file changed, 77 insertions(+), 7 deletions(-)
diff --git a/drivers/crypto/nx/nx-aes-xcbc.c b/drivers/crypto/nx/nx-aes-xcbc.c
index 1a5d9e3..03c4bf5 100644
--- a/drivers/crypto/nx/nx-aes-xcbc.c
+++ b/drivers/crypto/nx/nx-aes-xcbc.c
@@ -56,6 +56,77 @@ static int nx_xcbc_set_key(struct crypto_shash *desc,
return 0;
}
+/*
+ * Based on RFC 3566, for a zero-length message:
+ *
+ * n = 1
+ * K1 = E(K, 0x01010101010101010101010101010101)
+ * K3 = E(K, 0x03030303030303030303030303030303)
+ * E[0] = 0x00000000000000000000000000000000
+ * M[1] = 0x80000000000000000000000000000000 (0 length message with padding)
+ * E[1] = (K1, M[1] ^ E[0] ^ K3)
+ * Tag = M[1]
+ */
+static int nx_xcbc_empty(struct shash_desc *desc, u8 *out)
+{
+ struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(&desc->tfm->base);
+ struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
+ struct nx_sg *in_sg, *out_sg;
+ u8 keys[2][AES_BLOCK_SIZE];
+ u8 key[32];
+ int rc = 0;
+
+ /* Change to ECB mode */
+ csbcpb->cpb.hdr.mode = NX_MODE_AES_ECB;
+ memcpy(key, csbcpb->cpb.aes_xcbc.key, AES_BLOCK_SIZE);
+ memcpy(csbcpb->cpb.aes_ecb.key, key, AES_BLOCK_SIZE);
+ NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT;
+
+ /* K1 and K3 base patterns */
+ memset(keys[0], 0x01, sizeof(keys[0]));
+ memset(keys[1], 0x03, sizeof(keys[1]));
+
+ /* Generate K1 and K3 encrypting the patterns */
+ in_sg = nx_build_sg_list(nx_ctx->in_sg, (u8 *) keys, sizeof(keys),
+ nx_ctx->ap->sglen);
+ out_sg = nx_build_sg_list(nx_ctx->out_sg, (u8 *) keys, sizeof(keys),
+ nx_ctx->ap->sglen);
+ nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg);
+ nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg);
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ goto out;
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+
+ /* XOr K3 with the padding for a 0 length message */
+ keys[1][0] ^= 0x80;
+
+ /* Encrypt the final result */
+ memcpy(csbcpb->cpb.aes_ecb.key, keys[0], AES_BLOCK_SIZE);
+ in_sg = nx_build_sg_list(nx_ctx->in_sg, (u8 *) keys[1], sizeof(keys[1]),
+ nx_ctx->ap->sglen);
+ out_sg = nx_build_sg_list(nx_ctx->out_sg, out, AES_BLOCK_SIZE,
+ nx_ctx->ap->sglen);
+ nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg);
+ nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg);
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ goto out;
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+
+out:
+ /* Restore XCBC mode */
+ csbcpb->cpb.hdr.mode = NX_MODE_AES_XCBC_MAC;
+ memcpy(csbcpb->cpb.aes_xcbc.key, key, AES_BLOCK_SIZE);
+ NX_CPB_FDM(csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
+
+ return rc;
+}
+
static int nx_xcbc_init(struct shash_desc *desc)
{
struct xcbc_state *sctx = shash_desc_ctx(desc);
@@ -201,13 +272,12 @@ static int nx_xcbc_final(struct shash_desc *desc, u8 *out)
memcpy(csbcpb->cpb.aes_xcbc.cv,
csbcpb->cpb.aes_xcbc.out_cv_mac, AES_BLOCK_SIZE);
} else if (sctx->count == 0) {
- /* we've never seen an update, so this is a 0 byte op. The
- * hardware cannot handle a 0 byte op, so just copy out the
- * known 0 byte result. This is cheaper than allocating a
- * software context to do a 0 byte op */
- u8 data[] = { 0x75, 0xf0, 0x25, 0x1d, 0x52, 0x8a, 0xc0, 0x1c,
- 0x45, 0x73, 0xdf, 0xd5, 0x84, 0xd7, 0x9f, 0x29 };
- memcpy(out, data, sizeof(data));
+ /*
+ * we've never seen an update, so this is a 0 byte op. The
+ * hardware cannot handle a 0 byte op, so just ECB to
+ * generate the hash.
+ */
+ rc = nx_xcbc_empty(desc, out);
goto out;
}
--
1.7.12
^ permalink raw reply related
* [PATCH 09/10] crypto: nx - fix GCM for zero length messages
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Marcelo Cerri, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
The NX CGM implementation doesn't support zero length messages and the
current implementation has two flaws:
- When the input data length is zero, it ignores the associated data.
- Even when both lengths are zero, it uses the Crypto API to encrypt a
zeroed block using ctr(aes) and because of this it allocates a new
transformation and sets the key for this new tfm. Both operations are
intended to be used only in user context, while the cryptographic
operations can be called in both user and softirq contexts.
This patch replaces the nested Crypto API use and adds two special
cases:
- When input data and associated data lengths are zero: it uses NX ECB
mode to emulate the encryption of a zeroed block using ctr(aes).
- When input data is zero and associated data is available: it uses NX
GMAC mode to calculate the associated data MAC.
Reviewed-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-aes-gcm.c | 132 ++++++++++++++++++++++++++++++++++-------
1 file changed, 112 insertions(+), 20 deletions(-)
diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c
index 9e89bdf..025d9a8 100644
--- a/drivers/crypto/nx/nx-aes-gcm.c
+++ b/drivers/crypto/nx/nx-aes-gcm.c
@@ -187,40 +187,125 @@ static int nx_gca(struct nx_crypto_ctx *nx_ctx,
return rc;
}
+static int gmac(struct aead_request *req, struct blkcipher_desc *desc)
+{
+ int rc;
+ struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm);
+ struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
+ struct nx_sg *nx_sg;
+ unsigned int nbytes = req->assoclen;
+ unsigned int processed = 0, to_process;
+ u32 max_sg_len;
+
+ /* Set GMAC mode */
+ csbcpb->cpb.hdr.mode = NX_MODE_AES_GMAC;
+
+ NX_CPB_FDM(csbcpb) &= ~NX_FDM_CONTINUATION;
+
+ /* page_limit: number of sg entries that fit on one page */
+ max_sg_len = min_t(u32, nx_driver.of.max_sg_len/sizeof(struct nx_sg),
+ nx_ctx->ap->sglen);
+
+ /* Copy IV */
+ memcpy(csbcpb->cpb.aes_gcm.iv_or_cnt, desc->info, AES_BLOCK_SIZE);
+
+ do {
+ /*
+ * to_process: the data chunk to process in this update.
+ * This value is bound by sg list limits.
+ */
+ to_process = min_t(u64, nbytes - processed,
+ nx_ctx->ap->databytelen);
+ to_process = min_t(u64, to_process,
+ NX_PAGE_SIZE * (max_sg_len - 1));
+
+ if ((to_process + processed) < nbytes)
+ NX_CPB_FDM(csbcpb) |= NX_FDM_INTERMEDIATE;
+ else
+ NX_CPB_FDM(csbcpb) &= ~NX_FDM_INTERMEDIATE;
+
+ nx_sg = nx_walk_and_build(nx_ctx->in_sg, nx_ctx->ap->sglen,
+ req->assoc, processed, to_process);
+ nx_ctx->op.inlen = (nx_ctx->in_sg - nx_sg)
+ * sizeof(struct nx_sg);
+
+ csbcpb->cpb.aes_gcm.bit_length_data = 0;
+ csbcpb->cpb.aes_gcm.bit_length_aad = 8 * nbytes;
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ goto out;
+
+ memcpy(csbcpb->cpb.aes_gcm.in_pat_or_aad,
+ csbcpb->cpb.aes_gcm.out_pat_or_mac, AES_BLOCK_SIZE);
+ memcpy(csbcpb->cpb.aes_gcm.in_s0,
+ csbcpb->cpb.aes_gcm.out_s0, AES_BLOCK_SIZE);
+
+ NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;
+
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+ atomic64_add(req->assoclen, &(nx_ctx->stats->aes_bytes));
+
+ processed += to_process;
+ } while (processed < nbytes);
+
+out:
+ /* Restore GCM mode */
+ csbcpb->cpb.hdr.mode = NX_MODE_AES_GCM;
+ return rc;
+}
+
static int gcm_empty(struct aead_request *req, struct blkcipher_desc *desc,
int enc)
{
int rc;
struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm);
struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
+ char out[AES_BLOCK_SIZE];
+ struct nx_sg *in_sg, *out_sg;
/* For scenarios where the input message is zero length, AES CTR mode
* may be used. Set the source data to be a single block (16B) of all
* zeros, and set the input IV value to be the same as the GMAC IV
* value. - nx_wb 4.8.1.3 */
- char src[AES_BLOCK_SIZE] = {};
- struct scatterlist sg;
- desc->tfm = crypto_alloc_blkcipher("ctr(aes)", 0, 0);
- if (IS_ERR(desc->tfm)) {
- rc = -ENOMEM;
- goto out;
- }
-
- crypto_blkcipher_setkey(desc->tfm, csbcpb->cpb.aes_gcm.key,
- NX_CPB_KEY_SIZE(csbcpb) == NX_KS_AES_128 ? 16 :
- NX_CPB_KEY_SIZE(csbcpb) == NX_KS_AES_192 ? 24 : 32);
-
- sg_init_one(&sg, src, AES_BLOCK_SIZE);
+ /* Change to ECB mode */
+ csbcpb->cpb.hdr.mode = NX_MODE_AES_ECB;
+ memcpy(csbcpb->cpb.aes_ecb.key, csbcpb->cpb.aes_gcm.key,
+ sizeof(csbcpb->cpb.aes_ecb.key));
if (enc)
- rc = crypto_blkcipher_encrypt_iv(desc, req->dst, &sg,
- AES_BLOCK_SIZE);
+ NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT;
else
- rc = crypto_blkcipher_decrypt_iv(desc, req->dst, &sg,
- AES_BLOCK_SIZE);
- crypto_free_blkcipher(desc->tfm);
+ NX_CPB_FDM(csbcpb) &= ~NX_FDM_ENDE_ENCRYPT;
+ /* Encrypt the counter/IV */
+ in_sg = nx_build_sg_list(nx_ctx->in_sg, (u8 *) desc->info,
+ AES_BLOCK_SIZE, nx_ctx->ap->sglen);
+ out_sg = nx_build_sg_list(nx_ctx->out_sg, (u8 *) out, sizeof(out),
+ nx_ctx->ap->sglen);
+ nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg);
+ nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg);
+
+ rc = nx_hcall_sync(nx_ctx, &nx_ctx->op,
+ desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP);
+ if (rc)
+ goto out;
+ atomic_inc(&(nx_ctx->stats->aes_ops));
+
+ /* Copy out the auth tag */
+ memcpy(csbcpb->cpb.aes_gcm.out_pat_or_mac, out,
+ crypto_aead_authsize(crypto_aead_reqtfm(req)));
out:
+ /* Restore XCBC mode */
+ csbcpb->cpb.hdr.mode = NX_MODE_AES_GCM;
+
+ /*
+ * ECB key uses the same region that GCM AAD and counter, so it's safe
+ * to just fill it with zeroes.
+ */
+ memset(csbcpb->cpb.aes_ecb.key, 0, sizeof(csbcpb->cpb.aes_ecb.key));
+
return rc;
}
@@ -242,8 +327,14 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc)
*(u32 *)(desc.info + NX_GCM_CTR_OFFSET) = 1;
if (nbytes == 0) {
- rc = gcm_empty(req, &desc, enc);
- goto out;
+ if (req->assoclen == 0)
+ rc = gcm_empty(req, &desc, enc);
+ else
+ rc = gmac(req, &desc);
+ if (rc)
+ goto out;
+ else
+ goto mac;
}
/* Process associated data */
@@ -310,6 +401,7 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc)
processed += to_process;
} while (processed < nbytes);
+mac:
if (enc) {
/* copy out the auth tag */
scatterwalk_map_and_copy(csbcpb->cpb.aes_gcm.out_pat_or_mac,
--
1.7.12
^ permalink raw reply related
* [PATCH 10/10] crypto: nx - fix SHA-2 for chunks bigger than block size
From: Marcelo Cerri @ 2013-08-23 20:01 UTC (permalink / raw)
To: herbert; +Cc: Marcelo Cerri, linuxppc-dev, linux-kernel, linux-crypto
In-Reply-To: <1377288074-18998-1-git-send-email-mhcerri@linux.vnet.ibm.com>
Each call to the co-processor, with exception of the last call, needs to
send data that is multiple of block size. As consequence, any remaining
data is kept in the internal NX context.
This patch fixes a bug in the driver that causes it to save incorrect
data into the context when data is bigger than the block size.
Reviewed-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
---
drivers/crypto/nx/nx-sha256.c | 2 +-
drivers/crypto/nx/nx-sha512.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/nx/nx-sha256.c b/drivers/crypto/nx/nx-sha256.c
index 6547a71..da0b24a 100644
--- a/drivers/crypto/nx/nx-sha256.c
+++ b/drivers/crypto/nx/nx-sha256.c
@@ -129,7 +129,7 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data,
NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;
total -= to_process;
- data += to_process;
+ data += to_process - sctx->count;
sctx->count = 0;
in_sg = nx_ctx->in_sg;
} while (leftover >= SHA256_BLOCK_SIZE);
diff --git a/drivers/crypto/nx/nx-sha512.c b/drivers/crypto/nx/nx-sha512.c
index 236e6af..4ae5b0f 100644
--- a/drivers/crypto/nx/nx-sha512.c
+++ b/drivers/crypto/nx/nx-sha512.c
@@ -131,7 +131,7 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data,
NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;
total -= to_process;
- data += to_process;
+ data += to_process - sctx->count[0];
sctx->count[0] = 0;
in_sg = nx_ctx->in_sg;
} while (leftover >= SHA512_BLOCK_SIZE);
--
1.7.12
^ permalink raw reply related
* Re: [v3] powerpc/mpc85xx: Update the clock device tree nodes
From: Scott Wood @ 2013-08-23 20:08 UTC (permalink / raw)
To: tang yuantian; +Cc: devicetree, linuxppc-dev
In-Reply-To: <1370480811-13700-1-git-send-email-Yuantian.Tang@freescale.com>
On Thu, Jun 06, 2013 at 09:06:51AM +0800, tang yuantian wrote:
> From: Tang Yuantian <yuantian.tang@freescale.com>
>
> The following SoCs will be affected: p2041, p3041, p4080,
> p5020, p5040, b4420, b4860, t4240
>
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
>
> ---
> v3:
> - fix typo
> v2:
> - add t4240, b4420, b4860 support
> - remove pll/4 clock from p2041, p3041 and p5020 board
>
> arch/powerpc/boot/dts/fsl/b4420si-post.dtsi | 32 ++++++++-
> arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi | 2 +
> arch/powerpc/boot/dts/fsl/b4860si-post.dtsi | 32 ++++++++-
> arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi | 4 ++
> arch/powerpc/boot/dts/fsl/p2041si-post.dtsi | 54 ++++++++++++++-
> arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi | 4 ++
> arch/powerpc/boot/dts/fsl/p3041si-post.dtsi | 54 ++++++++++++++-
> arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi | 4 ++
> arch/powerpc/boot/dts/fsl/p4080si-post.dtsi | 100 +++++++++++++++++++++++++++-
> arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi | 8 +++
> arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | 38 ++++++++++-
> arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi | 2 +
> arch/powerpc/boot/dts/fsl/p5040si-post.dtsi | 54 ++++++++++++++-
> arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi | 4 ++
> arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 77 ++++++++++++++++++++-
> arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi | 12 ++++
> 16 files changed, 473 insertions(+), 8 deletions(-)
>
> diff --git a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
> index 5a6615d..b69d6e5 100644
> --- a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
> +++ b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
> @@ -85,7 +85,37 @@
> };
>
> clockgen: global-utilities@e1000 {
> - compatible = "fsl,b4420-clockgen", "fsl,qoriq-clockgen-2.0";
> + compatible = "fsl,b4420-clockgen", "fsl,qoriq-clockgen-2.0",
> + "fixed-clock";
> + clock-output-names = "sysclk";
> + #clock-cells = <0>;
Does U-Boot fill in clock-frequency here?
> + #address-cells = <1>;
> + #size-cells = <0>;
> + pll0: pll0@800 {
> + #clock-cells = <1>;
> + reg = <0x800>;
> + compatible = "fsl,core-pll-clock";
> + clocks = <&clockgen>;
> + clock-output-names = "pll0", "pll0-div2", "pll0-div4";
> + };
> + pll1: pll1@820 {
> + #clock-cells = <1>;
> + reg = <0x820>;
> + compatible = "fsl,core-pll-clock";
> + clocks = <&clockgen>;
> + clock-output-names = "pll1", "pll1-div2", "pll1-div4";
> + };
Please leave a blank line between properties and nodes, and between
nodes.
What does reg represent? Where is the binding for this?
The compatible is too vague.
> + mux0: mux0@0 {
> + #clock-cells = <0>;
> + reg = <0x0>;
> + compatible = "fsl,core-mux-clock";
> + clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
> + <&pll1 0>, <&pll1 1>, <&pll1 2>;
> + clock-names = "pll0_0", "pll0_1", "pll0_2",
> + "pll1_0", "pll1_1", "pll1_2";
> + clock-output-names = "cmux0";
> + };
What does reg represent? Where is the binding for this?
The compatible is too vague.
-Scott
^ permalink raw reply
* Re: [alsa-devel] [PATCH v5 1/2] ASoC: fsl: Add S/PDIF CPU DAI driver
From: Mike Turquette @ 2013-08-23 21:41 UTC (permalink / raw)
To: Sascha Hauer, Mark Rutland
Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
lars@metafoo.de, ian.campbell@citrix.com, Pawel Moll,
swarren@wwwdotorg.org, linuxppc-dev@lists.ozlabs.org,
Nicolin Chen, Tomasz Figa, rob.herring@calxeda.com,
timur@tabi.org, broonie@kernel.org, p.zabel@pengutronix.de,
galak@codeaurora.org, shawn.guo@linaro.org, festevam@gmail.com
In-Reply-To: <20130823140128.GI31036@pengutronix.de>
Quoting Sascha Hauer (2013-08-23 07:01:28)
> On Fri, Aug 23, 2013 at 01:58:15PM +0100, Mark Rutland wrote:
> > On Fri, Aug 23, 2013 at 07:34:21AM +0100, Sascha Hauer wrote:
> > > On Fri, Aug 23, 2013 at 12:49:19AM +0200, Tomasz Figa wrote:
> > > > On Thursday 22 of August 2013 15:43:31 Mike Turquette wrote:
> > > > > Quoting Sascha Hauer (2013-08-22 14:00:35)
> > > > > =
> > > > > > On Thu, Aug 22, 2013 at 01:09:31PM +0100, Mark Rutland wrote:
> > > > > > > On Thu, Aug 22, 2013 at 08:19:10AM +0100, Mike Turquette wrot=
e:
> > > > > > > > Quoting Tomasz Figa (2013-08-21 14:34:55)
> > > > > > > > =
> > > > > > > > > On Wednesday 21 of August 2013 09:50:15 Mark Rutland wrot=
e:
> > > > > > > > > > On Tue, Aug 20, 2013 at 01:06:25AM +0100, Mike Turquett=
e =
> > > > wrote:
> > > > > > > > > > > Quoting Mark Rutland (2013-08-19 02:35:43)
> > > > > > > > > > > =
> > > > > > > > > > > > On Sat, Aug 17, 2013 at 04:17:18PM +0100, Tomasz Fi=
ga =
> > > > wrote:
> > > > > > > > > > > > > On Saturday 17 of August 2013 16:53:16 Sascha Hau=
er =
> > > > wrote:
> > > > > > > > > > > > > > On Sat, Aug 17, 2013 at 02:28:04PM +0200, Tomas=
z Figa =
> > > > wrote:
> > > > > > > > > > > > > > > > > > Also I would make this option required.=
Use a
> > > > > > > > > > > > > > > > > > dummy
> > > > > > > > > > > > > > > > > > clock for
> > > > > > > > > > > > > > > > > > mux
> > > > > > > > > > > > > > > > > > inputs that are grounded for a specific=
SoC.
> > > > > > > > > > > > > > > > > =
> > > > > > > > > > > > > > > > > Some clocks are not from CCM and we haven=
't
> > > > > > > > > > > > > > > > > defined in
> > > > > > > > > > > > > > > > > imx6q-clk.txt,
> > > > > > > > > > > > > > > > > so in most cases we can't provide a phand=
le for
> > > > > > > > > > > > > > > > > them, eg:
> > > > > > > > > > > > > > > > > spdif_ext.
> > > > > > > > > > > > > > > > > I think it's a bit hard to force it to be
> > > > > > > > > > > > > > > > > 'required'. An
> > > > > > > > > > > > > > > > > 'optional'
> > > > > > > > > > > > > > > > > looks more flexible to me and a default o=
ne is
> > > > > > > > > > > > > > > > > ensured
> > > > > > > > > > > > > > > > > even if
> > > > > > > > > > > > > > > > > it's
> > > > > > > > > > > > > > > > > missing.
> > > > > > > > > > > > > > > > =
> > > > > > > > > > > > > > > > <&clks 0> is the dummy clock. This can be u=
sed for
> > > > > > > > > > > > > > > > all input
> > > > > > > > > > > > > > > > clocks
> > > > > > > > > > > > > > > > not
> > > > > > > > > > > > > > > > defined by the SoC.
> > > > > > > > > > > > > > > =
> > > > > > > > > > > > > > > Where does this assumption come from? Is it
> > > > > > > > > > > > > > > documented
> > > > > > > > > > > > > > > anywhere?
> > > > > > > > > > > > > > =
> > > > > > > > > > > > > > This is how all i.MX clock bindings currently a=
re. See
> > > > > > > > > > > > > > Documentation/devicetree/bindings/clock/imx*-cl=
ock.txt
> > > > > > > > > > > > > =
> > > > > > > > > > > > > OK, thanks.
> > > > > > > > > > > > > =
> > > > > > > > > > > > > I guess we need some discussion on dummy clocks vs
> > > > > > > > > > > > > skipped clocks.
> > > > > > > > > > > > > I think we want some consistency on this, don't w=
e?
> > > > > > > > > > > > > =
> > > > > > > > > > > > > If we really need a dummy clock, then we might al=
so want
> > > > > > > > > > > > > a generic
> > > > > > > > > > > > > way to specify it.
> > > > > > > > > > > > =
> > > > > > > > > > > > What do we actually mean by a "dummy clock"? We alr=
eady
> > > > > > > > > > > > have
> > > > > > > > > > > > bindings
> > > > > > > > > > > > for "fixed-clock" and co friends describe relatively
> > > > > > > > > > > > simple
> > > > > > > > > > > > preconfigured clocks.
> > > > > > > > > > > =
> > > > > > > > > > > Some platforms have a fake clock which defines noops
> > > > > > > > > > > callbacks and
> > > > > > > > > > > basically doesn't do anything. This is analogous to t=
he
> > > > > > > > > > > dummy
> > > > > > > > > > > regulator
> > > > > > > > > > > implementation. A central one could be registered by =
the
> > > > > > > > > > > clock core,
> > > > > > > > > > > as
> > > > > > > > > > > is done by the regulator core.
> > > > > > > > > > =
> > > > > > > > > > When you say some platforms, you presumably mean the pl=
atform
> > > > > > > > > > code in
> > > > > > > > > > Linux? A dummy clock sounds like a completely Linux-spe=
cific
> > > > > > > > > > abstraction rather than a description of the hardware, =
and I
> > > > > > > > > > don't see why we need that in the DT:
> > > > > > > > > > =
> > > > > > > > > > * If a clock is wired up and running (as presumably the=
dummy
> > > > > > > > > > clock is), then surely it's a fixed-clock (it's running=
, we
> > > > > > > > > > and we have no control over it, but we presumably know =
its
> > > > > > > > > > rate) and can be described as such?
> > > > > > > > > > =
> > > > > > > > > > * If no clock is wired up, then we should be able to de=
scribe
> > > > > > > > > > that. If a driver believes that a clock is required whe=
n it
> > > > > > > > > > isn't (for some level of functionality), then that driv=
er
> > > > > > > > > > should be fixed up to support the clock as being option=
al.
> > > > > > > > > > =
> > > > > > > > > > Am I missing something?
> > > > > > > > > =
> > > > > > > > > I second that.
> > > > > > > > > =
> > > > > > > > > Moreover, I don't think that device tree should deal with=
dummy
> > > > > > > > > anything. It should be able to describe hardware that is
> > > > > > > > > available on given system, not list what hardware is not
> > > > > > > > > available.
> > > > > > > > =
> > > > > > > > I wasn't clear. The dummy clock IS a completely Linux-speci=
fic
> > > > > > > > abstraction.
> > > > > > > > =
> > > > > > > > I'm not advocating a dummy clock in DT. I am advocating
> > > > > > > > consolidation of the implementation of a clock that does no=
thing
> > > > > > > > into the clock core. This code could easily live in
> > > > > > > > drivers/clk/clk.c instead of having everyone open-code it.
> > > > > > > > =
> > > > > > > > As far as specifying a dummy clock in DT? I dunno. DT should
> > > > > > > > describe
> > > > > > > > real hardware so there isn't much use for a dummy clock.
> > > > > > > =
> > > > > > > Sorry, I misunderstood. Good to hear we're on the same page :)
> > > > > > > =
> > > > > > > > I'm guessing one of the reasons for such a clock are driver=
s do
> > > > > > > > not
> > > > > > > > honor the clk.h api and they freak out when clk_get gives t=
hem a
> > > > > > > > NULL
> > > > > > > > pointer?
> > > > > > > =
> > > > > > > I'm not sure. Sascha, could you shed some light on the matter?
> > > > > > =
> > > > > > The original reason introducing the dummy clocks in the i.MX dt=
bs
> > > > > > was to provide devices a clock which the driver requests but is
> > > > > > not software controllable. We often have the case where the same
> > > > > > devices are on several SoCs, but not on all of them all clocks =
have
> > > > > > a bit to en/disable them.
> > > > > > =
> > > > > > Anyway, to accomplish this we don't need dummy clocks. We can j=
ust
> > > > > > describe the real clocks.
> > > > > =
> > > > > You could use a dummy clk for the Linux implementation, but the d=
ownside
> > > > > is that a dummy clock has a rate of 0 always and a your clocks li=
kely
> > > > > have non-zero rates.
> > > > > =
> > > > > It is probably better for you define a clock which only implement=
s the
> > > > > .recalc_rate callback. If the rate of this clock changes without =
Linux
> > > > > having knowledge of it you can use the CLK_GET_RATE_NOCACHE flag.
> > > > =
> > > > I doubt that rate of a dummy clock could ever change... unless it i=
s a =
> > > > rather smart dummy.
> > > > =
> > > > > > BTW with the S/PDIF core on which not all mux inputs are connec=
ted
> > > > > > to actual clocks we could also describe the unconnected inputs =
as
> > > > > > ground clocks with rate 0. This way we describe something which
> > > > > > is really there instead of dummy clocks ;)
> > > > > =
> > > > > Again you could use a dummy clock for this OR a fixed-rate clock =
with a
> > > > > rate of zero from the perspective of the Linux implementation.
> > > > > =
> > > > > Do you think it worthwhile to have a DT binding for a grounded cl=
ock?
> > > > > That is not an entirely uncommon case.
> > > > =
> > > > Well, how would that differ from skipping a clock from clocks list,=
i.e. =
> > > > not specifying it in clock-names and clocks properties?
> > > =
> > > The difference is that you can successfully grab it in your driver.
> > =
> > That's a driver-specific issue. The driver knows best which clocks it
> > can live without (if it's poking only a subset of the hardware, it may
> > not need some just yet, but could for extended functionality in future
> > when support is extended), and could assign a dummy to those clocks it
> > knows it doesn't need that aren't described. That doesn't need to be in
> > the dt, and shouldn't be, because it's OS and driver specific.
> > =
> > > =
> > > > =
> > > > > > Background to why it might be a good idea to connect a ground c=
lock
> > > > > > to the unconnected input pins is that a driver has a chance to
> > > > > > successfully grab all clocks. Otherwise how does the driver
> > > > > > distinguish
> > > > > > between an unconnected and an erroneous clock?
> > > > > =
> > > > > Sorry, I don't follow this last question. Do you mean how to dist=
inguish
> > > > > based on the value returned from clk_get?
> > > > =
> > > > Hmm, in theory, a driver could want to distinguish an error case (e=
.g. =
> > > > clock specified, but there is a problem with it) from no clock (e.g=
. clock =
> > > > not specified in DT, because it is not available on particular boar=
d).
> > > =
> > > Yes, that's what I meant. To illustrate the problem for this driver:
> > > =
> > > for (i =3D 0; i < STC_TXCLK_SRC_MAX; i++) {
> > > sprintf(tmp, "rxtx%d", i);
> > > clk =3D devm_clk_get(&pdev->dev, tmp);
> > > if (IS_ERR(clk)) {
> > =
> > [...]
> > =
> > /*
> > * ERR_PTR(-ENOENT) returned when clock not
> > * present in the dt (i.e. not wired up). We can
> > * live without this clock, so assign a dummy
> > * (NULL) to simplify the rest of the code. If
> > * the clock is present but something else went
> > * wrong, we'll get a different ERR_PTR value
> > * and actually fail.
> > */
> > if (clk =3D=3D ERR_PTR(-ENOENT)
> > clk =3D NULL;
> > =
> > > }
> > > }
> > > =
> > > This could be solved by always specifying all input clocks in the
> > > devicetree.
> > =
> > As far as I can see, the above is sufficient, and leaves the knowledge
> > of skippable clocks in the driver, where I believe it should be.
> =
> You miss my point. Once a clock is specified in the devicetree it is no
> longer optional. The driver currently can't find out whether a clock
> hasn't been specified (and it's ok that it's not there) or a clock has
> been specified, but some error prevents actually grabbing the clock (in
> which case the driver should bail out)
Seems like the regulator framework is solving this with the new
regulator_get_optional() call. This leaves the
optional-versus-not-optional logic up to the driver.
Regards,
Mike
> =
> Sascha
> =
> =
> -- =
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH][RFC] pci: fsl: rework PCIe driver compatible with Layerscape
From: Scott Wood @ 2013-08-23 21:45 UTC (permalink / raw)
To: Minghuan Lian; +Cc: linuxppc-dev, Zang Roy-R61911
In-Reply-To: <1376915011-31467-1-git-send-email-Minghuan.Lian@freescale.com>
On Mon, 2013-08-19 at 20:23 +0800, Minghuan Lian wrote:
> The Freescale's Layerscape series processors will use ARM cores.
> The LS1's PCIe controllers is the same as T4240's. So it's better
> the PCIe controller driver can support PowerPC and ARM
> simultaneously. This patch is for this purpose. It derives
> the common functions from arch/powerpc/sysdev/fsl_pci.c to
> drivers/pci/host/pcie-fsl.c and leaves several platform-dependent
> functions which should be implemented in platform files.
>
> Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
> ---
> Based on upstream master 3.11-rc6
> The function has been tested on P5020DS and P3041DS and T4240QDS boards
> For mpc83xx and mpc86xx, I only did compile test.
I assume you'll test on these (and older mpc85xx) before this becomes
non-RFC?
> arch/powerpc/Kconfig | 1 +
> arch/powerpc/sysdev/fsl_pci.c | 591 ++++++----------------------------
> arch/powerpc/sysdev/fsl_pci.h | 91 ------
> drivers/edac/mpc85xx_edac.c | 10 -
> drivers/pci/host/Kconfig | 4 +
> drivers/pci/host/Makefile | 1 +
> drivers/pci/host/pcie-fsl.c | 734 ++++++++++++++++++++++++++++++++++++++++++
> include/linux/fsl/fsl-pcie.h | 176 ++++++++++
> 8 files changed, 1008 insertions(+), 600 deletions(-)
> create mode 100644 drivers/pci/host/pcie-fsl.c
> create mode 100644 include/linux/fsl/fsl-pcie.h
Please use -M -C with git format-patch.
Why "pcie" rather than "pci"? Is non-express not supported by these new
files?
> @@ -259,15 +258,6 @@ int mpc85xx_pci_err_probe(struct platform_device *op)
>
> /* we only need the error registers */
> r.start += 0xe00;
> -
> - if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r),
> - pdata->name)) {
> - printk(KERN_ERR "%s: Error while requesting mem region\n",
> - __func__);
> - res = -EBUSY;
> - goto err;
> - }
> -
> pdata->pci_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r));
> if (!pdata->pci_vbase) {
> printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
Could you explain this part?
> diff --git a/drivers/pci/host/pcie-fsl.c b/drivers/pci/host/pcie-fsl.c
> new file mode 100644
> index 0000000..6e767d4
> --- /dev/null
> +++ b/drivers/pci/host/pcie-fsl.c
> @@ -0,0 +1,734 @@
> +/*
> + * 85xx/86xx/LS PCI/PCIE common driver support
> + *
> + * Copyright 2013 Freescale Semiconductor, Inc.
> + *
> + * Moved from arch/power/fsl_pci.c
That's not the right pathname.
> + *
> + * 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.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/pci.h>
> +#include <linux/string.h>
> +#include <linux/init.h>
> +#include <linux/log2.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_pci.h>
> +#include <linux/pci_regs.h>
> +#include <linux/platform_device.h>
> +#include <linux/resource.h>
> +#include <linux/types.h>
> +#include <linux/memblock.h>
> +#include <linux/fsl/fsl-pcie.h>
You don't need an "fsl-" prefix if it's in the "fsl/" directory.
> +static int fsl_pcie_write_config(struct fsl_pcie *pcie, int bus, int devfn,
> + int offset, int len, u32 val)
> +{
> + void __iomem *cfg_data;
> + u32 bus_no, reg;
> +
> + if (pcie->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) {
> + if (bus != pcie->first_busno)
> + return PCIBIOS_DEVICE_NOT_FOUND;
> + if (devfn != 0)
> + return PCIBIOS_DEVICE_NOT_FOUND;
> + }
> +
> + if (fsl_pci_exclude_device(pcie, bus, devfn))
> + return PCIBIOS_DEVICE_NOT_FOUND;
> +
> + bus_no = (bus == pcie->first_busno) ?
> + pcie->self_busno : bus;
> +
> + if (pcie->indirect_type & INDIRECT_TYPE_EXT_REG)
> + reg = ((offset & 0xf00) << 16) | (offset & 0xfc);
> + else
> + reg = offset & 0xfc;
> +
> + if (pcie->indirect_type & INDIRECT_TYPE_BIG_ENDIAN)
> + out_be32(&pcie->regs->config_addr,
> + (0x80000000 | (bus_no << 16) | (devfn << 8) | reg));
> + else
> + out_le32(&pcie->regs->config_addr,
> + (0x80000000 | (bus_no << 16) | (devfn << 8) | reg));
Did you try building this on ARM? out_be32/le32() is PPC-specific. Use iowrite32be()/iowrite32().
> +ep_mode:
> + dev_info(&pdev->dev, "It works as EP mode\n");
This is a bit casually phrased... and where did this come from? This
patch should just be about moving code around and removing PPC
dependencies (ideally even those two would be separate). If there's
new functionality or other changes it should be a separate patch.
> +static int __init fsl_pcie_probe(struct platform_device *pdev)
> +{
> + int ret;
> + struct fsl_pcie *pcie;
> +
> + if (!of_device_is_available(pdev->dev.of_node)) {
> + dev_err(&pdev->dev, "disabled\n");
> + return -ENODEV;
> + }
That's not an error.
-Scott
^ permalink raw reply
* Re: [PATCH v4 04/31] mtd: mpc5121_nfc: cleanup clock API use
From: Anatolij Gustschin @ 2013-08-23 21:47 UTC (permalink / raw)
To: Gerhard Sittig; +Cc: David Woodhouse, linuxppc-dev
In-Reply-To: <1375821851-31609-5-git-send-email-gsi@denx.de>
On Tue, 6 Aug 2013 22:43:44 +0200
Gerhard Sittig <gsi@denx.de> wrote:
> use devm_clk_get() for automatic put after device close, check for and
> propagate errors when enabling clocks, need to prepare clocks before
> they can get enabled, adjust error code paths to correctly balance
> get/put and prepare/unprepare and enable/disable calls
>
> Signed-off-by: Gerhard Sittig <gsi@denx.de>
> ---
> drivers/mtd/nand/mpc5121_nfc.c | 21 ++++++++++++---------
> 1 file changed, 12 insertions(+), 9 deletions(-)
Applied to mpc5xxx tree, thanks!
Anatolij
^ permalink raw reply
* Re: [PATCH v4 05/31] [media] fsl-viu: cleanup clock API use
From: Anatolij Gustschin @ 2013-08-23 21:48 UTC (permalink / raw)
To: Gerhard Sittig; +Cc: linuxppc-dev, Mauro Carvalho Chehab
In-Reply-To: <1375821851-31609-6-git-send-email-gsi@denx.de>
On Tue, 6 Aug 2013 22:43:45 +0200
Gerhard Sittig <gsi@denx.de> wrote:
> use devm_clk_get() for automatic put after device close, check for and
> propagate errors when enabling clocks, need to prepare clocks before
> they can get enabled, adjust code paths to correctly balance get/put and
> prepare/unprepare and enable/disable calls
>
> Signed-off-by: Gerhard Sittig <gsi@denx.de>
> ---
> drivers/media/platform/fsl-viu.c | 23 +++++++++++++----------
> 1 file changed, 13 insertions(+), 10 deletions(-)
Applied to mpc5xxx tree, thanks!
Anatolij
^ permalink raw reply
* Re: [PATCH v4 12/31] powerpc: mpc512x: array decl for MCLK registers in CCM
From: Anatolij Gustschin @ 2013-08-23 21:49 UTC (permalink / raw)
To: Gerhard Sittig; +Cc: linuxppc-dev
In-Reply-To: <1375821851-31609-13-git-send-email-gsi@denx.de>
On Tue, 6 Aug 2013 22:43:52 +0200
Gerhard Sittig <gsi@denx.de> wrote:
> reword the clock control module's registers declaration such that the
> MCLK related registers form an array and get indexed by PSC controller
> or CAN controller component number
>
> this change is in preparation to COMMON_CLK support for the MPC512x
> platform, the changed declaration remains neutral to existing code since
> the PSC and MSCAN CCR fields declared here aren't referenced anywhere
>
> Signed-off-by: Gerhard Sittig <gsi@denx.de>
> ---
> arch/powerpc/include/asm/mpc5121.h | 18 ++----------------
> 1 file changed, 2 insertions(+), 16 deletions(-)
Applied, thanks!
Anatolij
^ permalink raw reply
* Re: [PATCH v3 13/31] clk: wrap I/O access for improved portability
From: Anatolij Gustschin @ 2013-08-23 22:05 UTC (permalink / raw)
To: Mike Turquette; +Cc: Gerhard Sittig, linuxppc-dev, linux-arm-kernel
In-Reply-To: <20130802223000.6450.97817@quantum>
On Fri, 02 Aug 2013 15:30:00 -0700
Mike Turquette <mturquette@linaro.org> wrote:
> Quoting Gerhard Sittig (2013-07-22 05:14:40)
> > the common clock drivers were motivated/initiated by ARM development
> > and apparently assume little endian peripherals
> >
> > wrap register/peripherals access in the common code (div, gate, mux)
> > in preparation of adding COMMON_CLK support for other platforms
> >
> > Signed-off-by: Gerhard Sittig <gsi@denx.de>
>
> I've taken this into clk-next for testing. regmap deserves investigation
> but I don't think your series should be blocked on that. We can always
> overhaul the basic clock primitives with regmap support later on if that
> makes sense.
Mike, I cannot see it in clk-next branch of
git://git.linaro.org/people/mturquette/linux.git
Can you please check? Or am I looking in the wrong place?
Thanks,
Anatolij
^ permalink raw reply
* Re: [PATCH v4 14/31] dts: mpc512x: prepare for preprocessor support
From: Anatolij Gustschin @ 2013-08-23 22:18 UTC (permalink / raw)
To: Gerhard Sittig; +Cc: devicetree, linuxppc-dev
In-Reply-To: <1375821851-31609-15-git-send-email-gsi@denx.de>
On Tue, 6 Aug 2013 22:43:54 +0200
Gerhard Sittig <gsi@denx.de> wrote:
> prepare C preprocessor support when processing MPC512x DTS files
> - switch from DTS syntax to CPP syntax for include specs
> - create a symlink such that DTS processing can reference includes
>
> Signed-off-by: Gerhard Sittig <gsi@denx.de>
> ---
> arch/powerpc/boot/dts/ac14xx.dts | 2 +-
> arch/powerpc/boot/dts/include/dt-bindings | 1 +
> arch/powerpc/boot/dts/mpc5121ads.dts | 2 +-
> arch/powerpc/boot/dts/pdm360ng.dts | 2 +-
> 4 files changed, 4 insertions(+), 3 deletions(-)
> create mode 120000 arch/powerpc/boot/dts/include/dt-bindings
Applied, thanks!
Anatolij
^ permalink raw reply
* Re: [PATCH] powerpc/ppc64: remove __volatile__ in get_current()
From: James Yang @ 2013-08-23 23:40 UTC (permalink / raw)
To: James Yang; +Cc: scottwood, linuxppc-dev
In-Reply-To: <1376110162-3462-1-git-send-email-James.Yang@freescale.com>
On Sat, 10 Aug 2013, James Yang wrote:
> Uses of get_current() that normally get optimized away still result in
> a load instruction of the current pointer in 64-bit because the inline
> asm uses __volatile__. This patch removes __volatile__ so that nop-ed
> uses of get_current() don't actually result in a load of the pointer.
>
> Signed-off-by: James Yang <James.Yang@freescale.com>
> ---
> arch/powerpc/include/asm/current.h | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/current.h b/arch/powerpc/include/asm/current.h
> index e2c7f06..bb250c8 100644
> --- a/arch/powerpc/include/asm/current.h
> +++ b/arch/powerpc/include/asm/current.h
> @@ -19,7 +19,7 @@ static inline struct task_struct *get_current(void)
> {
> struct task_struct *task;
>
> - __asm__ __volatile__("ld %0,%1(13)"
> + __asm__ ("ld %0,%1(13)"
> : "=r" (task)
> : "i" (offsetof(struct paca_struct, __current)));
Hello,
Scott's been able to put enough doubt in me to think that this is not
entirely safe, even though the testing and code generation show it to
work. Please reject this patch.
I think there is still value in getting the unnecessary loads to be
removed since it would also allow unnecessary conditional branches to
be removed. I'll think about alternate ways to do this.
Regards,
--James
^ permalink raw reply
* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Anthony Foiani @ 2013-08-23 23:41 UTC (permalink / raw)
To: Scott Wood
Cc: Adrian Bunk, Robert P.J.Day, linuxppc-dev@lists.ozlabs.org,
Shaohui.Xie, Li Yang-R58472
In-Reply-To: <20130823192532.GA29205@home.buserror.net>
Scott Wood <scottwood@freescale.com> writes:
>> --- a/Documentation/devicetree/bindings/powerpc/fsl/board.txt
>> +++ b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
>
> This should go in Documentation/devicetree/bindings/ata/fsl-sata.txt.
Ok, will change.
> As for the property name, I'd prefer "fsl,sata-speed-limit" or
> "fsl,sata-max-generation".
In my original patch:
http://article.gmane.org/gmane.linux.ports.ppc.embedded/58710
I used "fsl,sata-max-gen". I thought Jeff disliked it, so I changed
it be more generic -- but maybe I misread his complaint. (And while
his opinions are still respected, new maintainers might have different
tastes.)
I think my logic was that there exist "sata_spd_limit" and related
functions in the ata core, so I should mirror that in the dev tree.
No guarantees, though -- it's been a while since I wrote that code.
> Shaohui, do the driver bits look OK?
> This patch should go via the linux-scsi list (note that Tejun Heo is
> now the SATA maintainer).
linux-scsi, or linux-ide? My other recent change to sata_fsl went
through the latter.
Thanks for the review / comments. Let me know how you'd like to
proceed on the above points, and I can resubmit (as a proper patch for
easier tracking).
Best regards,
Anthony Foiani
^ permalink raw reply
* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Scott Wood @ 2013-08-23 23:47 UTC (permalink / raw)
To: Anthony Foiani
Cc: Adrian Bunk, Robert P.J.Day, linuxppc-dev@lists.ozlabs.org,
Shaohui.Xie, Li Yang-R58472
In-Reply-To: <gppt4gel1.fsf@dworkin.scrye.com>
On Fri, 2013-08-23 at 17:41 -0600, Anthony Foiani wrote:
> Scott Wood <scottwood@freescale.com> writes:
>
> >> --- a/Documentation/devicetree/bindings/powerpc/fsl/board.txt
> >> +++ b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
> >
> > This should go in Documentation/devicetree/bindings/ata/fsl-sata.txt.
>
> Ok, will change.
>
> > As for the property name, I'd prefer "fsl,sata-speed-limit" or
> > "fsl,sata-max-generation".
>
> In my original patch:
>
> http://article.gmane.org/gmane.linux.ports.ppc.embedded/58710
>
> I used "fsl,sata-max-gen". I thought Jeff disliked it, so I changed
> it be more generic -- but maybe I misread his complaint. (And while
> his opinions are still respected, new maintainers might have different
> tastes.)
I didn't see anything to that effect from Jeff in that thread -- maybe
it was elsewhere.
> I think my logic was that there exist "sata_spd_limit" and related
> functions in the ata core, so I should mirror that in the dev tree.
> No guarantees, though -- it's been a while since I wrote that code.
The device tree describes the hardware, not the driver -- and thus
should be free to use clearer wording. :-)
As for fsl-specific versus generic, generic is fine but then it needs to
be documented in a generic place.
> > Shaohui, do the driver bits look OK?
>
> > This patch should go via the linux-scsi list (note that Tejun Heo is
> > now the SATA maintainer).
>
> linux-scsi, or linux-ide? My other recent change to sata_fsl went
> through the latter.
Sorry, linux-ide.
-Scott
^ permalink raw reply
* Re: [PATCH] powerpc/ppc64: remove __volatile__ in get_current()
From: Scott Wood @ 2013-08-23 23:48 UTC (permalink / raw)
To: James Yang; +Cc: linuxppc-dev
In-Reply-To: <alpine.LRH.2.00.1308231832570.4940@ra8135-ec1.am.freescale.net>
On Fri, 2013-08-23 at 18:40 -0500, James Yang wrote:
> On Sat, 10 Aug 2013, James Yang wrote:
>
> > Uses of get_current() that normally get optimized away still result in
> > a load instruction of the current pointer in 64-bit because the inline
> > asm uses __volatile__. This patch removes __volatile__ so that nop-ed
> > uses of get_current() don't actually result in a load of the pointer.
> >
> > Signed-off-by: James Yang <James.Yang@freescale.com>
> > ---
> > arch/powerpc/include/asm/current.h | 2 +-
> > 1 files changed, 1 insertions(+), 1 deletions(-)
> >
> > diff --git a/arch/powerpc/include/asm/current.h b/arch/powerpc/include/asm/current.h
> > index e2c7f06..bb250c8 100644
> > --- a/arch/powerpc/include/asm/current.h
> > +++ b/arch/powerpc/include/asm/current.h
> > @@ -19,7 +19,7 @@ static inline struct task_struct *get_current(void)
> > {
> > struct task_struct *task;
> >
> > - __asm__ __volatile__("ld %0,%1(13)"
> > + __asm__ ("ld %0,%1(13)"
> > : "=r" (task)
> > : "i" (offsetof(struct paca_struct, __current)));
>
>
> Hello,
>
> Scott's been able to put enough doubt in me to think that this is not
> entirely safe, even though the testing and code generation show it to
> work. Please reject this patch.
>
> I think there is still value in getting the unnecessary loads to be
> removed since it would also allow unnecessary conditional branches to
> be removed. I'll think about alternate ways to do this.
Actually, I changed my mind in the other direction in parallel. :-P
I think it's probably safe.
-Scott
^ permalink raw reply
* Re: [v2] powerpc/85xx: Add P1023RDB board support
From: Scott Wood @ 2013-08-24 0:09 UTC (permalink / raw)
To: Chunhe Lan; +Cc: linuxppc-dev
In-Reply-To: <1375184429-22145-1-git-send-email-Chunhe.Lan@freescale.com>
On Tue, Jul 30, 2013 at 07:40:29PM +0800, Chunhe Lan wrote:
> P1023RDB Specification:
> -----------------------
> Memory subsystem:
> 512MB DDR3 (Fixed DDR on board)
> 64MB NOR flash
> 128MB NAND flash
>
> Ethernet:
> eTSEC1: Connected to Atheros AR8035 GETH PHY
> eTSEC2: Connected to Atheros AR8035 GETH PHY
>
> PCIe:
> Three mini-PCIe slots
>
> USB:
> Two USB2.0 Type A ports
>
> I2C:
> AT24C08 8K Board EEPROM (8 bit address)
>
> Signed-off-by: Chunhe Lan <Chunhe.Lan@freescale.com>
> Cc: Scott Wood <scottwood@freescale.com>
>
> ---
No changelog since v1...
> + nor@0,0 {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "cfi-flash";
> + reg = <0x0 0x0 0x04000000>;
> + bank-width = <2>;
> + device-width = <1>;
> +
> + partition@0 {
> + /* 48MB for JFFS2 based Root file System */
> + reg = <0x00000000 0x03000000>;
> + label = "NOR JFFS2 Root File System";
> + };
Don't specify JFFS2.
> + partition@1000000 {
> + /* 32MB for Compressed Root file System Image */
> + reg = <0x01000000 0x02000000>;
> + label = "NAND Compressed RFS Image";
> + };
> +
> + partition@3000000 {
> + /* 64MB for JFFS2 based Root file System */
> + reg = <0x03000000 0x04000000>;
> + label = "NAND JFFS2 Root File System";
> + };
> +
> + partition@7000000 {
> + /* 16MB for User Writable Area */
> + reg = <0x07000000 0x01000000>;
> + label = "NAND Writable User area";
> + };
Don't specify JFFS2.
Why three separate partitions instead of one? At least the two RFS
partitions should be merged.
> + board_pci1: pci1: pcie@ff609000 {
You don't need more than one label on a node.
> diff --git a/arch/powerpc/configs/85xx/p1023_defconfig b/arch/powerpc/configs/85xx/p1023_defconfig
> new file mode 100644
> index 0000000..ac29fb8
> --- /dev/null
> +++ b/arch/powerpc/configs/85xx/p1023_defconfig
While I can understand p1023 wanting a separate defconfig once we get
datapath support (it's the only e500v2 chip with datapath, so we probably
don't want to burden mpc85xx_smp_defconfig with it), but I don't see why
we need a separate config right now.
> +# CONFIG_DEBUG_BUGVERBOSE is not set
Please don't disable this. It's very useful for interpreting bug reports
and has minimal cost.
> diff --git a/arch/powerpc/configs/85xx/p1023rds_defconfig b/arch/powerpc/configs/85xx/p1023rds_defconfig
> deleted file mode 100644
> index b80bcc6..0000000
> --- a/arch/powerpc/configs/85xx/p1023rds_defconfig
> +++ /dev/null
> @@ -1,169 +0,0 @@
> -CONFIG_PPC_85xx=y
> -CONFIG_SMP=y
> -CONFIG_NR_CPUS=2
Oh, you were just moving this. Please use "-M -C" with git format-patch
so such things are more obvious.
> diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
> index efdd37c..d6424e9 100644
> --- a/arch/powerpc/platforms/85xx/Kconfig
> +++ b/arch/powerpc/platforms/85xx/Kconfig
> @@ -112,10 +112,10 @@ config P1022_RDK
> reference board.
>
> config P1023_RDS
> - bool "Freescale P1023 RDS"
> + bool "Freescale P1023 RDS (P1023 RDB)"
> select DEFAULT_UIMAGE
> help
> - This option enables support for the P1023 RDS board
> + This option enables support for the P1023 RDS (P1023 RDB) board
>
> config SOCRATES
> bool "Socrates"
I'd just say "P1023 RDS/RDB".
> +static int __init p1023_rdb_probe(void)
> +{
> + unsigned long root = of_get_flat_dt_root();
> +
> + return of_flat_dt_is_compatible(root, "fsl,P1023RDB");
> +
> +}
Remove the blank line at the end of the function.
-Scott
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox