From: Gagandeep Singh <[email protected]> Improve the FQ shutdown sequence to handle edge cases more robustly, including better handling of ORL (Order Restoration List) presence and improved error recovery paths.
Signed-off-by: Gagandeep Singh <[email protected]> --- drivers/bus/dpaa/base/qbman/qman.c | 45 ++++++++++++++++-------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c index 6cf303de59..56dc1cba45 100644 --- a/drivers/bus/dpaa/base/qbman/qman.c +++ b/drivers/bus/dpaa/base/qbman/qman.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2017,2019-2025 NXP + * Copyright 2017,2019-2026 NXP * */ @@ -2843,9 +2843,10 @@ qman_shutdown_fq(struct qman_fq *fq) } res = mcr->result; /* Make a copy as we reuse MCR below */ - if (res == QM_MCR_RESULT_OK) { + if (res == QM_MCR_RESULT_OK) drain_mr_fqrni(&p->p); - } else if (res == QM_MCR_RESULT_PENDING) { + + if (res == QM_MCR_RESULT_PENDING) { /* * Need to wait for the FQRN in the message ring, which * will only occur once the FQ has been drained. In @@ -2853,28 +2854,29 @@ qman_shutdown_fq(struct qman_fq *fq) * to dequeue from the channel the FQ is scheduled on */ int found_fqrn = 0; - const u16 pool_ch_start = dpaa_get_qm_channel_pool(); - const u16 pool_ch_end = pool_ch_start + dpaa_get_qm_channel_pool_num(); - u32 sdqcr = p->sdqcr; /* Flag that we need to drain FQ */ drain = 1; + const u16 pool_ch_start = dpaa_get_qm_channel_pool(); + const u16 pool_ch_end = pool_ch_start + + dpaa_get_qm_channel_pool_num(); if (channel >= pool_ch_start && channel < pool_ch_end) { - /* Pool channel, enable the bit in the portal */ + /* Pool channel - must use affine portal */ if (p->config->channel != channel) { - DPAA_BUS_ERR("Portal affine channel(0x%04x) != wq channel(0x%04x)", + DPAA_BUS_ERR("Portal ch(0x%04x) != FQ ch(0x%04x)", p->config->channel, channel); ret = -EINVAL; goto out; } } else if (channel < pool_ch_start) { /* Dedicated channel */ - sdqcr = QM_SDQCR_TYPE_ACTIVE | QM_SDQCR_CHANNELS_DEDICATED; - qm_dqrr_sdqcr_set(&p->p, sdqcr); + qm_dqrr_sdqcr_set(&p->p, + QM_SDQCR_TYPE_ACTIVE | + QM_SDQCR_CHANNELS_DEDICATED); } else { - DPAA_BUS_ERR("Can't recover FQ 0x%x, Invalid channel: 0x%x", - fqid, channel); + DPAA_BUS_ERR("Invalid channel 0x%x for FQ 0x%x", + channel, fqid); ret = -EBUSY; goto out; } @@ -2882,15 +2884,16 @@ qman_shutdown_fq(struct qman_fq *fq) /* Keep draining DQRR while checking the MR*/ qm_dqrr_drain_nomatch(&p->p); /* Process message ring too */ - found_fqrn = qm_mr_drain(&p->p, - FQRN); + found_fqrn = qm_mr_drain(&p->p, FQRN); cpu_relax(); } while (!found_fqrn); - /* Restore SDQCR */ - if (sdqcr != p->sdqcr) - qm_dqrr_sdqcr_set(&p->p, p->sdqcr); - } else { - DPAA_BUS_ERR("retire_fq failed: FQ 0x%x, res=0x%x", fqid, res); + qm_dqrr_sdqcr_set(&p->p, p->sdqcr); + + } + if (res != QM_MCR_RESULT_OK && + res != QM_MCR_RESULT_PENDING) { + DPAA_BUS_ERR("retire_fq failed: FQ 0x%x, res=0x%x", + fqid, res); ret = -EIO; goto out; } @@ -2933,7 +2936,7 @@ qman_shutdown_fq(struct qman_fq *fq) if (mcr->result != QM_MCR_RESULT_OK) { DPAA_BUS_ERR("OOS after drain fail: FQ 0x%x (0x%x)", - fqid, mcr->result); + fqid, mcr->result); ret = -EIO; goto out; } @@ -2952,7 +2955,7 @@ qman_shutdown_fq(struct qman_fq *fq) if (mcr->result != QM_MCR_RESULT_OK) { DPAA_BUS_ERR("OOS fail: FQ 0x%x (0x%x)", - fqid, mcr->result); + fqid, mcr->result); ret = -EIO; goto out; } -- 2.25.1

