common/octeontx2: add AF to PF mailbox IRQ and msg handlers

This patch adds support for AF to PF mailbox interrupt and message
handling. PF writes the message on mapped mailbox region
followed by writing the mailbox doorbell register. Upon receiving,
the mailbox request in AF(In Linux kernel), It processes the messages
and update the counter memory and update the AF mbox doorbell
register. That would trigger a VFIO interrupt to userspace and
otx2_process_msgs() will handle it.

Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
This commit is contained in:
Nithin Dabilpuram 2019-06-22 18:54:00 +05:30 committed by Thomas Monjalon
parent 0e9734fe41
commit 9190acdd7a

View File

@ -14,6 +14,9 @@
#include "otx2_dev.h"
#include "otx2_mbox.h"
#define RVU_MAX_VF 64 /* RVU_PF_VFPF_MBOX_INT(0..1) */
#define RVU_MAX_INT_RETRY 3
/* PF/VF message handling timer */
#define VF_PF_MBOX_TIMER_MS (20 * 1000)
@ -47,6 +50,108 @@ mbox_mem_unmap(void *va, size_t size)
munmap(va, size);
}
static void
otx2_process_msgs(struct otx2_dev *dev, struct otx2_mbox *mbox)
{
struct otx2_mbox_dev *mdev = &mbox->dev[0];
struct mbox_hdr *req_hdr;
struct mbox_msghdr *msg;
int msgs_acked = 0;
int offset;
uint16_t i;
req_hdr = (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->rx_start);
if (req_hdr->num_msgs == 0)
return;
offset = mbox->rx_start + RTE_ALIGN(sizeof(*req_hdr), MBOX_MSG_ALIGN);
for (i = 0; i < req_hdr->num_msgs; i++) {
msg = (struct mbox_msghdr *)((uintptr_t)mdev->mbase + offset);
msgs_acked++;
otx2_base_dbg("Message 0x%x (%s) pf:%d/vf:%d",
msg->id, otx2_mbox_id2name(msg->id),
otx2_get_pf(msg->pcifunc),
otx2_get_vf(msg->pcifunc));
switch (msg->id) {
/* Add message id's that are handled here */
case MBOX_MSG_READY:
/* Get our identity */
dev->pf_func = msg->pcifunc;
break;
default:
if (msg->rc)
otx2_err("Message (%s) response has err=%d",
otx2_mbox_id2name(msg->id), msg->rc);
break;
}
offset = mbox->rx_start + msg->next_msgoff;
}
otx2_mbox_reset(mbox, 0);
/* Update acked if someone is waiting a message */
mdev->msgs_acked = msgs_acked;
rte_wmb();
}
static void
otx2_af_pf_mbox_irq(void *param)
{
struct otx2_dev *dev = param;
uint64_t intr;
intr = otx2_read64(dev->bar2 + RVU_PF_INT);
if (intr == 0)
return;
otx2_write64(intr, dev->bar2 + RVU_PF_INT);
otx2_base_dbg("Irq 0x%" PRIx64 "(pf:%d,vf:%d)", intr, dev->pf, dev->vf);
if (intr)
/* First process all configuration messages */
otx2_process_msgs(dev, dev->mbox);
}
static int
mbox_register_irq(struct rte_pci_device *pci_dev, struct otx2_dev *dev)
{
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int rc;
otx2_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1C);
dev->timer_set = 0;
/* MBOX interrupt AF <-> PF */
rc = otx2_register_irq(intr_handle, otx2_af_pf_mbox_irq,
dev, RVU_PF_INT_VEC_AFPF_MBOX);
if (rc) {
otx2_err("Fail to register AF<->PF mbox irq");
return rc;
}
otx2_write64(~0ull, dev->bar2 + RVU_PF_INT);
otx2_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1S);
return rc;
}
static void
mbox_unregister_irq(struct rte_pci_device *pci_dev, struct otx2_dev *dev)
{
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
otx2_write64(~0ull, dev->bar2 + RVU_PF_INT_ENA_W1C);
dev->timer_set = 0;
/* MBOX interrupt AF <-> PF */
otx2_unregister_irq(intr_handle, otx2_af_pf_mbox_irq, dev,
RVU_PF_INT_VEC_AFPF_MBOX);
}
static void
otx2_update_pass_hwcap(struct rte_pci_device *pci_dev, struct otx2_dev *dev)
{
@ -120,10 +225,15 @@ otx2_dev_init(struct rte_pci_device *pci_dev, void *otx2_dev)
if (rc)
goto error;
/* Register mbox interrupts */
rc = mbox_register_irq(pci_dev, dev);
if (rc)
goto mbox_fini;
/* Check the readiness of PF/VF */
rc = otx2_send_ready_msg(dev->mbox, &dev->pf_func);
if (rc)
goto mbox_fini;
goto mbox_unregister;
dev->pf = otx2_get_pf(dev->pf_func);
dev->vf = otx2_get_vf(dev->pf_func);
@ -162,6 +272,8 @@ otx2_dev_init(struct rte_pci_device *pci_dev, void *otx2_dev)
iounmap:
mbox_mem_unmap(hwbase, MBOX_SIZE * pci_dev->max_vfs);
mbox_unregister:
mbox_unregister_irq(pci_dev, dev);
mbox_fini:
otx2_mbox_fini(dev->mbox);
otx2_mbox_fini(&dev->mbox_up);
@ -176,6 +288,7 @@ error:
void
otx2_dev_fini(struct rte_pci_device *pci_dev, void *otx2_dev)
{
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct otx2_dev *dev = otx2_dev;
struct otx2_idev_cfg *idev;
struct otx2_mbox *mbox;
@ -185,6 +298,8 @@ otx2_dev_fini(struct rte_pci_device *pci_dev, void *otx2_dev)
if (idev->npa_lf && idev->npa_lf->pci_dev == pci_dev)
idev->npa_lf = NULL;
mbox_unregister_irq(pci_dev, dev);
/* Release PF - VF */
mbox = &dev->mbox_vfpf;
if (mbox->hwbase && mbox->dev)
@ -200,4 +315,7 @@ otx2_dev_fini(struct rte_pci_device *pci_dev, void *otx2_dev)
mbox = &dev->mbox_up;
otx2_mbox_fini(mbox);
dev->mbox_active = 0;
/* Disable MSIX vectors */
otx2_disable_irqs(intr_handle);
}