Provide recorded mbox send/receive history and a dump of it together with
the AEQ state so mailbox timeouts and response mismatches can be diagnosed.

Signed-off-by: Jiacheng Ye <[email protected]>
---
 drivers/net/hinic3/base/hinic3_eqs.c  | 59 +++++++++++++++++++++++++++
 drivers/net/hinic3/base/hinic3_eqs.h  |  2 +
 drivers/net/hinic3/base/hinic3_mbox.c | 53 ++++++++++++++++++++++++
 drivers/net/hinic3/base/hinic3_mbox.h | 22 ++++++++++
 4 files changed, 136 insertions(+)

diff --git a/drivers/net/hinic3/base/hinic3_eqs.c 
b/drivers/net/hinic3/base/hinic3_eqs.c
index 1fc78adc85..e961eda374 100644
--- a/drivers/net/hinic3/base/hinic3_eqs.c
+++ b/drivers/net/hinic3/base/hinic3_eqs.c
@@ -587,6 +587,65 @@ hinic3_dump_aeq_info(struct hinic3_hwdev *hwdev)
        }
 }
 
+void hinic3_dump_aeq_mbox_info(struct hinic3_hwdev *hwdev)
+{
+       struct save_mbox_info *save_mbox = NULL;
+       struct hinic3_eq *aeq = NULL;
+       struct hinic3_aeq_elem *aeqe_pos = NULL;
+       struct rte_pci_device *pci_dev = NULL;
+       struct rte_eth_dev *eth_dev = NULL;
+       uint32_t i, pos;
+       uint8_t src, size, wrapped, seq_id, seg_len, msg_id, mod;
+       uint8_t data[HINIC3_AEQE_DATA_SIZE];
+       uint16_t src_func_idx, cmd;
+       uint32_t aeqe_desc;
+       uint64_t mbox_header;
+       enum hinic3_aeq_type event;
+
+       eth_dev = &rte_eth_devices[hwdev->port_id];
+       pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
+       save_mbox = hwdev->func_to_func->save_mbox;
+       aeq = &hwdev->aeqs->aeq[HINIC3_MBOX_RSP_MSG_AEQ];
+
+       PMD_DRV_LOG(ERR, "Sending the latest mbox messages:");
+       for (i = 0; i < HINIC3_MBOX_SAVE_NUM; i++) {
+               pos = (hwdev->func_to_func->save_mbox->start + i) % 
HINIC3_MBOX_SAVE_NUM;
+               PMD_DRV_LOG(ERR, "send_msg_id: %u, cmd: %u, mod: %u, port: %u, 
func id: %u, bus: %u, devid: %u",
+                       save_mbox->send_info[pos].send_msg_id, 
save_mbox->send_info[pos].cmd,
+                       save_mbox->send_info[pos].mod, 
save_mbox->send_info[pos].port,
+                       save_mbox->send_info[pos].func_id, 
save_mbox->send_info[pos].bus,
+                       save_mbox->send_info[pos].devid);
+       }
+
+       PMD_DRV_LOG(ERR, "dump aeqe info:");
+       PMD_DRV_LOG(ERR, "port: %u, eq cid: %u, func id: %u, bus: %u, devid: 
%u, wrapped: %u",
+               hwdev->port_id, aeq->cons_idx, pci_dev->addr.function, 
pci_dev->addr.bus,
+               pci_dev->addr.devid, aeq->wrapped);
+       for (i = 0; i < aeq->eq_len; i++) {
+               /* Parsing the data field. */
+               aeqe_pos = GET_AEQ_ELEM(aeq, i);
+               aeqe_desc = rte_be_to_cpu_32(aeqe_pos->desc);
+               memcpy(data, aeqe_pos->aeqe_data, HINIC3_AEQE_DATA_SIZE);
+               hinic3_be32_to_cpu(data, HINIC3_AEQE_DATA_SIZE);
+               mbox_header = *((uint64_t *)data);
+               seq_id = HINIC3_MSG_HEADER_GET(mbox_header, SEQID);
+               seg_len = HINIC3_MSG_HEADER_GET(mbox_header, SEG_LEN);
+               src_func_idx = HINIC3_MSG_HEADER_GET(mbox_header, 
SRC_GLB_FUNC_IDX);
+               msg_id = HINIC3_MSG_HEADER_GET(mbox_header, MSG_ID);
+               mod = HINIC3_MSG_HEADER_GET(mbox_header, MODULE);
+               cmd = HINIC3_MSG_HEADER_GET(mbox_header, CMD);
+               /* Parsing the desc field. */
+               event = EQ_ELEM_DESC_GET(aeqe_desc, TYPE);
+               src = EQ_ELEM_DESC_GET(aeqe_desc, SRC);
+               size = EQ_ELEM_DESC_GET(aeqe_desc, SIZE);
+               wrapped = EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED);
+
+               PMD_DRV_LOG(ERR, "index: %d, msg_id: %u, mod: %u, cmd: %u, 
seq_id: %u, seg_len: %u,"
+                       "src_func_idx: %u, event: %u, src: %u, size: %u, 
wrapped: %u", i, msg_id,
+                       mod, cmd, seq_id, seg_len, src_func_idx, event, src, 
size, wrapped);
+       }
+}
+
 static int
 aeq_elem_handler(struct hinic3_eq *eq, uint32_t aeqe_desc,
                 struct hinic3_aeq_elem *aeqe_pos, void *param)
