From: "Teh, Wen Ping" <[email protected]>

commit d031779b1e0a2ecec3bf7ce8a5602e92a5013b4d from
https://github.com/altera-opensource/linux-socfpga.git

Add generic mailbox command that can support SDM command. User can use this
command to send SDM mailbox command. User have to specified an input file
which contain the command data and an output file for SDM response to be
copied over.

Signed-off-by: Teh, Wen Ping <[email protected]>
Signed-off-by: Wenlin Kang <[email protected]>
---
 drivers/crypto/intel_fcs.c           | 127 +++++++++++++++++++++++++++
 include/uapi/linux/intel_fcs-ioctl.h |  26 ++++++
 2 files changed, 153 insertions(+)

diff --git a/drivers/crypto/intel_fcs.c b/drivers/crypto/intel_fcs.c
index 4f6aa59d2c42..d2996d151af1 100644
--- a/drivers/crypto/intel_fcs.c
+++ b/drivers/crypto/intel_fcs.c
@@ -210,6 +210,28 @@ static void fcs_hwrng_callback(struct stratix10_svc_client 
*client,
        complete(&priv->completion);
 }
 
+static void fcs_mbox_send_cmd_callback(struct stratix10_svc_client *client,
+                                    struct stratix10_svc_cb_data *data)
+{
+       struct intel_fcs_priv *priv = client->priv;
+
+       if (data->status == BIT(SVC_STATUS_OK)) {
+               priv->status =  0;
+               priv->size = *((unsigned int *)data->kaddr2);
+       } else if (data->status == BIT(SVC_STATUS_ERROR)) {
+               priv->status = *((unsigned int *)data->kaddr1);
+               dev_err(client->dev, "mbox_error=0x%x\n", priv->status);
+       } else if (data->status == BIT(SVC_STATUS_INVALID_PARAM)) {
+               priv->status = -EINVAL;
+               dev_err(client->dev, "request rejected\n");
+       } else {
+               priv->status = -EINVAL;
+               dev_err(client->dev, "rejected, invalid param\n");
+       }
+
+       complete(&priv->completion);
+}
+
 static int fcs_request_service(struct intel_fcs_priv *priv,
                               void *msg, unsigned long timeout)
 {
@@ -2733,6 +2755,111 @@ static long fcs_ioctl(struct file *file, unsigned int 
cmd,
 
                break;
 
+       case INTEL_FCS_DEV_MBOX_SEND:
+               if (copy_from_user(data, (void __user *)arg, sizeof(*data))) {
+                       dev_err(dev, "failure on copy_from_user\n");
+                       mutex_unlock(&priv->lock);
+                       return -EFAULT;
+               }
+
+               if (data->com_paras.mbox_send_cmd.cmd_data_sz % 4) {
+                       dev_err(dev, "Command data size (%d) is not 4 byte 
align\n",
+                       data->com_paras.mbox_send_cmd.cmd_data_sz);
+                       mutex_unlock(&priv->lock);
+                       return -EFAULT;
+               }
+
+               if (data->com_paras.mbox_send_cmd.rsp_data_sz % 4) {
+                       dev_err(dev, "Respond data size (%d) is not 4 byte 
align\n",
+                       data->com_paras.mbox_send_cmd.rsp_data_sz);
+                       mutex_unlock(&priv->lock);
+                       return -EFAULT;
+               }
+
+               if (data->com_paras.mbox_send_cmd.cmd_data_sz) {
+                       s_buf = stratix10_svc_allocate_memory(priv->chan,
+                                       
data->com_paras.mbox_send_cmd.cmd_data_sz);
+                       if (!s_buf) {
+                               dev_err(dev, "failed allocate source CMD 
buf\n");
+                               mutex_unlock(&priv->lock);
+                               return -ENOMEM;
+                       }
+               } else {
+                       s_buf = NULL;
+               }
+
+               if (data->com_paras.mbox_send_cmd.rsp_data_sz) {
+                       d_buf = stratix10_svc_allocate_memory(priv->chan,
+                                       
data->com_paras.mbox_send_cmd.rsp_data_sz);
+                       if (!d_buf) {
+                               dev_err(dev, "failed allocate destination RSP 
buf\n");
+                               fcs_free_memory(priv, s_buf, NULL, NULL);
+                               mutex_unlock(&priv->lock);
+                               return -ENOMEM;
+                       }
+               } else {
+                       d_buf = NULL;
+               }
+
+               if (s_buf != NULL) {
+                       /* Copy user data from user space to kernel space */
+                       ret = copy_from_user(s_buf,
+                                               
data->com_paras.mbox_send_cmd.cmd_data,
+                                               
data->com_paras.mbox_send_cmd.cmd_data_sz);
+                       if (ret) {
+                               dev_err(dev, "failed copy buf ret=%d\n", ret);
+                               fcs_free_memory(priv, s_buf, d_buf, NULL);
+                               mutex_unlock(&priv->lock);
+                               return -EFAULT;
+                       }
+               }
+
+               msg->command = COMMAND_MBOX_SEND_CMD;
+               msg->arg[0] = data->com_paras.mbox_send_cmd.mbox_cmd;
+               msg->arg[1] = data->com_paras.mbox_send_cmd.urgent;
+               msg->payload = s_buf;
+               msg->payload_length = data->com_paras.mbox_send_cmd.cmd_data_sz;
+               msg->payload_output = d_buf;
+               msg->payload_length_output = 
data->com_paras.mbox_send_cmd.rsp_data_sz;
+               priv->client.receive_cb = fcs_mbox_send_cmd_callback;
+
+               ret = fcs_request_service(priv, (void *)msg,
+                                         10 * FCS_REQUEST_TIMEOUT);
+
+               if (!ret && !priv->status) {
+                       if (priv->size > 
data->com_paras.mbox_send_cmd.rsp_data_sz) {
+                               dev_err(dev, "Resp data size (%d) bigger than 
dest size\n",
+                                               priv->size);
+                               fcs_close_services(priv, s_buf, d_buf);
+                               return -EFAULT;
+                       }
+
+                       data->com_paras.mbox_send_cmd.rsp_data_sz = priv->size;
+
+                       if (data->com_paras.mbox_send_cmd.rsp_data_sz) {
+                               ret = 
copy_to_user(data->com_paras.mbox_send_cmd.rsp_data, d_buf,
+                                                                       
data->com_paras.mbox_send_cmd.rsp_data_sz);
+
+                               if (ret) {
+                                       dev_err(dev, "failure on 
copy_to_user\n");
+                                       fcs_close_services(priv, s_buf, d_buf);
+                                       return -EFAULT;
+                               }
+                       }
+               } else {
+                       data->com_paras.mbox_send_cmd.rsp_data = NULL;
+                       data->com_paras.mbox_send_cmd.rsp_data_sz = 0;
+               }
+               data->status = priv->status;
+
+               if (copy_to_user((void __user *)arg, data, sizeof(*data))) {
+                       dev_err(dev, "failure on copy_to_user\n");
+                       ret = -EFAULT;
+               }
+
+               fcs_close_services(priv, s_buf, d_buf);
+               break;
+
        default:
                dev_warn(dev, "shouldn't be here [0x%x]\n", cmd);
                break;
diff --git a/include/uapi/linux/intel_fcs-ioctl.h 
b/include/uapi/linux/intel_fcs-ioctl.h
index 1316a24490f1..0d484abf552c 100644
--- a/include/uapi/linux/intel_fcs-ioctl.h
+++ b/include/uapi/linux/intel_fcs-ioctl.h
@@ -38,6 +38,24 @@ enum fcs_certificate_test {
        INTEL_FCS_TEST = 1
 };
 
+/**
+ * struct fcs_mbox_send_cmd - send generic mailbox command
+ * @mbox_cmd: mailbox command code
+ * @urgent: 0 for CASUAL, 1 for URGENT
+ * @cmd_data: virtual address of mailbox command data
+ * @cmd_data_sz: size of mailbox command data in bytes
+ * @rsp_data: virtual address to store response data
+ * @rsp_data_sz: maximun size to store response data in bytes
+ */
+struct fcs_mbox_send_cmd {
+       uint32_t mbox_cmd;
+       uint8_t urgent;
+       void *cmd_data;
+       uint16_t cmd_data_sz;
+       void *rsp_data;
+       uint16_t rsp_data_sz;
+};
+
 /**
  * struct fcs_placeholder - placeholder of ioctl stuct
  * @data: placeholder of iotcl struct
@@ -427,6 +445,7 @@ struct intel_fcs_dev_ioctl {
 
        /* command parameters */
        union {
+               struct fcs_mbox_send_cmd        mbox_send_cmd;
                struct fcs_placeholder          placeholder;
                struct fcs_validation_request   s_request;
                struct fcs_certificate_request  c_request;
@@ -461,6 +480,8 @@ struct intel_fcs_dev_ioctl {
  *
  * @INTEL_FCS_DEV_VERSION_CMD:
  *
+ * @INTEL_FCS_DEV_MBOX_SEND_CMD:
+ *
  * @INTEL_FCS_DEV_CERTIFICATE_CMD:
  *
  * @INTEL_FCS_DEV_VALIDATE_REQUEST_CMD:
@@ -482,6 +503,7 @@ struct intel_fcs_dev_ioctl {
 enum intel_fcs_command_code {
        INTEL_FCS_DEV_COMMAND_NONE = 0,
        INTEL_FCS_DEV_VERSION_CMD = 1,
+       INTEL_FCS_DEV_MBOX_SEND_CMD,
        INTEL_FCS_DEV_CERTIFICATE_CMD = 0xB,
        INTEL_FCS_DEV_VALIDATE_REQUEST_CMD = 0x78,
        INTEL_FCS_DEV_COUNTER_SET_CMD,
@@ -520,6 +542,10 @@ enum intel_fcs_command_code {
        _IOWR(INTEL_FCS_IOCTL, \
              INTEL_FCS_DEV_VERSION_CMD, struct intel_fcs_dev_ioctl)
 
+#define INTEL_FCS_DEV_MBOX_SEND \
+       _IOWR(INTEL_FCS_IOCTL, \
+             INTEL_FCS_DEV_MBOX_SEND_CMD, struct intel_fcs_dev_ioctl)
+
 #define INTEL_FCS_DEV_VALIDATION_REQUEST \
        _IOWR(INTEL_FCS_IOCTL, \
              INTEL_FCS_DEV_VALIDATE_REQUEST_CMD, struct intel_fcs_dev_ioctl)
-- 
2.25.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#12573): 
https://lists.yoctoproject.org/g/linux-yocto/message/12573
Mute This Topic: https://lists.yoctoproject.org/mt/98921489/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to