Browse Source

qcedev: check crypto status before unlocking

Whenever there is a crypto error, the pipe is reset which
in turn resets the crypto core. When the pipe is reset wait
for it to complete by monitoring the crypto status.

Change-Id: Id79838e517df491b8062ec379baff2407fea500c
Signed-off-by: Gaurav Kashyap <[email protected]>
Gaurav Kashyap 1 year ago
parent
commit
e0e07de5fd
2 changed files with 19 additions and 6 deletions
  1. 18 3
      crypto-qti/qce50.c
  2. 1 3
      crypto-qti/qcedev.c

+ 18 - 3
crypto-qti/qce50.c

@@ -246,7 +246,7 @@ void qce_get_crypto_status(void *handle, struct qce_error *error)
 	dump_status_regs(status);
 #endif
 
-	if (status[0] != QCE_STATUS1_NO_ERROR) {
+	if (status[0] != QCE_STATUS1_NO_ERROR || status[1]) {
 		if (pce_dev->ce_bam_info.minor_version >= 8) {
 			if (status[2] & CRYPTO58_TIMER_EXPIRED) {
 				error->timer_error = true;
@@ -284,7 +284,7 @@ void qce_get_crypto_status(void *handle, struct qce_error *error)
 	}
 
 	error->no_error = true;
-	pr_err("%s: No crypto error, status1 = 0x%x\n",
+	pr_info("%s: No crypto error, status1 = 0x%x\n",
 		   __func__, status[0]);
 
 	return;
@@ -2419,6 +2419,8 @@ exit:
 	return rc;
 }
 
+#define MAX_RESET_TIME_RETRIES 1000
+
 int qce_manage_timeout(void *handle, int req_info)
 {
 	struct qce_device *pce_dev = (struct qce_device *) handle;
@@ -2426,6 +2428,8 @@ int qce_manage_timeout(void *handle, int req_info)
 	struct ce_request_info *preq_info;
 	qce_comp_func_ptr_t qce_callback;
 	uint16_t op = pce_dev->ce_request_info[req_info].offload_op;
+	struct qce_error error = {0};
+	int retries = 0;
 
 	preq_info = &pce_dev->ce_request_info[req_info];
 	qce_callback = preq_info->qce_cb;
@@ -2436,11 +2440,22 @@ int qce_manage_timeout(void *handle, int req_info)
 	if (qce_sps_pipe_reset(pce_dev, op))
 		pr_err("%s: pipe reset failed\n", __func__);
 
-	qce_enable_clock_gating(pce_dev);
+	qce_get_crypto_status(pce_dev, &error);
+	while (!error.no_error && retries < MAX_RESET_TIME_RETRIES) {
+		usleep_range(3000, 5000);
+		retries++;
+		qce_get_crypto_status(pce_dev, &error);
+		pr_info("%s: waiting for reset to complete\n", __func__);
+	}
+
+	// Write memory barrier
+	wmb();
 
 	if (_qce_unlock_other_pipes(pce_dev, req_info))
 		pr_err("%s: fail unlock other pipes\n", __func__);
 
+	qce_enable_clock_gating(pce_dev);
+
 	if (!atomic_read(&preq_info->in_use)) {
 		pr_err("request information %d already done\n", req_info);
 		return -ENXIO;

+ 1 - 3
crypto-qti/qcedev.c

@@ -49,7 +49,7 @@
  * This is temporary, and we can use the 1500 value once the
  * core irqs are enabled.
  */
-#define MAX_OFFLOAD_CRYPTO_WAIT_TIME 25
+#define MAX_OFFLOAD_CRYPTO_WAIT_TIME 20
 
 #define MAX_REQUEST_TIME 5000
 
@@ -841,12 +841,10 @@ static int submit_req(struct qcedev_async_req *qcedev_areq,
 			}
 			return 0;
 		}
-		spin_lock_irqsave(&podev->lock, flags);
 		ret = qce_manage_timeout(podev->qce, current_req_info);
 		if (ret)
 			pr_err("%s: error during manage timeout", __func__);
 
-		spin_unlock_irqrestore(&podev->lock, flags);
 		req_done((unsigned long) podev);
 		if (qcedev_areq->offload_cipher_op_req.err !=
 						QCEDEV_OFFLOAD_NO_ERROR)