summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRoy Pledge <Roy.Pledge@freescale.com>2015-02-20 17:50:07 (GMT)
committerHonghua Yin <Hong-Hua.Yin@freescale.com>2015-04-21 03:37:13 (GMT)
commit24f775724bac8b5cffba1e6bec7059a85f44000d (patch)
treea346f63afe1774fa3ab5c4328dbadf6bdfe5d766 /drivers
parente5813370f1978ccd25b09c8d86c4d5780d0cc6df (diff)
downloadlinux-fsl-qoriq-24f775724bac8b5cffba1e6bec7059a85f44000d.tar.xz
qbman: Agressively clean QMan portals before use
Make sure both the message ring and dequeue ring of a QMan portal are clean before attempting to use them Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com> Change-Id: I8b4736625acfb25954cd3fa60e0761f86c2d9620 Reviewed-on: http://git.am.freescale.net:8181/31755 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com> Reviewed-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com> Reviewed-by: Richard Schmitt <richard.schmitt@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/35331 Reviewed-by: Honghua Yin <Hong-Hua.Yin@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/fsl_qbman/qman_high.c27
-rw-r--r--drivers/staging/fsl_qbman/qman_low.h2
2 files changed, 5 insertions, 24 deletions
diff --git a/drivers/staging/fsl_qbman/qman_high.c b/drivers/staging/fsl_qbman/qman_high.c
index aed5b26..565de9e 100644
--- a/drivers/staging/fsl_qbman/qman_high.c
+++ b/drivers/staging/fsl_qbman/qman_high.c
@@ -327,7 +327,7 @@ static inline void qman_stop_dequeues_ex(struct qman_portal *p)
PORTAL_IRQ_UNLOCK(p, irqflags);
}
-static int drain_mr_fqrni(struct qm_portal *p)
+static int drain_mr(struct qm_portal *p)
{
const struct qm_mr_entry *msg;
loop:
@@ -353,11 +353,6 @@ loop:
if (!msg)
return 0;
}
- if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) {
- /* We aren't draining anything but FQRNIs */
- pr_err("QMan found verb 0x%x in MR\n", msg->verb);
- return -1;
- }
qm_mr_next(p);
qm_mr_cci_consume(p, 1);
goto loop;
@@ -539,24 +534,9 @@ struct qman_portal *qman_create_portal(
}
isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
qm_isr_disable_write(__p, isdr);
- if (qm_dqrr_current(__p) != NULL) {
- pr_err("Qman DQRR unclean\n");
+ while (qm_dqrr_current(__p) != NULL)
qm_dqrr_cdc_consume_n(__p, 0xffff);
- }
- if (qm_mr_current(__p) != NULL) {
- /* special handling, drain just in case it's a few FQRNIs */
- if (drain_mr_fqrni(__p)) {
- const struct qm_mr_entry *e = qm_mr_current(__p);
- /*
- * Message ring cannot be empty no need to check
- * qm_mr_current returned successfully
- */
- pr_err("Qman MR unclean, MR VERB 0x%x, "
- "rc 0x%x\n, addr 0x%x",
- e->verb, e->ern.rc, e->ern.fd.addr_lo);
- goto fail_dqrr_mr_empty;
- }
- }
+ drain_mr(__p);
/* Success */
portal->config = config;
qm_isr_disable_write(__p, 0);
@@ -564,7 +544,6 @@ struct qman_portal *qman_create_portal(
/* Write a sane SDQCR */
qm_dqrr_sdqcr_set(__p, portal->sdqcr);
return portal;
-fail_dqrr_mr_empty:
fail_eqcr_empty:
fail_affinity:
free_irq(config->public_cfg.irq, portal);
diff --git a/drivers/staging/fsl_qbman/qman_low.h b/drivers/staging/fsl_qbman/qman_low.h
index 2fe7a1e..407a82c 100644
--- a/drivers/staging/fsl_qbman/qman_low.h
+++ b/drivers/staging/fsl_qbman/qman_low.h
@@ -558,6 +558,8 @@ static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
+ dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
+ dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
}
static inline int qm_dqrr_init(struct qm_portal *portal,