From 27df142b9bd2957c897529abd2fd7bc86b0671f8 Mon Sep 17 00:00:00 2001 From: Vakul Garg Date: Tue, 11 Mar 2014 15:16:35 +0530 Subject: qbman: Added DQRR cleanup when portal is not in cdc mode To acknowledge a DQRR entry, the portal should be preserved in same mode as it was when the DQRR entry was created. Function qm_dqrr_init() is invoked when a raw portal is released back. The raw portal could be either in one of cci or cci or cdc modes. So while cleaning up a portal using qm_dqrr_init(), the dqrr consumption mode should be read and accordingly approriate DQRR consumption routine should be invoked. Signed-off-by: Vakul Garg Change-Id: I07b412915cd483060147a845cfe935d0bd7f2024 Reviewed-on: http://git.am.freescale.net:8181/9634 Tested-by: Review Code-CDREVIEW Reviewed-by: Roy Pledge Reviewed-by: Geoff Thorpe Reviewed-by: Jose Rivera diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c index 11b2a8d..d86a4ff 100644 --- a/drivers/staging/fsl_qbman/fsl_usdpaa.c +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c @@ -323,11 +323,6 @@ static int init_qm_portal(struct qm_portal_config *config, " recover portal, portal will be leaked\n"); return 1; } - /* Consume any items in the dequeue ring */ - while (qm_dqrr_cdc_cci(portal) != qm_dqrr_cursor(portal)) { - qm_dqrr_cdc_consume_n(portal, 0xffff); - qm_dqrr_cdc_cce_prefetch(portal); - } /* Initialize the EQCR */ if (qm_eqcr_init(portal, qm_eqcr_pvb, diff --git a/drivers/staging/fsl_qbman/qman_low.h b/drivers/staging/fsl_qbman/qman_low.h index b624f67..5d3e820 100644 --- a/drivers/staging/fsl_qbman/qman_low.h +++ b/drivers/staging/fsl_qbman/qman_low.h @@ -536,6 +536,30 @@ static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf) ((mf & (QM_DQRR_SIZE - 1)) << 20)); } +static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num) +{ + register struct qm_dqrr *dqrr = &portal->dqrr; + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci); + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1); + qm_out(DQRR_CI_CINH, dqrr->ci); +} + +static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num) +{ + register struct qm_dqrr *dqrr = &portal->dqrr; + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce); + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1); + qm_cl_out(DQRR_CI, dqrr->ci); +} + +static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask) +{ + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc); + qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */ + ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */ +} + static inline int qm_dqrr_init(struct qm_portal *portal, const struct qm_portal_config *config, enum qm_dqrr_dmode dmode, @@ -557,6 +581,29 @@ static inline int qm_dqrr_init(struct qm_portal *portal, dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ? QM_DQRR_VERB_VBIT : 0; dqrr->ithresh = qm_in(DQRR_ITR); + + /* Free up pending DQRR entries if any as per current DCM */ + if (dqrr->fill) { + enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3; + +#ifdef CONFIG_FSL_DPA_CHECKING + dqrr->cmode = dcm; +#endif + switch (dcm) { + case qm_dqrr_cci: + qm_dqrr_cci_consume(portal, dqrr->fill); + break; + case qm_dqrr_cce: + qm_dqrr_cce_consume(portal, dqrr->fill); + break; + case qm_dqrr_cdc: + qm_dqrr_cdc_consume_n(portal, (QM_DQRR_SIZE - 1)); + break; + default: + DPA_ASSERT(0); + } + } + #ifdef CONFIG_FSL_DPA_CHECKING dqrr->dmode = dmode; dqrr->pmode = pmode; @@ -655,13 +702,6 @@ static inline void qm_dqrr_pvb_update(struct qm_portal *portal) } } -static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num) -{ - register struct qm_dqrr *dqrr = &portal->dqrr; - DPA_ASSERT(dqrr->cmode == qm_dqrr_cci); - dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1); - qm_out(DQRR_CI_CINH, dqrr->ci); -} static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal) { @@ -679,14 +719,6 @@ static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal) qm_cl_touch_rw(DQRR_CI); } -static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num) -{ - register struct qm_dqrr *dqrr = &portal->dqrr; - DPA_ASSERT(dqrr->cmode == qm_dqrr_cce); - dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1); - qm_cl_out(DQRR_CI, dqrr->ci); -} - static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal) { register struct qm_dqrr *dqrr = &portal->dqrr; @@ -720,14 +752,6 @@ static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal, idx); /* DQRR_DCAP::DCAP_CI */ } -static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask) -{ - __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; - DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc); - qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */ - ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */ -} - static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal) { __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -- cgit v0.10.2