Hi,
I have been utilizing inside-secure driver on MaxLinear
SoC platform (which has eip197 hardware inside).
One issue I found is that I needed to flip the endianness
in eip197_write_firmware() function, which for reason I am
not aware is using big-endian.
The firmware that I have is clearly using little-endian,
and unfortunately I do not have access to Marvell platform
to do more investigation or comparison there.
I have also tried to look for clues in Inside-Secure's
hardware/firmware documentation, without success.
Thus, assuming each vendor may use different endian format,
on these patch set I add support for little-endian firmware
(default remains big-endian). MaxLinear platform can then
utilize the option, which is implemented as soc data.
An alternative to this would be implementing the option
as a new device-tree property, but for now I assume we do
not need that since each platform endianness should be
fixed, and will not vary per board/hardware.
Please help review.
Thanks!
v2:
Revert directory change for generic case.
Add missing driver data change in pci_device_id.
Rename data struct to safexcel_priv_data.
Rework endianness selection code casting, to fix warning caught by kernel test robot.
Rename mxl version string to eip197 'c'.
Peter Harliman Liem (3):
crypto: inside-secure - Expand soc data structure
crypto: inside-secure - Add fw_little_endian option
crypto: inside-secure - Add MaxLinear platform
drivers/crypto/inside-secure/safexcel.c | 69 ++++++++++++++++++-------
drivers/crypto/inside-secure/safexcel.h | 10 +++-
2 files changed, 59 insertions(+), 20 deletions(-)
--
2.17.1
Currently platform data is assigned directly to
version string(instead of struct). To make it more
scalable, we move it to use data struct instead.
This allows customization for individual platforms other
than version string.
Signed-off-by: Peter Harliman Liem <[email protected]>
---
drivers/crypto/inside-secure/safexcel.c | 44 +++++++++++++++++--------
drivers/crypto/inside-secure/safexcel.h | 6 +++-
2 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
index ad0d8c4a71ac..8f4872470529 100644
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -410,10 +410,10 @@ 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
return -ENODEV;
@@ -423,7 +423,7 @@ static int eip197_load_firmwares(struct safexcel_crypto_priv *priv)
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
@@ -1597,7 +1597,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
@@ -1731,7 +1731,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);
@@ -1806,27 +1806,43 @@ static int safexcel_remove(struct platform_device *pdev)
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 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,
},
/* 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 +1878,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 +1897,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 +1965,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,
},
{},
};
diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
index 797ff91512e0..e8da8b30a392 100644
--- a/drivers/crypto/inside-secure/safexcel.h
+++ b/drivers/crypto/inside-secure/safexcel.h
@@ -733,6 +733,10 @@ enum safexcel_eip_version {
EIP197_DEVBRD
};
+struct safexcel_priv_data {
+ enum safexcel_eip_version version;
+};
+
/* Priority we use for advertising our algorithms */
#define SAFEXCEL_CRA_PRIORITY 300
@@ -815,7 +819,7 @@ struct safexcel_crypto_priv {
struct clk *reg_clk;
struct safexcel_config config;
- enum safexcel_eip_version version;
+ struct safexcel_priv_data *data;
struct safexcel_register_offsets offsets;
struct safexcel_hwconfig hwconfig;
u32 flags;
--
2.17.1
This is to add MaxLinear platform into compatible id.
Firmware endianness option is added since MaxLinear
firmware is in little endian format.
Signed-off-by: Peter Harliman Liem <[email protected]>
---
drivers/crypto/inside-secure/safexcel.c | 11 +++++++++++
drivers/crypto/inside-secure/safexcel.h | 3 ++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
index 4d6d64ff9a0f..ae6110376e21 100644
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -421,6 +421,8 @@ static int eip197_load_firmwares(struct safexcel_crypto_priv *priv)
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;
@@ -1828,6 +1830,11 @@ 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",
@@ -1841,6 +1848,10 @@ static const struct of_device_id safexcel_of_match_table[] = {
.compatible = "inside-secure,safexcel-eip197d",
.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",
diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
index f049293870b4..6c2fc662f64f 100644
--- a/drivers/crypto/inside-secure/safexcel.h
+++ b/drivers/crypto/inside-secure/safexcel.h
@@ -730,7 +730,8 @@ enum safexcel_eip_version {
EIP97IES_MRVL,
EIP197B_MRVL,
EIP197D_MRVL,
- EIP197_DEVBRD
+ EIP197_DEVBRD,
+ EIP197C_MXL,
};
struct safexcel_priv_data {
--
2.17.1
This is to add fw_little_endian option, which can
be used for platform which firmware is using little-endian
(instead of big-endian).
Signed-off-by: Peter Harliman Liem <[email protected]>
---
drivers/crypto/inside-secure/safexcel.c | 14 ++++++++++----
drivers/crypto/inside-secure/safexcel.h | 1 +
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
index 8f4872470529..4d6d64ff9a0f 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;
diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
index e8da8b30a392..f049293870b4 100644
--- a/drivers/crypto/inside-secure/safexcel.h
+++ b/drivers/crypto/inside-secure/safexcel.h
@@ -735,6 +735,7 @@ enum safexcel_eip_version {
struct safexcel_priv_data {
enum safexcel_eip_version version;
+ bool fw_little_endian;
};
/* Priority we use for advertising our algorithms */
--
2.17.1
On Tue, Sep 27, 2022 at 11:10:07AM +0800, Peter Harliman Liem wrote:
> Hi,
>
> I have been utilizing inside-secure driver on MaxLinear
> SoC platform (which has eip197 hardware inside).
>
> One issue I found is that I needed to flip the endianness
> in eip197_write_firmware() function, which for reason I am
> not aware is using big-endian.
> The firmware that I have is clearly using little-endian,
> and unfortunately I do not have access to Marvell platform
> to do more investigation or comparison there.
> I have also tried to look for clues in Inside-Secure's
> hardware/firmware documentation, without success.
>
> Thus, assuming each vendor may use different endian format,
> on these patch set I add support for little-endian firmware
> (default remains big-endian). MaxLinear platform can then
> utilize the option, which is implemented as soc data.
>
> An alternative to this would be implementing the option
> as a new device-tree property, but for now I assume we do
> not need that since each platform endianness should be
> fixed, and will not vary per board/hardware.
>
> Please help review.
>
> Thanks!
>
> v2:
> Revert directory change for generic case.
> Add missing driver data change in pci_device_id.
> Rename data struct to safexcel_priv_data.
> Rework endianness selection code casting, to fix warning caught by kernel test robot.
> Rename mxl version string to eip197 'c'.
>
> Peter Harliman Liem (3):
> crypto: inside-secure - Expand soc data structure
> crypto: inside-secure - Add fw_little_endian option
> crypto: inside-secure - Add MaxLinear platform
>
> drivers/crypto/inside-secure/safexcel.c | 69 ++++++++++++++++++-------
> drivers/crypto/inside-secure/safexcel.h | 10 +++-
> 2 files changed, 59 insertions(+), 20 deletions(-)
>
> --
> 2.17.1
All applied. Thanks.
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt