summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTudor Ambarus <tudor.ambarus@freescale.com>2015-05-15 13:48:49 (GMT)
committerHonghua Yin <Hong-Hua.Yin@freescale.com>2015-05-21 02:25:04 (GMT)
commit7191bc627c7038611663f90c7dd053733bc5586b (patch)
tree38caa2b183972d74ab8b09f76939a0de730aae16
parentcffaa48ffefae00664bdb0bba446e9de799afe23 (diff)
downloadlinux-fsl-qoriq-7191bc627c7038611663f90c7dd053733bc5586b.tar.xz
crypto: caampkc - workaround for erratum A-006899
The problem will occur only in T1040R1. A workaround has been verified; set a Scatter Gather (SG) flag on the Q or G Pointers on KPG, which will give the PKHA unload time to complete. It's sufficient to have the SG flag set for only one of these. Change-Id: I5a403576c6e995110227872c84de7e74da0144c5 Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/36617 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Horia Ioan Geanta Neag <horia.geanta@freescale.com> Reviewed-by: Honghua Yin <Hong-Hua.Yin@freescale.com>
-rw-r--r--drivers/crypto/caam/caampkc.c35
-rw-r--r--drivers/crypto/caam/ctrl.c8
-rw-r--r--drivers/crypto/caam/intern.h5
-rw-r--r--drivers/crypto/caam/pkc_desc.c9
-rw-r--r--drivers/crypto/caam/pkc_desc.h4
-rw-r--r--drivers/crypto/caam/regs.h2
-rw-r--r--drivers/crypto/caam/sg_sw_sec4.h12
7 files changed, 60 insertions, 15 deletions
diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c
index f98abfb..e9944a4 100644
--- a/drivers/crypto/caam/caampkc.c
+++ b/drivers/crypto/caam/caampkc.c
@@ -30,6 +30,12 @@ struct caam_pkc_context_s {
struct device *dev;
};
+struct caam_pkc_alg {
+ struct list_head entry;
+ struct device *ctrldev;
+ struct crypto_alg crypto_alg;
+};
+
static void rsa_unmap(struct device *dev,
struct rsa_edesc *edesc, struct pkc_request *req)
{
@@ -484,6 +490,10 @@ static int caam_keygen_edesc(struct pkc_request *req,
{
struct crypto_pkc *tfm = crypto_pkc_reqtfm(req);
struct caam_pkc_context_s *ctxt = crypto_pkc_ctx(tfm);
+ struct crypto_alg *alg = crypto_pkc_tfm(tfm)->__crt_alg;
+ struct caam_pkc_alg *caam_alg =
+ container_of(alg, struct caam_pkc_alg, crypto_alg);
+ struct caam_drv_private *caam_priv = dev_get_drvdata(caam_alg->ctrldev);
struct device *dev = ctxt->dev;
struct keygen_req_s *key_req = &req->req_u.keygen;
@@ -491,6 +501,7 @@ static int caam_keygen_edesc(struct pkc_request *req,
edesc->n_len = key_req->r_len;
edesc->req_type = req->type;
edesc->curve_type = req->curve_type;
+ edesc->erratum_A_006899 = caam_priv->errata & SEC_ERRATUM_A_006899;
edesc->q_dma = dma_map_single(dev, key_req->q, key_req->q_len,
DMA_TO_DEVICE);
@@ -513,6 +524,20 @@ static int caam_keygen_edesc(struct pkc_request *req,
goto g_map_fail;
}
+ if (edesc->erratum_A_006899) {
+ dma_to_sec4_sg_one(&(edesc->g_sg), edesc->g_dma,
+ key_req->g_len, 0);
+ edesc->g_sg.len |= SEC4_SG_LEN_FIN;
+
+ edesc->g_sg_dma = dma_map_single(dev, &(edesc->g_sg),
+ sizeof(struct sec4_sg_entry),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(dev, edesc->g_sg_dma)) {
+ dev_err(dev, "unable to map S/G table\n");
+ goto g_sg_dma_fail;
+ }
+ }
+
edesc->key_dma = dma_map_single(dev, key_req->pub_key,
key_req->pub_key_len, DMA_FROM_DEVICE);
if (dma_mapping_error(dev, edesc->key_dma)) {
@@ -545,6 +570,10 @@ s_map_fail:
dma_unmap_single(dev, edesc->key_dma, key_req->pub_key_len,
DMA_FROM_DEVICE);
key_map_fail:
+ if (edesc->erratum_A_006899)
+ dma_unmap_single(dev, edesc->g_sg_dma, key_req->g_len,
+ DMA_TO_DEVICE);
+g_sg_dma_fail:
dma_unmap_single(dev, edesc->g_dma, key_req->g_len, DMA_TO_DEVICE);
g_map_fail:
dma_unmap_single(dev, edesc->r_dma, key_req->r_len, DMA_TO_DEVICE);
@@ -1324,12 +1353,6 @@ static struct caam_pkc_template driver_pkc[] = {
}
};
-struct caam_pkc_alg {
- struct list_head entry;
- struct device *ctrldev;
- struct crypto_alg crypto_alg;
-};
-
/* Per session pkc's driver context creation function */
static int caam_pkc_cra_init(struct crypto_tfm *tfm)
{
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 7a22427..321deb0 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -480,6 +480,7 @@ static int caam_probe(struct platform_device *pdev)
{
int ret, ring, rspec;
u64 caam_id;
+ u32 caam_id_ms;
struct device *dev;
struct device_node *nprop, *np;
struct caam_ctrl __iomem *ctrl;
@@ -660,7 +661,12 @@ static int caam_probe(struct platform_device *pdev)
/* NOTE: RTIC detection ought to go here, around Si time */
ctrlpriv->era = caam_get_era();
- caam_id = (u64)rd_reg32(&ctrl->perfmon.caam_id_ms) << 32 |
+
+ caam_id_ms = rd_reg32(&ctrl->perfmon.caam_id_ms);
+ if (caam_id_ms == SEC_ID_MS_T1040)
+ ctrlpriv->errata |= SEC_ERRATUM_A_006899;
+
+ caam_id = (u64)caam_id_ms << 32 |
(u64)rd_reg32(&ctrl->perfmon.caam_id_ls);
/* Report "alive" for developer to see */
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index 43596fe..9faf832 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -95,6 +95,11 @@ struct caam_drv_private {
struct list_head pkc_list;
int era; /* SEC Era */
+
+#define SEC_ERRATUM_A_006899 0x01
+ /* SEC errata bitmask */
+ u32 errata;
+
int virt_en; /* Virtualization enabled in CAAM */
#define RNG4_MAX_HANDLES 2
diff --git a/drivers/crypto/caam/pkc_desc.c b/drivers/crypto/caam/pkc_desc.c
index 5bcf5d3..2e81519 100644
--- a/drivers/crypto/caam/pkc_desc.c
+++ b/drivers/crypto/caam/pkc_desc.c
@@ -271,10 +271,15 @@ void *caam_keygen_desc(struct dsa_edesc_s *edesc)
(start_idx << HDR_START_IDX_SHIFT) |
(start_idx & HDR_DESCLEN_MASK) | HDR_ONE);
ecc_desc->sgf_ln = (edesc->l_len << DSA_PDB_L_SHIFT) |
- ((edesc->n_len & DSA_PDB_N_MASK));
+ (edesc->n_len & DSA_PDB_N_MASK);
+ if (edesc->erratum_A_006899) {
+ ecc_desc->sgf_ln |= DSA_PDB_SGF_G;
+ ecc_desc->g_dma = edesc->g_sg_dma;
+ } else {
+ ecc_desc->g_dma = edesc->g_dma;
+ }
ecc_desc->q_dma = edesc->q_dma;
ecc_desc->r_dma = edesc->r_dma;
- ecc_desc->g_dma = edesc->g_dma;
ecc_desc->s_dma = edesc->s_dma;
ecc_desc->w_dma = edesc->key_dma;
ecc_desc->ab_dma = edesc->ab_dma;
diff --git a/drivers/crypto/caam/pkc_desc.h b/drivers/crypto/caam/pkc_desc.h
index 03013c2..e859e40 100644
--- a/drivers/crypto/caam/pkc_desc.h
+++ b/drivers/crypto/caam/pkc_desc.h
@@ -20,6 +20,7 @@
#include "desc_constr.h"
#include "jr.h"
#include "error.h"
+#include "sg_sw_sec4.h"
#include <linux/crypto.h>
#include "pdb.h"
@@ -187,8 +188,11 @@ struct dsa_edesc_s {
dma_addr_t d_dma;
dma_addr_t ab_dma;
dma_addr_t g_dma;
+ dma_addr_t g_sg_dma;
dma_addr_t tmp_dma;
uint8_t *tmp; /* Allocate locally for dsa_verify */
+ struct sec4_sg_entry g_sg;
+ bool erratum_A_006899;
u32 hw_desc[];
};
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index 928cb53..72193f8 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -182,6 +182,8 @@ struct sec_vid {
u8 min_rev;
};
+#define SEC_ID_MS_T1040 0x0A120400
+
struct caam_perfmon {
/* Performance Monitor Registers f00-f9f */
u64 req_dequeued; /* PC_REQ_DEQ - Dequeued Requests */
diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h
index eef6345..752134c 100644
--- a/drivers/crypto/caam/sg_sw_sec4.h
+++ b/drivers/crypto/caam/sg_sw_sec4.h
@@ -90,9 +90,9 @@ static inline int sg_count(struct scatterlist *sg_list, int nbytes,
return sg_nents;
}
-static int dma_map_sg_chained(struct device *dev, struct scatterlist *sg,
- unsigned int nents, enum dma_data_direction dir,
- bool chained)
+static int __maybe_unused dma_map_sg_chained(struct device *dev,
+ struct scatterlist *sg, unsigned int nents, enum dma_data_direction dir,
+ bool chained)
{
if (!sg || !nents)
return 0;
@@ -109,9 +109,9 @@ static int dma_map_sg_chained(struct device *dev, struct scatterlist *sg,
return nents;
}
-static void dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg,
- unsigned int nents, enum dma_data_direction dir,
- bool chained)
+static void __maybe_unused dma_unmap_sg_chained(struct device *dev,
+ struct scatterlist *sg, unsigned int nents, enum dma_data_direction dir,
+ bool chained)
{
if (!sg || !nents)
return;