diff --git a/drivers/net/hinic3/base/hinic3_eqs.h 
b/drivers/net/hinic3/base/hinic3_eqs.h
index 365c9cbf39..38de79a705 100644
--- a/drivers/net/hinic3/base/hinic3_eqs.h
+++ b/drivers/net/hinic3/base/hinic3_eqs.h
@@ -85,6 +85,8 @@ void hinic3_aeqs_free(struct hinic3_hwdev *hwdev);
 
 void hinic3_dump_aeq_info(struct hinic3_hwdev *hwdev);
 
+void hinic3_dump_aeq_mbox_info(struct hinic3_hwdev *hwdev);
+
 int hinic3_aeq_poll_msg(struct hinic3_eq *eq, uint32_t timeout, void *param);
 
 void hinic3_dev_handle_aeq_event(struct hinic3_hwdev *hwdev, void *param);
diff --git a/drivers/net/hinic3/base/hinic3_mbox.c 
b/drivers/net/hinic3/base/hinic3_mbox.c
index c4ca2ed7ba..03aa5cfbb2 100644
--- a/drivers/net/hinic3/base/hinic3_mbox.c
+++ b/drivers/net/hinic3/base/hinic3_mbox.c
@@ -711,6 +711,35 @@ send_tlp_mbox_seg(struct hinic3_mbox *func_to_func, 
uint64_t header, uint16_t ds
        return 0;
 }
 
+static void hinic3_record_mbox_info(struct hinic3_mbox *func_to_func,
+                                   enum hinic3_mod_type mod, uint16_t cmd,
+                                   uint8_t msg_id)
+{
+       struct rte_pci_device *pci_dev = NULL;
+       struct rte_eth_dev *eth_dev = NULL;
+       struct mbox_send_info send_mbox;
+
+       eth_dev = &rte_eth_devices[func_to_func->hwdev->port_id];
+       pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
+       send_mbox.cmd = cmd;
+       send_mbox.mod = mod;
+       send_mbox.port = func_to_func->hwdev->port_id;
+       send_mbox.send_msg_id = msg_id;
+       send_mbox.func_id = pci_dev->addr.function;
+       send_mbox.devid = pci_dev->addr.devid;
+       send_mbox.bus = pci_dev->addr.bus;
+
+       uint8_t pos = (func_to_func->save_mbox->start + 
func_to_func->save_mbox->count) %
+                     HINIC3_MBOX_SAVE_NUM;
+       func_to_func->save_mbox->send_info[pos] = send_mbox;
+
+       if (func_to_func->save_mbox->count < HINIC3_MBOX_SAVE_NUM)
+               func_to_func->save_mbox->count++;
+       else
+               func_to_func->save_mbox->start = 
(func_to_func->save_mbox->start + 1) %
+                                                HINIC3_MBOX_SAVE_NUM;
+}
+
 static int
 send_mbox_to_func(struct hinic3_mbox *func_to_func, enum hinic3_mod_type mod,
                struct hinic3_handler_info *handler_info, struct mbox_msg_info 
*msg_info)
@@ -724,6 +753,9 @@ send_mbox_to_func(struct hinic3_mbox *func_to_func, enum 
hinic3_mod_type mod,
 
        rsp_aeq_id = HINIC3_MBOX_RSP_MSG_AEQ;
 
+       hinic3_record_mbox_info(func_to_func, mod, handler_info->cmd,
+                               msg_info->msg_id);
+
        /* Set the header message. */
        header = HINIC3_MSG_HEADER_SET(handler_info->in_size, MSG_LEN) |
                 HINIC3_MSG_HEADER_SET(mod, MODULE) |
@@ -782,6 +814,9 @@ send_tlp_mbox_to_func(struct hinic3_mbox *func_to_func, 
enum hinic3_mod_type mod
 
        rsp_aeq_id = HINIC3_MBOX_RSP_MSG_AEQ;
 
+       hinic3_record_mbox_info(func_to_func, mod, handler_info->cmd,
+                               msg_info->msg_id);
+
        /* Set the header message. */
        header = HINIC3_MSG_HEADER_SET(MBOX_TLP_HEADER_SZ, MSG_LEN) |
                 HINIC3_MSG_HEADER_SET(MBOX_TLP_HEADER_SZ, SEG_LEN) |
@@ -873,6 +908,7 @@ hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, enum 
hinic3_mod_type mod,
                goto send_err;
        }
 
+       func_to_func->mbox_send_cnt++;
        /* Wait for the response message. */
        time = timeout ? timeout : HINIC3_MBOX_COMP_TIME;
        aeq = &func_to_func->hwdev->aeqs->aeq[HINIC3_MBOX_RSP_MSG_AEQ];
@@ -880,15 +916,18 @@ hinic3_mbox_to_func(struct hinic3_mbox *func_to_func, 
enum hinic3_mod_type mod,
        if (err) {
                set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);
                PMD_DRV_LOG(ERR, "Send mailbox message time out");
+               hinic3_dump_aeq_mbox_info(func_to_func->hwdev);
                err = -ETIMEDOUT;
                goto send_err;
        }
 
+       func_to_func->mbox_ack_cnt++;
        /* Check whether mod and command of the rsp message match the sent 
message. */
        if (mod != mbox_for_resp->mod || handler_info->cmd != 
mbox_for_resp->cmd) {
                PMD_DRV_LOG(ERR,
                            "Invalid response mbox message, mod: 0x%x, cmd: 
0x%x, expect mod: 0x%x, cmd: 0x%x",
                            mbox_for_resp->mod, mbox_for_resp->cmd, mod, 
handler_info->cmd);
+               hinic3_dump_aeq_mbox_info(func_to_func->hwdev);
                err = -EFAULT;
                goto send_err;
        }
@@ -1129,6 +1168,16 @@ hinic3_func_to_func_init(struct hinic3_hwdev *hwdev)
 
        hwdev->func_to_func = func_to_func;
        func_to_func->hwdev = hwdev;
+
+       struct save_mbox_info *save_mbox = rte_zmalloc("save_mbox_info",
+                                                     sizeof(struct 
save_mbox_info), 0);
+       if (!save_mbox) {
+               err = -ENOMEM;
+               goto alloc_save_mbox_err;
+       }
+
+       func_to_func->save_mbox = save_mbox;
+
        rte_spinlock_init(&func_to_func->mbox_lock);
 
        /* Alloc the memory required by the mailbox. */
@@ -1170,6 +1219,9 @@ hinic3_func_to_func_init(struct hinic3_hwdev *hwdev)
        free_mbox_info(func_to_func->mbox_send);
 
 alloc_mbox_for_send_err:
+       rte_free(save_mbox);
+alloc_save_mbox_err:
+       hwdev->func_to_func = NULL;
        rte_free(func_to_func);
 
        return err;
@@ -1184,5 +1236,6 @@ hinic3_func_to_func_free(struct hinic3_hwdev *hwdev)
        free_mbox_tlp_buffer(func_to_func);
        free_mbox_info(func_to_func->mbox_resp);
        free_mbox_info(func_to_func->mbox_send);
+       rte_free(func_to_func->save_mbox);
        rte_free(func_to_func);
 }
