On Tue, Dec 14, 2021 at 2:24 AM <pbhagavat...@marvell.com> wrote: > > From: Pavan Nikhilesh <pbhagavat...@marvell.com> > > Due to an errata writing to vWQE flush register might hang NIX. > Add workaround for vWQE flush hang by waiting for the max > coalescing timeout to flush out any pending vWQEs.
Fixes: ee48f711f3b0 ("common/cnxk: support NIX inline inbound and outbound setup") Cc: sta...@dpdk.org > > Signed-off-by: Pavan Nikhilesh <pbhagavat...@marvell.com> Acked-by: Jerin Jacob <jer...@marvell.com> Applied to dpdk-next-net-eventdev/for-main. Thanks > --- > drivers/common/cnxk/roc_nix_inl.c | 3 +-- > drivers/common/cnxk/roc_nix_inl_dev.c | 12 ++++++++++++ > drivers/common/cnxk/roc_nix_inl_priv.h | 1 + > drivers/common/cnxk/roc_nix_priv.h | 1 + > drivers/common/cnxk/roc_nix_queue.c | 19 +++++++++++++++++-- > 5 files changed, 32 insertions(+), 4 deletions(-) > > diff --git a/drivers/common/cnxk/roc_nix_inl.c > b/drivers/common/cnxk/roc_nix_inl.c > index f0fc690417..e8981c4aa4 100644 > --- a/drivers/common/cnxk/roc_nix_inl.c > +++ b/drivers/common/cnxk/roc_nix_inl.c > @@ -595,8 +595,7 @@ roc_nix_inl_dev_rq_put(struct roc_nix_rq *rq) > plt_err("Failed to disable inline device rq, rc=%d", rc); > > /* Flush NIX LF for CN10K */ > - if (roc_model_is_cn10k()) > - plt_write64(0, inl_dev->nix_base + NIX_LF_OP_VWQE_FLUSH); > + nix_rq_vwqe_flush(rq, inl_dev->vwqe_interval); > > return rc; > } > diff --git a/drivers/common/cnxk/roc_nix_inl_dev.c > b/drivers/common/cnxk/roc_nix_inl_dev.c > index a0fe6ecd82..10912a6c93 100644 > --- a/drivers/common/cnxk/roc_nix_inl_dev.c > +++ b/drivers/common/cnxk/roc_nix_inl_dev.c > @@ -346,6 +346,7 @@ nix_inl_nix_setup(struct nix_inl_dev *inl_dev) > struct mbox *mbox = dev->mbox; > struct nix_lf_alloc_rsp *rsp; > struct nix_lf_alloc_req *req; > + struct nix_hw_info *hw_info; > size_t inb_sa_sz; > int i, rc = -ENOSPC; > void *sa; > @@ -382,6 +383,17 @@ nix_inl_nix_setup(struct nix_inl_dev *inl_dev) > inl_dev->qints = rsp->qints; > inl_dev->cints = rsp->cints; > > + /* Get VWQE info if supported */ > + if (roc_model_is_cn10k()) { > + mbox_alloc_msg_nix_get_hw_info(mbox); > + rc = mbox_process_msg(mbox, (void *)&hw_info); > + if (rc) { > + plt_err("Failed to get HW info, rc=%d", rc); > + goto lf_free; > + } > + inl_dev->vwqe_interval = hw_info->vwqe_delay; > + } > + > /* Register nix interrupts */ > rc = nix_inl_nix_register_irqs(inl_dev); > if (rc) { > diff --git a/drivers/common/cnxk/roc_nix_inl_priv.h > b/drivers/common/cnxk/roc_nix_inl_priv.h > index 3dc526f929..be53a3fa81 100644 > --- a/drivers/common/cnxk/roc_nix_inl_priv.h > +++ b/drivers/common/cnxk/roc_nix_inl_priv.h > @@ -35,6 +35,7 @@ struct nix_inl_dev { > /* NIX data */ > uint8_t lf_tx_stats; > uint8_t lf_rx_stats; > + uint16_t vwqe_interval; > uint16_t cints; > uint16_t qints; > struct roc_nix_rq rq; > diff --git a/drivers/common/cnxk/roc_nix_priv.h > b/drivers/common/cnxk/roc_nix_priv.h > index 04575af295..deb2a6ba11 100644 > --- a/drivers/common/cnxk/roc_nix_priv.h > +++ b/drivers/common/cnxk/roc_nix_priv.h > @@ -377,6 +377,7 @@ int nix_rq_cfg(struct dev *dev, struct roc_nix_rq *rq, > uint16_t qints, bool cfg, > int nix_rq_ena_dis(struct dev *dev, struct roc_nix_rq *rq, bool enable); > int nix_tm_bp_config_get(struct roc_nix *roc_nix, bool *is_enabled); > int nix_tm_bp_config_set(struct roc_nix *roc_nix, bool enable); > +void nix_rq_vwqe_flush(struct roc_nix_rq *rq, uint16_t vwqe_interval); > > /* > * TM priv utils. > diff --git a/drivers/common/cnxk/roc_nix_queue.c > b/drivers/common/cnxk/roc_nix_queue.c > index c8c8401d81..d5f6813e69 100644 > --- a/drivers/common/cnxk/roc_nix_queue.c > +++ b/drivers/common/cnxk/roc_nix_queue.c > @@ -28,6 +28,22 @@ nix_qsize_clampup(uint32_t val) > return i; > } > > +void > +nix_rq_vwqe_flush(struct roc_nix_rq *rq, uint16_t vwqe_interval) > +{ > + uint64_t wait_ns; > + > + if (!roc_model_is_cn10k()) > + return; > + /* Due to HW errata writes to VWQE_FLUSH might hang, so instead > + * wait for max vwqe timeout interval. > + */ > + if (rq->vwqe_ena) { > + wait_ns = rq->vwqe_wait_tmo * (vwqe_interval + 1) * 100; > + plt_delay_us((wait_ns / 1E3) + 1); > + } > +} > + > int > nix_rq_ena_dis(struct dev *dev, struct roc_nix_rq *rq, bool enable) > { > @@ -66,9 +82,8 @@ roc_nix_rq_ena_dis(struct roc_nix_rq *rq, bool enable) > int rc; > > rc = nix_rq_ena_dis(&nix->dev, rq, enable); > + nix_rq_vwqe_flush(rq, nix->vwqe_interval); > > - if (roc_model_is_cn10k()) > - plt_write64(rq->qid, nix->base + NIX_LF_OP_VWQE_FLUSH); > return rc; > } > > -- > 2.17.1 >