summaryrefslogtreecommitdiff
path: root/drivers/firmware/stratix10-svc.c
diff options
context:
space:
mode:
authorAng Tien Sung <tien.sung.ang@intel.com>2022-07-11 17:31:36 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-07-14 16:55:09 +0200
commit79b936254aa0eb4e3bc73fecaacf049145613c0a (patch)
tree46a61b4489980cbad470e66bf2557f237c9376bf /drivers/firmware/stratix10-svc.c
parente6281c26674e037798bf674f26a7593a324cdf39 (diff)
firmware: stratix10-svc: add FCS polling command
Introduce a new SMC command INTEL_SIP_SMC_FUNCID_SERVICE_COMPLETED that polls if a previous asynchronous command was completed. This SMC command is used by the new FPGA Crypto Service (FCS). A basic example is that the FCS sends an AES data encryption call to the secure device manager(SDM) and waits for the completion of the operation by continuously polling the results with the new command. Signed-off-by: Ang Tien Sung <tien.sung.ang@intel.com> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org> Link: https://lore.kernel.org/r/20220711223140.2307945-2-dinguyen@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/firmware/stratix10-svc.c')
-rw-r--r--drivers/firmware/stratix10-svc.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index 1fe748c047df..439a4bdf8207 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -248,6 +248,7 @@ static void svc_thread_cmd_config_status(struct stratix10_svc_controller *ctrl,
{
struct arm_smccc_res res;
int count_in_sec;
+ unsigned long a0, a1, a2;
cb_data->kaddr1 = NULL;
cb_data->kaddr2 = NULL;
@@ -256,24 +257,45 @@ static void svc_thread_cmd_config_status(struct stratix10_svc_controller *ctrl,
pr_debug("%s: polling config status\n", __func__);
+ a0 = INTEL_SIP_SMC_FPGA_CONFIG_ISDONE;
+ a1 = (unsigned long)p_data->paddr;
+ a2 = (unsigned long)p_data->size;
+
+ if (p_data->command == COMMAND_POLL_SERVICE_STATUS)
+ a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
+
count_in_sec = FPGA_CONFIG_STATUS_TIMEOUT_SEC;
while (count_in_sec) {
- ctrl->invoke_fn(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE,
- 0, 0, 0, 0, 0, 0, 0, &res);
+ ctrl->invoke_fn(a0, a1, a2, 0, 0, 0, 0, 0, &res);
if ((res.a0 == INTEL_SIP_SMC_STATUS_OK) ||
- (res.a0 == INTEL_SIP_SMC_STATUS_ERROR))
+ (res.a0 == INTEL_SIP_SMC_STATUS_ERROR) ||
+ (res.a0 == INTEL_SIP_SMC_STATUS_REJECTED))
break;
/*
- * configuration is still in progress, wait one second then
+ * request is still in progress, wait one second then
* poll again
*/
msleep(1000);
count_in_sec--;
}
- if (res.a0 == INTEL_SIP_SMC_STATUS_OK && count_in_sec)
+ if (!count_in_sec) {
+ pr_err("%s: poll status timeout\n", __func__);
+ cb_data->status = BIT(SVC_STATUS_BUSY);
+ } else if (res.a0 == INTEL_SIP_SMC_STATUS_OK) {
cb_data->status = BIT(SVC_STATUS_COMPLETED);
+ cb_data->kaddr2 = (res.a2) ?
+ svc_pa_to_va(res.a2) : NULL;
+ cb_data->kaddr3 = (res.a3) ? &res.a3 : NULL;
+ } else {
+ pr_err("%s: poll status error\n", __func__);
+ cb_data->kaddr1 = &res.a1;
+ cb_data->kaddr2 = (res.a2) ?
+ svc_pa_to_va(res.a2) : NULL;
+ cb_data->kaddr3 = (res.a3) ? &res.a3 : NULL;
+ cb_data->status = BIT(SVC_STATUS_ERROR);
+ }
p_data->chan->scl->receive_cb(p_data->chan->scl, cb_data);
}
@@ -298,6 +320,7 @@ static void svc_thread_recv_status_ok(struct stratix10_svc_data *p_data,
case COMMAND_RECONFIG:
case COMMAND_RSU_UPDATE:
case COMMAND_RSU_NOTIFY:
+ case COMMAND_POLL_SERVICE_STATUS:
cb_data->status = BIT(SVC_STATUS_OK);
break;
case COMMAND_RECONFIG_DATA_SUBMIT:
@@ -430,6 +453,14 @@ static int svc_normal_to_secure_thread(void *data)
a1 = 0;
a2 = 0;
break;
+ /* for polling */
+ case COMMAND_POLL_SERVICE_STATUS:
+ a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
+ a1 = (unsigned long)pdata->paddr;
+ a2 = (unsigned long)pdata->size;
+
+ break;
+
default:
pr_warn("it shouldn't happen\n");
break;
@@ -470,6 +501,7 @@ static int svc_normal_to_secure_thread(void *data)
pdata, cbdata);
break;
case COMMAND_RECONFIG_STATUS:
+ case COMMAND_POLL_SERVICE_STATUS:
svc_thread_cmd_config_status(ctrl,
pdata, cbdata);
break;