[1/2] common/cnxk: clear rvum interrupts

Message ID 20210921110038.115560-1-hkalra@marvell.com (mailing list archive)
State Accepted, archived
Delegated to: Jerin Jacob
Headers
Series [1/2] common/cnxk: clear rvum interrupts |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Harman Kalra Sept. 21, 2021, 11 a.m. UTC
  As per an known HW issue RVUM interrupts may get dropped, If an RVUM
interrupt event occurs when PCCPF_XXX_MSIX_CAP_HDR[MSIXEN]=0 then no
interrupt is triggered, which is expected. But after MSIXEN is set to
1, subsequently if same interrupts event occurs again, still no
interrupt will be triggered.

As a workaround, all RVUM interrupt lines should be cleared between
MSIXEN=0 and MSIXEN=1.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
---
 drivers/common/cnxk/roc_dev.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
  

Comments

Jerin Jacob Sept. 30, 2021, 3:53 p.m. UTC | #1
On Tue, Sep 21, 2021 at 4:30 PM Harman Kalra <hkalra@marvell.com> wrote:
>
> As per an known HW issue RVUM interrupts may get dropped, If an RVUM
> interrupt event occurs when PCCPF_XXX_MSIX_CAP_HDR[MSIXEN]=0 then no
> interrupt is triggered, which is expected. But after MSIXEN is set to
> 1, subsequently if same interrupts event occurs again, still no
> interrupt will be triggered.
>
> As a workaround, all RVUM interrupt lines should be cleared between
> MSIXEN=0 and MSIXEN=1.
>
> Signed-off-by: Harman Kalra <hkalra@marvell.com>

Series Acked-by: Jerin Jacob <jerinj@marvell.com>
Series applied to dpdk-next-net-mrvl/for-next-net. Thanks.

Changed the git log to:

commit b17c509dccf4b05d1471a2dac9c6cfd6ee78c94f (HEAD -> for-next-net)
Author: Harman Kalra <hkalra@marvell.com>
Date:   Tue Sep 21 16:30:38 2021 +0530

    common/cnxk: enable CQ overflow errata

    An issue exists on some HW revisions whereby if a CQ overflows
    NIX may have undefined behavior, e.g. free incorrect buffers.
    Implementing a workaround for this known HW issue.

    Signed-off-by: Harman Kalra <hkalra@marvell.com>
    Acked-by: Jerin Jacob <jerinj@marvell.com>

commit 416bf1eda5727a967de7b4c0475d350996e41720
Author: Harman Kalra <hkalra@marvell.com>
Date:   Tue Sep 21 16:30:37 2021 +0530

    common/cnxk: enable RVUM interrupt errata

    As per an known HW issue RVUM interrupts may get dropped, If an RVUM
    interrupt event occurs when PCCPF_XXX_MSIX_CAP_HDR[MSIXEN]=0 then no
    interrupt is triggered, which is expected. But after MSIXEN is set to
    1, subsequently if same interrupts event occurs again, still no
    interrupt will be triggered.

    As a workaround, all RVUM interrupt lines should be cleared between
    MSIXEN=0 and MSIXEN=1.

    Signed-off-by: Harman Kalra <hkalra@marvell.com>
    Acked-by: Jerin Jacob <jerinj@marvell.com>