diff --git a/drivers/net/hinic3/base/hinic3_mbox.h 
b/drivers/net/hinic3/base/hinic3_mbox.h
index df6de062e2..c0ee700ae6 100644
--- a/drivers/net/hinic3/base/hinic3_mbox.h
+++ b/drivers/net/hinic3/base/hinic3_mbox.h
@@ -15,6 +15,8 @@
 
 #define HINIC3_MAX_PF_FUNCS 32
 
+#define HINIC3_MBOX_SAVE_NUM          20
+
 /* Message header define. */
 #define HINIC3_MSG_HEADER_SRC_GLB_FUNC_IDX_SHIFT 0
 #define HINIC3_MSG_HEADER_STATUS_SHIFT          13
@@ -150,8 +152,25 @@ enum hinic3_mbox_cb_state {
        HINIC3_PPF_TO_PF_MBOX_CB_RUNNING
 };
 
+struct mbox_send_info {
+       uint16_t cmd;
+       enum hinic3_mod_type mod;
+       uint8_t send_msg_id;
+       uint8_t port;
+       uint8_t func_id;
+       uint8_t devid;
+       uint8_t bus;
+};
+
+struct save_mbox_info {
+       struct mbox_send_info send_info[HINIC3_MBOX_SAVE_NUM];
+       uint8_t start;
+       uint8_t count;
+};
+
 struct hinic3_mbox {
        struct hinic3_hwdev *hwdev;
+       struct save_mbox_info *save_mbox;
 
        struct hinic3_send_mbox send_mbox;
 
@@ -163,6 +182,9 @@ struct hinic3_mbox {
        enum mbox_event_state event_flag;
        /* Lock for mbox event flag. */
        rte_spinlock_t mbox_lock;
+
+       uint64_t mbox_send_cnt;
+       uint64_t mbox_ack_cnt;
 };
 
 int hinic3_mbox_func_aeqe_handler(struct hinic3_hwdev *hwdev, uint8_t *header,
-- 
2.33.0


Reply via email to