From d807dd7d4cd8e3ef4d42bd945cfb8318e4fef5b6 Mon Sep 17 00:00:00 2001 From: Xiaoyun Wang Date: Sat, 27 Jun 2020 11:55:44 +0800 Subject: [PATCH] net/hinic/base: check output of management sync channel Add output buffer and out size info for some cmds that use management sync channel, which can improve dfx capability when sent msg failed. Fixes: 7fcd6b05b923 ("net/hinic/base: support cmdq mechanism") Cc: stable@dpdk.org Signed-off-by: Xiaoyun Wang --- drivers/net/hinic/base/hinic_pmd_cmdq.c | 31 ++++-- drivers/net/hinic/base/hinic_pmd_hwdev.c | 129 +++++++++++++++------- drivers/net/hinic/base/hinic_pmd_niccfg.c | 27 ++--- drivers/net/hinic/base/hinic_pmd_nicio.c | 36 ++++-- 4 files changed, 151 insertions(+), 72 deletions(-) diff --git a/drivers/net/hinic/base/hinic_pmd_cmdq.c b/drivers/net/hinic/base/hinic_pmd_cmdq.c index 2e98b9c286..1816636c34 100644 --- a/drivers/net/hinic/base/hinic_pmd_cmdq.c +++ b/drivers/net/hinic/base/hinic_pmd_cmdq.c @@ -426,27 +426,31 @@ static int hinic_set_cmdq_ctxts(struct hinic_hwdev *hwdev) { struct hinic_cmdqs *cmdqs = hwdev->cmdqs; struct hinic_cmdq_ctxt *cmdq_ctxt; + struct hinic_cmdq_ctxt cmdq_ctxt_out; enum hinic_cmdq_type cmdq_type; + u16 out_size = sizeof(cmdq_ctxt_out); u16 in_size; int err; cmdq_type = HINIC_CMDQ_SYNC; + memset(&cmdq_ctxt_out, 0, out_size); for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) { cmdq_ctxt = &cmdqs->cmdq[cmdq_type].cmdq_ctxt; cmdq_ctxt->resp_aeq_num = HINIC_AEQ1; in_size = sizeof(*cmdq_ctxt); err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_CMDQ_CTXT_SET, - cmdq_ctxt, in_size, NULL, - NULL, 0); - if (err) { + cmdq_ctxt, in_size, &cmdq_ctxt_out, + &out_size, 0); + if (err || !out_size || cmdq_ctxt_out.status) { if (err == HINIC_MBOX_PF_BUSY_ACTIVE_FW || err == HINIC_DEV_BUSY_ACTIVE_FW) { cmdqs->status |= HINIC_CMDQ_SET_FAIL; PMD_DRV_LOG(ERR, "PF or VF fw is hot active"); } - PMD_DRV_LOG(ERR, "Set cmdq ctxt failed, err: %d", err); - return -EFAULT; + PMD_DRV_LOG(ERR, "Set cmdq ctxt failed, err: %d, status: 0x%x, out_size: 0x%x", + err, cmdq_ctxt_out.status, out_size); + return -EIO; } } @@ -631,6 +635,8 @@ static void hinic_cmdqs_free(struct hinic_hwdev *hwdev) static int hinic_set_cmdq_depth(struct hinic_hwdev *hwdev, u16 cmdq_depth) { struct hinic_root_ctxt root_ctxt; + u16 out_size = sizeof(root_ctxt); + int err; memset(&root_ctxt, 0, sizeof(root_ctxt)); root_ctxt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; @@ -638,10 +644,17 @@ static int hinic_set_cmdq_depth(struct hinic_hwdev *hwdev, u16 cmdq_depth) root_ctxt.ppf_idx = hinic_ppf_idx(hwdev); root_ctxt.set_cmdq_depth = 1; root_ctxt.cmdq_depth = (u8)ilog2(cmdq_depth); - return hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, - HINIC_MGMT_CMD_VAT_SET, - &root_ctxt, sizeof(root_ctxt), - NULL, NULL, 0); + err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, + HINIC_MGMT_CMD_VAT_SET, + &root_ctxt, sizeof(root_ctxt), + &root_ctxt, &out_size, 0); + if (err || !out_size || root_ctxt.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, "Set cmdq depth failed, err: %d, status: 0x%x, out_size: 0x%x", + err, root_ctxt.mgmt_msg_head.status, out_size); + return -EIO; + } + + return 0; } int hinic_comm_cmdqs_init(struct hinic_hwdev *hwdev) diff --git a/drivers/net/hinic/base/hinic_pmd_hwdev.c b/drivers/net/hinic/base/hinic_pmd_hwdev.c index cc42076780..c132de09e9 100644 --- a/drivers/net/hinic/base/hinic_pmd_hwdev.c +++ b/drivers/net/hinic/base/hinic_pmd_hwdev.c @@ -390,6 +390,8 @@ void hinic_osdep_deinit(struct hinic_hwdev *hwdev) int hinic_set_ci_table(void *hwdev, u16 q_id, struct hinic_sq_attr *attr) { struct hinic_cons_idx_attr cons_idx_attr; + u16 out_size = sizeof(cons_idx_attr); + int err; memset(&cons_idx_attr, 0, sizeof(cons_idx_attr)); cons_idx_attr.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; @@ -406,10 +408,17 @@ int hinic_set_ci_table(void *hwdev, u16 q_id, struct hinic_sq_attr *attr) cons_idx_attr.sq_id = q_id; cons_idx_attr.ci_addr = attr->ci_dma_base; - return hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, + err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_L2NIC_SQ_CI_ATTR_SET, &cons_idx_attr, sizeof(cons_idx_attr), - NULL, NULL, 0); + &cons_idx_attr, &out_size, 0); + if (err || !out_size || cons_idx_attr.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, "Set ci attribute table failed, err: %d, status: 0x%x, out_size: 0x%x", + err, cons_idx_attr.mgmt_msg_head.status, out_size); + return -EIO; + } + + return 0; } /** @@ -422,7 +431,9 @@ int hinic_set_ci_table(void *hwdev, u16 q_id, struct hinic_sq_attr *attr) */ int hinic_set_pagesize(void *hwdev, u8 page_size) { - struct hinic_page_size cmd; + struct hinic_page_size page_size_info; + u16 out_size = sizeof(page_size_info); + int err; if (page_size > HINIC_PAGE_SIZE_MAX) { PMD_DRV_LOG(ERR, "Invalid page_size %u, bigger than %u", @@ -430,16 +441,23 @@ int hinic_set_pagesize(void *hwdev, u8 page_size) return -EINVAL; } - memset(&cmd, 0, sizeof(cmd)); - cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; - cmd.func_idx = hinic_global_func_id(hwdev); - cmd.ppf_idx = hinic_ppf_idx(hwdev); - cmd.page_size = page_size; + memset(&page_size_info, 0, sizeof(page_size_info)); + page_size_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; + page_size_info.func_idx = hinic_global_func_id(hwdev); + page_size_info.ppf_idx = hinic_ppf_idx(hwdev); + page_size_info.page_size = page_size; - return hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, - HINIC_MGMT_CMD_PAGESIZE_SET, - &cmd, sizeof(cmd), - NULL, NULL, 0); + err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, + HINIC_MGMT_CMD_PAGESIZE_SET, + &page_size_info, sizeof(page_size_info), + &page_size_info, &out_size, 0); + if (err || !out_size || page_size_info.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, "Set wq page size failed, err: %d, status: 0x%x, out_size: 0x%0x", + err, page_size_info.mgmt_msg_head.status, out_size); + return -EIO; + } + + return 0; } static int wait_for_flr_finish(struct hinic_hwif *hwif) @@ -546,7 +564,9 @@ static int hinic_pf_rx_tx_flush(struct hinic_hwdev *hwdev) struct hinic_hwif *hwif = hwdev->hwif; struct hinic_clear_doorbell clear_db; struct hinic_clear_resource clr_res; + u16 out_size; int err; + int ret = 0; rte_delay_ms(100); @@ -557,15 +577,19 @@ static int hinic_pf_rx_tx_flush(struct hinic_hwdev *hwdev) } hinic_disable_doorbell(hwif); + out_size = sizeof(clear_db); memset(&clear_db, 0, sizeof(clear_db)); clear_db.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; clear_db.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif); clear_db.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_FLUSH_DOORBELL, &clear_db, - sizeof(clear_db), NULL, NULL, 0); - if (err) - PMD_DRV_LOG(WARNING, "Flush doorbell failed"); + sizeof(clear_db), &clear_db, &out_size, 0); + if (err || !out_size || clear_db.mgmt_msg_head.status) { + PMD_DRV_LOG(WARNING, "Flush doorbell failed, err: %d, status: 0x%x, out_size: 0x%x", + err, clear_db.mgmt_msg_head.status, out_size); + ret = err ? err : (-EIO); + } hinic_set_pf_status(hwif, HINIC_PF_STATUS_FLR_START_FLAG); memset(&clr_res, 0, sizeof(clr_res)); @@ -576,20 +600,27 @@ static int hinic_pf_rx_tx_flush(struct hinic_hwdev *hwdev) err = hinic_msg_to_mgmt_no_ack(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_START_FLR, &clr_res, sizeof(clr_res), NULL, NULL); - if (err) - PMD_DRV_LOG(WARNING, "Notice flush message failed"); + if (err) { + PMD_DRV_LOG(WARNING, "Notice flush msg failed, err: %d", err); + ret = err; + } err = wait_for_flr_finish(hwif); - if (err) - PMD_DRV_LOG(WARNING, "Wait firmware FLR timeout"); + if (err) { + PMD_DRV_LOG(WARNING, "Wait firmware FLR timeout, err: %d", err); + ret = err; + } hinic_enable_doorbell(hwif); err = hinic_reinit_cmdq_ctxts(hwdev); - if (err) - PMD_DRV_LOG(WARNING, "Reinit cmdq failed when pf flush"); + if (err) { + PMD_DRV_LOG(WARNING, + "Reinit cmdq failed when pf flush, err: %d", err); + ret = err; + } - return 0; + return ret; } int hinic_func_rx_tx_flush(struct hinic_hwdev *hwdev) @@ -623,9 +654,9 @@ static int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev, &msix_cfg, sizeof(msix_cfg), &msix_cfg, &out_size, 0); if (err || !out_size || msix_cfg.mgmt_msg_head.status) { - PMD_DRV_LOG(ERR, "Get interrupt config failed, ret: %d", - msix_cfg.mgmt_msg_head.status); - return -EINVAL; + PMD_DRV_LOG(ERR, "Get interrupt config failed, err: %d, status: 0x%x, out size: 0x%x", + err, msix_cfg.mgmt_msg_head.status, out_size); + return -EIO; } interrupt_info->lli_credit_limit = msix_cfg.lli_credit_cnt; @@ -683,9 +714,9 @@ int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev, &msix_cfg, sizeof(msix_cfg), &msix_cfg, &out_size, 0); if (err || !out_size || msix_cfg.mgmt_msg_head.status) { - PMD_DRV_LOG(ERR, "Set interrupt config failed, ret: %d", - msix_cfg.mgmt_msg_head.status); - return -EINVAL; + PMD_DRV_LOG(ERR, "Set interrupt config failed, err: %d, status: 0x%x, out size: 0x%x", + err, msix_cfg.mgmt_msg_head.status, out_size); + return -EIO; } return 0; @@ -770,6 +801,8 @@ static int set_vf_dma_attr_entry(struct hinic_hwdev *hwdev, u8 entry_idx, enum hinic_pcie_tph tph_en) { struct hinic_vf_dma_attr_table attr; + u16 out_size = sizeof(attr); + int err; memset(&attr, 0, sizeof(attr)); attr.func_idx = hinic_global_func_id(hwdev); @@ -782,9 +815,16 @@ static int set_vf_dma_attr_entry(struct hinic_hwdev *hwdev, u8 entry_idx, attr.no_snooping = no_snooping; attr.tph_en = tph_en; - return hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, - HINIC_MGMT_CMD_DMA_ATTR_SET, - &attr, sizeof(attr), NULL, NULL, 0); + err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, + HINIC_MGMT_CMD_DMA_ATTR_SET, + &attr, sizeof(attr), &attr, &out_size, 0); + if (err || !out_size || attr.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, "Set dma attribute failed, err: %d, status: 0x%x, out_size: 0x%x", + err, attr.mgmt_msg_head.status, out_size); + return -EIO; + } + + return 0; } /** @@ -926,17 +966,26 @@ static void fault_report_show(struct hinic_hwdev *hwdev, static int resources_state_set(struct hinic_hwdev *hwdev, enum hinic_res_state state) { - struct hinic_hwif *hwif = hwdev->hwif; struct hinic_cmd_set_res_state res_state; + u16 out_size = sizeof(res_state); + int err; memset(&res_state, 0, sizeof(res_state)); res_state.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; - res_state.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif); + res_state.func_idx = HINIC_HWIF_GLOBAL_IDX(hwdev->hwif); res_state.state = state; - return hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, + err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_RES_STATE_SET, - &res_state, sizeof(res_state), NULL, NULL, 0); + &res_state, sizeof(res_state), + &res_state, &out_size, 0); + if (err || !out_size || res_state.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, "Set resources state failed, err: %d, status: 0x%x, out_size: 0x%x", + err, res_state.mgmt_msg_head.status, out_size); + return -EIO; + } + + return 0; } /** @@ -1020,6 +1069,7 @@ int hinic_l2nic_reset(struct hinic_hwdev *hwdev) { struct hinic_hwif *hwif = hwdev->hwif; struct hinic_l2nic_reset l2nic_reset; + u16 out_size = sizeof(l2nic_reset); int err = 0; err = hinic_set_vport_enable(hwdev, false); @@ -1036,10 +1086,11 @@ int hinic_l2nic_reset(struct hinic_hwdev *hwdev) err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_L2NIC_RESET, &l2nic_reset, sizeof(l2nic_reset), - NULL, NULL, 0); - if (err || l2nic_reset.mgmt_msg_head.status) { - PMD_DRV_LOG(ERR, "Reset L2NIC resources failed"); - return -EFAULT; + &l2nic_reset, &out_size, 0); + if (err || !out_size || l2nic_reset.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, "Reset L2NIC resources failed, err: %d, status: 0x%x, out_size: 0x%x", + err, l2nic_reset.mgmt_msg_head.status, out_size); + return -EIO; } return 0; diff --git a/drivers/net/hinic/base/hinic_pmd_niccfg.c b/drivers/net/hinic/base/hinic_pmd_niccfg.c index c5663dfabc..e894503d73 100644 --- a/drivers/net/hinic/base/hinic_pmd_niccfg.c +++ b/drivers/net/hinic/base/hinic_pmd_niccfg.c @@ -18,7 +18,6 @@ buf_in, in_size, \ buf_out, out_size, 0) - /** * hinic_init_function_table - Initialize function table. * @@ -380,9 +379,8 @@ int hinic_add_remove_vlan(void *hwdev, u16 vlan_id, u16 func_id, bool add) vlan_info.func_id = func_id; vlan_info.vlan_id = vlan_id; - err = l2nic_msg_to_mgmt_sync(hwdev, cmd, &vlan_info, - sizeof(vlan_info), &vlan_info, - &out_size); + err = l2nic_msg_to_mgmt_sync(hwdev, cmd, &vlan_info, sizeof(vlan_info), + &vlan_info, &out_size); if (err || !out_size || vlan_info.mgmt_msg_head.status) { PMD_DRV_LOG(ERR, "Failed to %s vlan, err: %d, status: 0x%x, out size: 0x%x", @@ -469,8 +467,8 @@ int hinic_set_rx_vlan_offload(void *hwdev, u8 en) vlan_cfg.vlan_rx_offload = en; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD, - &vlan_cfg, sizeof(vlan_cfg), - &vlan_cfg, &out_size); + &vlan_cfg, sizeof(vlan_cfg), + &vlan_cfg, &out_size); if (err || !out_size || vlan_cfg.mgmt_msg_head.status) { PMD_DRV_LOG(ERR, "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x", @@ -626,7 +624,7 @@ int hinic_get_port_info(void *hwdev, struct nic_port_info *port_info) PMD_DRV_LOG(ERR, "Failed to get port info, err: %d, status: 0x%x, out size: 0x%x", err, port_msg.mgmt_msg_head.status, out_size); - return err; + return -EIO; } port_info->autoneg_cap = port_msg.autoneg_cap; @@ -1270,7 +1268,6 @@ int hinic_set_rx_vhd_mode(void *hwdev, u16 vhd_mode, u16 rx_buf_sz) PMD_DRV_LOG(ERR, "Failed to set vhd mode, err: %d, status: 0x%x, out size: 0x%x", err, vhd_mode_cfg.mgmt_msg_head.status, out_size); - return -EIO; } @@ -1425,8 +1422,7 @@ int hinic_set_anti_attack(void *hwdev, bool enable) rate.xbs = ANTI_ATTACK_DEFAULT_XBS; err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_ANTI_ATTACK_RATE, - &rate, sizeof(rate), &rate, - &out_size); + &rate, sizeof(rate), &rate, &out_size); if (err || !out_size || rate.mgmt_msg_head.status) { PMD_DRV_LOG(ERR, "Can't %s port Anti-Attack rate limit, err: %d, status: 0x%x, out size: 0x%x", (enable ? "enable" : "disable"), err, @@ -1530,9 +1526,9 @@ int hinic_set_fast_recycle_mode(void *hwdev, u8 mode) sizeof(fast_recycled_mode), &fast_recycled_mode, &out_size, 0); if (err || fast_recycled_mode.mgmt_msg_head.status || !out_size) { - PMD_DRV_LOG(ERR, "Failed to set recycle mode, ret: %d", - fast_recycled_mode.mgmt_msg_head.status); - return -EFAULT; + PMD_DRV_LOG(ERR, "Failed to set recycle mode, err: %d, status: 0x%x, out size: 0x%x", + err, fast_recycled_mode.mgmt_msg_head.status, out_size); + return -EIO; } return 0; @@ -1756,12 +1752,11 @@ int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id) err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC, HINIC_PORT_CMD_GET_VF_COS, &vf_cos, - sizeof(vf_cos), &vf_cos, - &out_size, 0); + sizeof(vf_cos), &vf_cos, &out_size, 0); if (err || !out_size || vf_cos.mgmt_msg_head.status) { PMD_DRV_LOG(ERR, "Get VF default cos failed, err: %d, status: 0x%x, out size: 0x%x", err, vf_cos.mgmt_msg_head.status, out_size); - return -EFAULT; + return -EIO; } *cos_id = vf_cos.state.default_cos; diff --git a/drivers/net/hinic/base/hinic_pmd_nicio.c b/drivers/net/hinic/base/hinic_pmd_nicio.c index 7f7e11dbd2..7ec3e4ce76 100644 --- a/drivers/net/hinic/base/hinic_pmd_nicio.c +++ b/drivers/net/hinic/base/hinic_pmd_nicio.c @@ -471,6 +471,8 @@ static int hinic_set_root_ctxt(void *hwdev, u16 rq_depth, u16 sq_depth, int rx_buf_sz) { struct hinic_root_ctxt root_ctxt; + u16 out_size = sizeof(root_ctxt); + int err; memset(&root_ctxt, 0, sizeof(root_ctxt)); root_ctxt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; @@ -483,10 +485,18 @@ hinic_set_root_ctxt(void *hwdev, u16 rq_depth, u16 sq_depth, int rx_buf_sz) root_ctxt.rx_buf_sz = get_hw_rx_buf_size(rx_buf_sz); root_ctxt.sq_depth = (u16)ilog2(sq_depth); - return hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, - HINIC_MGMT_CMD_VAT_SET, - &root_ctxt, sizeof(root_ctxt), - NULL, NULL, 0); + err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, + HINIC_MGMT_CMD_VAT_SET, + &root_ctxt, sizeof(root_ctxt), + &root_ctxt, &out_size, 0); + if (err || !out_size || root_ctxt.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, + "Set root context failed, err: %d, status: 0x%x, out_size: 0x%x", + err, root_ctxt.mgmt_msg_head.status, out_size); + return -EIO; + } + + return 0; } /** @@ -499,6 +509,8 @@ hinic_set_root_ctxt(void *hwdev, u16 rq_depth, u16 sq_depth, int rx_buf_sz) static int hinic_clean_root_ctxt(void *hwdev) { struct hinic_root_ctxt root_ctxt; + u16 out_size = sizeof(root_ctxt); + int err; memset(&root_ctxt, 0, sizeof(root_ctxt)); root_ctxt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1; @@ -511,10 +523,18 @@ static int hinic_clean_root_ctxt(void *hwdev) root_ctxt.rx_buf_sz = 0; root_ctxt.sq_depth = 0; - return hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, - HINIC_MGMT_CMD_VAT_SET, - &root_ctxt, sizeof(root_ctxt), - NULL, NULL, 0); + err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, + HINIC_MGMT_CMD_VAT_SET, + &root_ctxt, sizeof(root_ctxt), + &root_ctxt, &out_size, 0); + if (err || !out_size || root_ctxt.mgmt_msg_head.status) { + PMD_DRV_LOG(ERR, + "Clean root context failed, err: %d, status: 0x%x, out_size: 0x%x", + err, root_ctxt.mgmt_msg_head.status, out_size); + return -EIO; + } + + return 0; } /* init qps ctxt and set sq ci attr and arm all sq and set vat page_size */ -- 2.20.1