4
4
* Queue Interface backend functionality
5
5
*
6
6
* Copyright 2013-2016 Freescale Semiconductor, Inc.
7
- * Copyright 2016-2017, 2019 NXP
7
+ * Copyright 2016-2017, 2019-2020 NXP
8
8
*/
9
9
10
10
#include <linux/cpumask.h>
@@ -124,8 +124,10 @@ int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req)
124
124
125
125
do {
126
126
ret = qman_enqueue (req -> drv_ctx -> req_fq , & fd );
127
- if (likely (!ret ))
127
+ if (likely (!ret )) {
128
+ refcount_inc (& req -> drv_ctx -> refcnt );
128
129
return 0 ;
130
+ }
129
131
130
132
if (ret != - EBUSY )
131
133
break ;
@@ -148,18 +150,20 @@ static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq,
148
150
149
151
fd = & msg -> ern .fd ;
150
152
151
- if (qm_fd_get_format (fd ) != qm_fd_compound ) {
152
- dev_err (qidev , "Non-compound FD from CAAM\n" );
153
- return ;
154
- }
155
-
156
153
drv_req = caam_iova_to_virt (priv -> domain , qm_fd_addr_get64 (fd ));
157
154
if (!drv_req ) {
158
155
dev_err (qidev ,
159
156
"Can't find original request for CAAM response\n" );
160
157
return ;
161
158
}
162
159
160
+ refcount_dec (& drv_req -> drv_ctx -> refcnt );
161
+
162
+ if (qm_fd_get_format (fd ) != qm_fd_compound ) {
163
+ dev_err (qidev , "Non-compound FD from CAAM\n" );
164
+ return ;
165
+ }
166
+
163
167
dma_unmap_single (drv_req -> drv_ctx -> qidev , qm_fd_addr (fd ),
164
168
sizeof (drv_req -> fd_sgt ), DMA_BIDIRECTIONAL );
165
169
@@ -287,9 +291,10 @@ static int kill_fq(struct device *qidev, struct qman_fq *fq)
287
291
return ret ;
288
292
}
289
293
290
- static int empty_caam_fq (struct qman_fq * fq )
294
+ static int empty_caam_fq (struct qman_fq * fq , struct caam_drv_ctx * drv_ctx )
291
295
{
292
296
int ret ;
297
+ int retries = 10 ;
293
298
struct qm_mcr_queryfq_np np ;
294
299
295
300
/* Wait till the older CAAM FQ get empty */
@@ -304,11 +309,18 @@ static int empty_caam_fq(struct qman_fq *fq)
304
309
msleep (20 );
305
310
} while (1 );
306
311
307
- /*
308
- * Give extra time for pending jobs from this FQ in holding tanks
309
- * to get processed
310
- */
311
- msleep (20 );
312
+ /* Wait until pending jobs from this FQ are processed by CAAM */
313
+ do {
314
+ if (refcount_read (& drv_ctx -> refcnt ) == 1 )
315
+ break ;
316
+
317
+ msleep (20 );
318
+ } while (-- retries );
319
+
320
+ if (!retries )
321
+ dev_warn_once (drv_ctx -> qidev , "%d frames from FQID %u still pending in CAAM\n" ,
322
+ refcount_read (& drv_ctx -> refcnt ), fq -> fqid );
323
+
312
324
return 0 ;
313
325
}
314
326
@@ -340,7 +352,7 @@ int caam_drv_ctx_update(struct caam_drv_ctx *drv_ctx, u32 *sh_desc)
340
352
drv_ctx -> req_fq = new_fq ;
341
353
342
354
/* Empty and remove the older FQ */
343
- ret = empty_caam_fq (old_fq );
355
+ ret = empty_caam_fq (old_fq , drv_ctx );
344
356
if (ret ) {
345
357
dev_err (qidev , "Old CAAM FQ empty failed: %d\n" , ret );
346
358
@@ -453,6 +465,9 @@ struct caam_drv_ctx *caam_drv_ctx_init(struct device *qidev,
453
465
return ERR_PTR (- ENOMEM );
454
466
}
455
467
468
+ /* init reference counter used to track references to request FQ */
469
+ refcount_set (& drv_ctx -> refcnt , 1 );
470
+
456
471
drv_ctx -> qidev = qidev ;
457
472
return drv_ctx ;
458
473
}
@@ -571,6 +586,16 @@ static enum qman_cb_dqrr_result caam_rsp_fq_dqrr_cb(struct qman_portal *p,
571
586
return qman_cb_dqrr_stop ;
572
587
573
588
fd = & dqrr -> fd ;
589
+
590
+ drv_req = caam_iova_to_virt (priv -> domain , qm_fd_addr_get64 (fd ));
591
+ if (unlikely (!drv_req )) {
592
+ dev_err (qidev ,
593
+ "Can't find original request for caam response\n" );
594
+ return qman_cb_dqrr_consume ;
595
+ }
596
+
597
+ refcount_dec (& drv_req -> drv_ctx -> refcnt );
598
+
574
599
status = be32_to_cpu (fd -> status );
575
600
if (unlikely (status )) {
576
601
u32 ssrc = status & JRSTA_SSRC_MASK ;
@@ -588,13 +613,6 @@ static enum qman_cb_dqrr_result caam_rsp_fq_dqrr_cb(struct qman_portal *p,
588
613
return qman_cb_dqrr_consume ;
589
614
}
590
615
591
- drv_req = caam_iova_to_virt (priv -> domain , qm_fd_addr_get64 (fd ));
592
- if (unlikely (!drv_req )) {
593
- dev_err (qidev ,
594
- "Can't find original request for caam response\n" );
595
- return qman_cb_dqrr_consume ;
596
- }
597
-
598
616
dma_unmap_single (drv_req -> drv_ctx -> qidev , qm_fd_addr (fd ),
599
617
sizeof (drv_req -> fd_sgt ), DMA_BIDIRECTIONAL );
600
618
0 commit comments