diff options
author | Roy Pledge <Roy.Pledge@freescale.com> | 2015-02-20 17:50:07 (GMT) |
---|---|---|
committer | Honghua Yin <Hong-Hua.Yin@freescale.com> | 2015-04-21 03:37:13 (GMT) |
commit | 24f775724bac8b5cffba1e6bec7059a85f44000d (patch) | |
tree | a346f63afe1774fa3ab5c4328dbadf6bdfe5d766 /drivers/staging/fsl_qbman | |
parent | e5813370f1978ccd25b09c8d86c4d5780d0cc6df (diff) | |
download | linux-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/staging/fsl_qbman')
-rw-r--r-- | drivers/staging/fsl_qbman/qman_high.c | 27 | ||||
-rw-r--r-- | drivers/staging/fsl_qbman/qman_low.h | 2 |
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, |