summaryrefslogtreecommitdiff
path: root/drivers/crypto/inside-secure/safexcel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/crypto/inside-secure/safexcel.c')
-rw-r--r--drivers/crypto/inside-secure/safexcel.c134
1 files changed, 83 insertions, 51 deletions
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
index ad0d8c4a71ac..c3b2b22934b7 100644
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -316,14 +316,20 @@ static void eip197_init_firmware(struct safexcel_crypto_priv *priv)
static int eip197_write_firmware(struct safexcel_crypto_priv *priv,
const struct firmware *fw)
{
- const __be32 *data = (const __be32 *)fw->data;
+ u32 val;
int i;
/* Write the firmware */
- for (i = 0; i < fw->size / sizeof(u32); i++)
- writel(be32_to_cpu(data[i]),
+ for (i = 0; i < fw->size / sizeof(u32); i++) {
+ if (priv->data->fw_little_endian)
+ val = le32_to_cpu(((const __le32 *)fw->data)[i]);
+ else
+ val = be32_to_cpu(((const __be32 *)fw->data)[i]);
+
+ writel(val,
priv->base + EIP197_CLASSIFICATION_RAMS +
- i * sizeof(__be32));
+ i * sizeof(val));
+ }
/* Exclude final 2 NOPs from size */
return i - EIP197_FW_TERMINAL_NOPS;
@@ -410,11 +416,13 @@ static int eip197_load_firmwares(struct safexcel_crypto_priv *priv)
int i, j, ret = 0, pe;
int ipuesz, ifppsz, minifw = 0;
- if (priv->version == EIP197D_MRVL)
+ if (priv->data->version == EIP197D_MRVL)
dir = "eip197d";
- else if (priv->version == EIP197B_MRVL ||
- priv->version == EIP197_DEVBRD)
+ else if (priv->data->version == EIP197B_MRVL ||
+ priv->data->version == EIP197_DEVBRD)
dir = "eip197b";
+ else if (priv->data->version == EIP197C_MXL)
+ dir = "eip197c";
else
return -ENODEV;
@@ -423,7 +431,7 @@ retry_fw:
snprintf(fw_path, 37, "inside-secure/%s/%s", dir, fw_name[i]);
ret = firmware_request_nowarn(&fw[i], fw_path, priv->dev);
if (ret) {
- if (minifw || priv->version != EIP197B_MRVL)
+ if (minifw || priv->data->version != EIP197B_MRVL)
goto release_fw;
/* Fallback to the old firmware location for the
@@ -466,7 +474,7 @@ release_fw:
goto retry_fw;
}
- dev_dbg(priv->dev, "Firmware load failed.\n");
+ dev_err(priv->dev, "Firmware load failed.\n");
return ret;
}
@@ -842,7 +850,7 @@ handle_req:
goto request_failed;
if (backlog)
- backlog->complete(backlog, -EINPROGRESS);
+ crypto_request_complete(backlog, -EINPROGRESS);
/* In case the send() helper did not issue any command to push
* to the engine because the input data was cached, continue to
@@ -962,17 +970,6 @@ void safexcel_complete(struct safexcel_crypto_priv *priv, int ring)
} while (!cdesc->last_seg);
}
-void safexcel_inv_complete(struct crypto_async_request *req, int error)
-{
- struct safexcel_inv_result *result = req->data;
-
- if (error == -EINPROGRESS)
- return;
-
- result->error = error;
- complete(&result->completion);
-}
-
int safexcel_invalidate_cache(struct crypto_async_request *async,
struct safexcel_crypto_priv *priv,
dma_addr_t ctxr_dma, int ring)
@@ -1042,7 +1039,7 @@ handle_results:
if (should_complete) {
local_bh_disable();
- req->complete(req, ret);
+ crypto_request_complete(req, ret);
local_bh_enable();
}
@@ -1194,8 +1191,6 @@ static struct safexcel_alg_template *safexcel_algs[] = {
&safexcel_alg_cbc_des3_ede,
&safexcel_alg_ecb_aes,
&safexcel_alg_cbc_aes,
- &safexcel_alg_cfb_aes,
- &safexcel_alg_ofb_aes,
&safexcel_alg_ctr_aes,
&safexcel_alg_md5,
&safexcel_alg_sha1,
@@ -1223,7 +1218,6 @@ static struct safexcel_alg_template *safexcel_algs[] = {
&safexcel_alg_xts_aes,
&safexcel_alg_gcm,
&safexcel_alg_ccm,
- &safexcel_alg_crc32,
&safexcel_alg_cbcmac,
&safexcel_alg_xcbcmac,
&safexcel_alg_cmac,
@@ -1234,8 +1228,6 @@ static struct safexcel_alg_template *safexcel_algs[] = {
&safexcel_alg_hmac_sm3,
&safexcel_alg_ecb_sm4,
&safexcel_alg_cbc_sm4,
- &safexcel_alg_ofb_sm4,
- &safexcel_alg_cfb_sm4,
&safexcel_alg_ctr_sm4,
&safexcel_alg_authenc_hmac_sha1_cbc_sm4,
&safexcel_alg_authenc_hmac_sm3_cbc_sm4,
@@ -1597,7 +1589,7 @@ static int safexcel_probe_generic(void *pdev,
safexcel_configure(priv);
- if (IS_ENABLED(CONFIG_PCI) && priv->version == EIP197_DEVBRD) {
+ if (IS_ENABLED(CONFIG_PCI) && priv->data->version == EIP197_DEVBRD) {
/*
* Request MSI vectors for global + 1 per ring -
* or just 1 for older dev images
@@ -1631,19 +1623,23 @@ static int safexcel_probe_generic(void *pdev,
&priv->ring[i].rdr);
if (ret) {
dev_err(dev, "Failed to initialize rings\n");
- return ret;
+ goto err_cleanup_rings;
}
priv->ring[i].rdr_req = devm_kcalloc(dev,
EIP197_DEFAULT_RING_SIZE,
sizeof(*priv->ring[i].rdr_req),
GFP_KERNEL);
- if (!priv->ring[i].rdr_req)
- return -ENOMEM;
+ if (!priv->ring[i].rdr_req) {
+ ret = -ENOMEM;
+ goto err_cleanup_rings;
+ }
ring_irq = devm_kzalloc(dev, sizeof(*ring_irq), GFP_KERNEL);
- if (!ring_irq)
- return -ENOMEM;
+ if (!ring_irq) {
+ ret = -ENOMEM;
+ goto err_cleanup_rings;
+ }
ring_irq->priv = priv;
ring_irq->ring = i;
@@ -1657,7 +1653,8 @@ static int safexcel_probe_generic(void *pdev,
ring_irq);
if (irq < 0) {
dev_err(dev, "Failed to get IRQ ID for ring %d\n", i);
- return irq;
+ ret = irq;
+ goto err_cleanup_rings;
}
priv->ring[i].irq = irq;
@@ -1669,8 +1666,10 @@ static int safexcel_probe_generic(void *pdev,
snprintf(wq_name, 9, "wq_ring%d", i);
priv->ring[i].workqueue =
create_singlethread_workqueue(wq_name);
- if (!priv->ring[i].workqueue)
- return -ENOMEM;
+ if (!priv->ring[i].workqueue) {
+ ret = -ENOMEM;
+ goto err_cleanup_rings;
+ }
priv->ring[i].requests = 0;
priv->ring[i].busy = false;
@@ -1687,16 +1686,26 @@ static int safexcel_probe_generic(void *pdev,
ret = safexcel_hw_init(priv);
if (ret) {
dev_err(dev, "HW init failed (%d)\n", ret);
- return ret;
+ goto err_cleanup_rings;
}
ret = safexcel_register_algorithms(priv);
if (ret) {
dev_err(dev, "Failed to register algorithms (%d)\n", ret);
- return ret;
+ goto err_cleanup_rings;
}
return 0;
+
+err_cleanup_rings:
+ for (i = 0; i < priv->config.rings; i++) {
+ if (priv->ring[i].irq)
+ irq_set_affinity_hint(priv->ring[i].irq, NULL);
+ if (priv->ring[i].workqueue)
+ destroy_workqueue(priv->ring[i].workqueue);
+ }
+
+ return ret;
}
static void safexcel_hw_reset_rings(struct safexcel_crypto_priv *priv)
@@ -1731,7 +1740,7 @@ static int safexcel_probe(struct platform_device *pdev)
return -ENOMEM;
priv->dev = dev;
- priv->version = (enum safexcel_eip_version)of_device_get_match_data(dev);
+ priv->data = (struct safexcel_priv_data *)of_device_get_match_data(dev);
platform_set_drvdata(pdev, priv);
@@ -1787,7 +1796,7 @@ err_core_clk:
return ret;
}
-static int safexcel_remove(struct platform_device *pdev)
+static void safexcel_remove(struct platform_device *pdev)
{
struct safexcel_crypto_priv *priv = platform_get_drvdata(pdev);
int i;
@@ -1802,31 +1811,54 @@ static int safexcel_remove(struct platform_device *pdev)
irq_set_affinity_hint(priv->ring[i].irq, NULL);
destroy_workqueue(priv->ring[i].workqueue);
}
-
- return 0;
}
+static const struct safexcel_priv_data eip97ies_mrvl_data = {
+ .version = EIP97IES_MRVL,
+};
+
+static const struct safexcel_priv_data eip197b_mrvl_data = {
+ .version = EIP197B_MRVL,
+};
+
+static const struct safexcel_priv_data eip197d_mrvl_data = {
+ .version = EIP197D_MRVL,
+};
+
+static const struct safexcel_priv_data eip197_devbrd_data = {
+ .version = EIP197_DEVBRD,
+};
+
+static const struct safexcel_priv_data eip197c_mxl_data = {
+ .version = EIP197C_MXL,
+ .fw_little_endian = true,
+};
+
static const struct of_device_id safexcel_of_match_table[] = {
{
.compatible = "inside-secure,safexcel-eip97ies",
- .data = (void *)EIP97IES_MRVL,
+ .data = &eip97ies_mrvl_data,
},
{
.compatible = "inside-secure,safexcel-eip197b",
- .data = (void *)EIP197B_MRVL,
+ .data = &eip197b_mrvl_data,
},
{
.compatible = "inside-secure,safexcel-eip197d",
- .data = (void *)EIP197D_MRVL,
+ .data = &eip197d_mrvl_data,
+ },
+ {
+ .compatible = "inside-secure,safexcel-eip197c-mxl",
+ .data = &eip197c_mxl_data,
},
/* For backward compatibility and intended for generic use */
{
.compatible = "inside-secure,safexcel-eip97",
- .data = (void *)EIP97IES_MRVL,
+ .data = &eip97ies_mrvl_data,
},
{
.compatible = "inside-secure,safexcel-eip197",
- .data = (void *)EIP197B_MRVL,
+ .data = &eip197b_mrvl_data,
},
{},
};
@@ -1862,7 +1894,7 @@ static int safexcel_pci_probe(struct pci_dev *pdev,
return -ENOMEM;
priv->dev = dev;
- priv->version = (enum safexcel_eip_version)ent->driver_data;
+ priv->data = (struct safexcel_priv_data *)ent->driver_data;
pci_set_drvdata(pdev, priv);
@@ -1881,7 +1913,7 @@ static int safexcel_pci_probe(struct pci_dev *pdev,
}
priv->base = pcim_iomap_table(pdev)[0];
- if (priv->version == EIP197_DEVBRD) {
+ if (priv->data->version == EIP197_DEVBRD) {
dev_dbg(dev, "Device identified as FPGA based development board - applying HW reset\n");
rc = pcim_iomap_regions(pdev, 4, "crypto_safexcel");
@@ -1949,7 +1981,7 @@ static const struct pci_device_id safexcel_pci_ids[] = {
{
PCI_DEVICE_SUB(PCI_VENDOR_ID_XILINX, 0x9038,
0x16ae, 0xc522),
- .driver_data = EIP197_DEVBRD,
+ .driver_data = (kernel_ulong_t)&eip197_devbrd_data,
},
{},
};
@@ -1998,7 +2030,7 @@ MODULE_AUTHOR("Ofer Heifetz <oferh@marvell.com>");
MODULE_AUTHOR("Igal Liberman <igall@marvell.com>");
MODULE_DESCRIPTION("Support for SafeXcel cryptographic engines: EIP97 & EIP197");
MODULE_LICENSE("GPL v2");
-MODULE_IMPORT_NS(CRYPTO_INTERNAL);
+MODULE_IMPORT_NS("CRYPTO_INTERNAL");
MODULE_FIRMWARE("ifpp.bin");
MODULE_FIRMWARE("ipue.bin");