Currently otx2_mbox_get_rsp get response once AF driver
interrupts after completion. But this funciton will get into
deadlock if called in another interrupt context.
To avoid it, implemented another version of this function which polls
on dedicated memory for a given timeout.
Also after clearing interrupt, there could UP messages available for
processing. So irq handler must check mbox messages.
Signed-off-by: Sunil Kumar Kori <skori@marvell.com>
---
v2:
- Included Makefile and meson build changes.
- Rebased patch on 19.11-rc4
drivers/common/octeontx2/Makefile | 2 +
drivers/common/octeontx2/meson.build | 2 +
drivers/common/octeontx2/otx2_mbox.c | 58 +++++++++++++++++++
drivers/common/octeontx2/otx2_mbox.h | 7 +++
.../rte_common_octeontx2_version.map | 7 +++
5 files changed, 76 insertions(+)
@@ -22,6 +22,8 @@ CFLAGS += -diag-disable 2259
endif
endif
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
EXPORT_MAP := rte_common_octeontx2_version.map
#
@@ -8,6 +8,8 @@ sources= files('otx2_dev.c',
'otx2_common.c',
)
+allow_experimental_apis = true
+
extra_flags = []
# This integrated controller runs only on a arm64 machine, remove 32bit warnings
if not dpdk_conf.get('RTE_ARCH_64')
@@ -11,6 +11,7 @@
#include <rte_cycles.h>
#include "otx2_mbox.h"
+#include "otx2_dev.h"
#define RVU_AF_AFPF_MBOX0 (0x02000)
#define RVU_AF_AFPF_MBOX1 (0x02008)
@@ -245,6 +246,63 @@ otx2_mbox_get_rsp(struct otx2_mbox *mbox, int devid, void **msg)
return msghdr->rc;
}
+/**
+ * @internal
+ * Polling for given wait time to get mailbox response
+ */
+int
+otx2_mbox_get_rsp_poll_tmo(struct otx2_mbox *mbox, int devid, void **msg,
+ uint32_t wait)
+{
+ struct otx2_mbox_dev *mdev = &mbox->dev[devid];
+ uint32_t timeout = 0, sleep = 1;
+ struct mbox_msghdr *msghdr;
+ uint64_t rsp_reg = 0;
+ uintptr_t reg_addr;
+ uint64_t offset;
+
+ rte_rmb();
+
+ offset = mbox->rx_start +
+ RTE_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+ msghdr = (struct mbox_msghdr *)((uintptr_t)mdev->mbase + offset);
+
+ reg_addr = mbox->reg_base + mbox->intr_offset;
+ while (!rsp_reg) {
+ rte_rmb();
+ rsp_reg = otx2_read64(reg_addr);
+
+ if (timeout >= wait)
+ return -ETIMEDOUT;
+
+ rte_delay_ms(sleep);
+ timeout += sleep;
+ }
+
+ if (msg != NULL)
+ *msg = msghdr;
+
+ /* Clear interrupt */
+ otx2_write64(rsp_reg, reg_addr);
+
+ /* Reset mbox */
+ otx2_mbox_reset(mbox, 0);
+
+ return msghdr->rc;
+}
+
+/**
+ * @internal
+ * Polling for 5 seconds to get mailbox response
+ */
+int
+otx2_mbox_get_rsp_poll(struct otx2_mbox *mbox, int devid, void **msg)
+{
+ uint32_t wait = 5 * MS_PER_S; /* 5 Seconds */
+
+ return otx2_mbox_get_rsp_poll_tmo(mbox, devid, msg, wait);
+}
+
/**
* @internal
* Wait and get mailbox response with timeout
@@ -1570,6 +1570,13 @@ void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid);
int otx2_mbox_wait_for_rsp(struct otx2_mbox *mbox, int devid);
int otx2_mbox_wait_for_rsp_tmo(struct otx2_mbox *mbox, int devid, uint32_t tmo);
int otx2_mbox_get_rsp(struct otx2_mbox *mbox, int devid, void **msg);
+
+__rte_experimental
+int otx2_mbox_get_rsp_poll(struct otx2_mbox *mbox, int devid, void **msg);
+__rte_experimental
+int otx2_mbox_get_rsp_poll_tmo(struct otx2_mbox *mbox, int devid, void **msg,
+ uint32_t tmo);
+
int otx2_mbox_get_rsp_tmo(struct otx2_mbox *mbox, int devid, void **msg,
uint32_t tmo);
int otx2_mbox_get_availmem(struct otx2_mbox *mbox, int devid);
@@ -33,3 +33,10 @@ DPDK_20.0 {
local: *;
};
+
+EXPERIMENTAL {
+ global:
+
+ otx2_mbox_get_rsp_poll;
+ otx2_mbox_get_rsp_poll_tmo;
+};