]> git.droids-corp.org - dpdk.git/commitdiff
common/cnxk: add workaround for vWQE flush
authorPavan Nikhilesh <pbhagavatula@marvell.com>
Mon, 13 Dec 2021 20:54:23 +0000 (02:24 +0530)
committerJerin Jacob <jerinj@marvell.com>
Mon, 24 Jan 2022 09:03:28 +0000 (10:03 +0100)
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: stable@dpdk.org
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
drivers/common/cnxk/roc_nix_inl.c
drivers/common/cnxk/roc_nix_inl_dev.c
drivers/common/cnxk/roc_nix_inl_priv.h
drivers/common/cnxk/roc_nix_priv.h
drivers/common/cnxk/roc_nix_queue.c

index f0fc6904173d90e405c64cb19fec155a6d35196c..e8981c4aa4a4dae9dff5ed3eb40f594414d307e9 100644 (file)
@@ -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;
 }
index a0fe6ecd82a6fbfaefc85f60258fd5d2e82c2966..10912a6c93c923547c71f968be39c56a3229e753 100644 (file)
@@ -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) {
index 3dc526f9296e845735faf341220561ff01969905..be53a3fa813a46fd555e305b6d8b78370a4f93b7 100644 (file)
@@ -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;
index 04575af2951804823fed32456357b3da83e18471..deb2a6ba11df40733b629cc2c5e7127950876edc 100644 (file)
@@ -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.
index c8c8401d819da632015a99d0eead541795cbe103..d5f6813e699cc2c2e67910dd91390774bc6017fd 100644 (file)
@@ -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;
 }