> ---
>  drivers/common/cnxk/roc_dev.c | 35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
>
> diff --git a/drivers/common/cnxk/roc_dev.c b/drivers/common/cnxk/roc_dev.c
> index 4e204373dc..ce6980cbe4 100644
> --- a/drivers/common/cnxk/roc_dev.c
> +++ b/drivers/common/cnxk/roc_dev.c
> @@ -884,6 +884,38 @@ vf_flr_register_irqs(struct plt_pci_device *pci_dev, struct dev *dev)
>         return 0;
>  }
>
> +static void
> +clear_rvum_interrupts(struct dev *dev)
> +{
> +       uint64_t intr;
> +       int i;
> +
> +       if (dev_is_vf(dev)) {
> +               /* Clear VF mbox interrupt */
> +               intr = plt_read64(dev->bar2 + RVU_VF_INT);
> +               if (intr)
> +                       plt_write64(intr, dev->bar2 + RVU_VF_INT);
> +       } else {
> +               /* Clear AF PF interrupt line */
> +               intr = plt_read64(dev->bar2 + RVU_PF_INT);
> +               if (intr)
> +                       plt_write64(intr, dev->bar2 + RVU_PF_INT);
> +               for (i = 0; i < MAX_VFPF_DWORD_BITS; ++i) {
> +                       /* Clear MBOX interrupts */
> +                       intr = plt_read64(dev->bar2 + RVU_PF_VFPF_MBOX_INTX(i));
> +                       if (intr)
> +                               plt_write64(intr,
> +                                           dev->bar2 +
> +                                                   RVU_PF_VFPF_MBOX_INTX(i));
> +                       /* Clear VF FLR interrupts */
> +                       intr = plt_read64(dev->bar2 + RVU_PF_VFFLR_INTX(i));
> +                       if (intr)
> +                               plt_write64(intr,
> +                                           dev->bar2 + RVU_PF_VFFLR_INTX(i));
> +               }
> +       }
> +}
> +
>  int
>  dev_active_vfs(struct dev *dev)
>  {
> @@ -1090,6 +1122,9 @@ dev_init(struct dev *dev, struct plt_pci_device *pci_dev)
>                 intr_offset = RVU_PF_INT;
>         }
>
> +       /* Clear all RVUM interrupts */
> +       clear_rvum_interrupts(dev);
> +
>         /* Initialize the local mbox */
>         rc = mbox_init(&dev->mbox_local, mbox, bar2, direction, 1, intr_offset);
>         if (rc)
> --
> 2.18.0
>
  

Patch

diff --git a/drivers/common/cnxk/roc_dev.c b/drivers/common/cnxk/roc_dev.c
index 4e204373dc..ce6980cbe4 100644
--- a/drivers/common/cnxk/roc_dev.c
+++ b/drivers/common/cnxk/roc_dev.c
@@ -884,6 +884,38 @@  vf_flr_register_irqs(struct plt_pci_device *pci_dev, struct dev *dev)
 	return 0;
 }
 
+static void
+clear_rvum_interrupts(struct dev *dev)
+{
+	uint64_t intr;
+	int i;
+
+	if (dev_is_vf(dev)) {
+		/* Clear VF mbox interrupt */
+		intr = plt_read64(dev->bar2 + RVU_VF_INT);
+		if (intr)
+			plt_write64(intr, dev->bar2 + RVU_VF_INT);
+	} else {
+		/* Clear AF PF interrupt line */
+		intr = plt_read64(dev->bar2 + RVU_PF_INT);
+		if (intr)
+			plt_write64(intr, dev->bar2 + RVU_PF_INT);
+		for (i = 0; i < MAX_VFPF_DWORD_BITS; ++i) {
+			/* Clear MBOX interrupts */
+			intr = plt_read64(dev->bar2 + RVU_PF_VFPF_MBOX_INTX(i));
+			if (intr)
+				plt_write64(intr,
+					    dev->bar2 +
+						    RVU_PF_VFPF_MBOX_INTX(i));
+			/* Clear VF FLR interrupts */
+			intr = plt_read64(dev->bar2 + RVU_PF_VFFLR_INTX(i));
+			if (intr)
+				plt_write64(intr,
+					    dev->bar2 + RVU_PF_VFFLR_INTX(i));
+		}
+	}
+}
+
 int
 dev_active_vfs(struct dev *dev)
 {
@@ -1090,6 +1122,9 @@  dev_init(struct dev *dev, struct plt_pci_device *pci_dev)
 		intr_offset = RVU_PF_INT;
 	}
 
+	/* Clear all RVUM interrupts */
+	clear_rvum_interrupts(dev);
+
 	/* Initialize the local mbox */
 	rc = mbox_init(&dev->mbox_local, mbox, bar2, direction, 1, intr_offset);
 	if (rc)