diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw.h b/drivers/net/ethernet/huawei/hinic/hinic_hw.h index 0947201690c15bb949e4e83825bb2e99c9897c14..e489a00cab2cfed4d8c6ae6b3c4e5f351f53086d 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw.h @@ -199,7 +199,8 @@ struct nic_interrupt_info { int hinic_get_interrupt_cfg(void *hwdev, struct nic_interrupt_info *interrupt_info); - +int hinic_set_interrupt_cfg_direct(void *hwdev, + struct nic_interrupt_info *interrupt_info); int hinic_set_interrupt_cfg(void *hwdev, struct nic_interrupt_info interrupt_info); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c b/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c index 8d6675c5039affa05aaafd516e8afe1ffb3abd33..101b671db4250b2191b46c44561cb7bd86f8f63c 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c @@ -1572,45 +1572,27 @@ int hinic_get_interrupt_cfg(void *hwdev, } EXPORT_SYMBOL(hinic_get_interrupt_cfg); -int hinic_set_interrupt_cfg(void *hwdev, - struct nic_interrupt_info interrupt_info) +int hinic_set_interrupt_cfg_direct(void *hwdev, + struct nic_interrupt_info *interrupt_info) { struct hinic_hwdev *nic_hwdev = hwdev; struct hinic_msix_config msix_cfg = {0}; - struct nic_interrupt_info temp_info; u16 out_size = sizeof(msix_cfg); int err; if (!hwdev) return -EINVAL; - temp_info.msix_index = interrupt_info.msix_index; - - err = hinic_get_interrupt_cfg(hwdev, &temp_info); - if (err) - return -EINVAL; - err = hinic_global_func_id_get(hwdev, &msix_cfg.func_id); if (err) return err; - msix_cfg.msix_index = (u16)interrupt_info.msix_index; - msix_cfg.lli_credit_cnt = temp_info.lli_credit_limit; - msix_cfg.lli_tmier_cnt = temp_info.lli_timer_cfg; - msix_cfg.pending_cnt = temp_info.pending_limt; - msix_cfg.coalesct_timer_cnt = temp_info.coalesc_timer_cfg; - msix_cfg.resend_timer_cnt = temp_info.resend_timer_cfg; - - if (interrupt_info.lli_set) { - msix_cfg.lli_credit_cnt = interrupt_info.lli_credit_limit; - msix_cfg.lli_tmier_cnt = interrupt_info.lli_timer_cfg; - } - - if (interrupt_info.interrupt_coalesc_set) { - msix_cfg.pending_cnt = interrupt_info.pending_limt; - msix_cfg.coalesct_timer_cnt = interrupt_info.coalesc_timer_cfg; - msix_cfg.resend_timer_cnt = interrupt_info.resend_timer_cfg; - } + msix_cfg.msix_index = (u16)interrupt_info->msix_index; + msix_cfg.lli_credit_cnt = interrupt_info->lli_credit_limit; + msix_cfg.lli_tmier_cnt = interrupt_info->lli_timer_cfg; + msix_cfg.pending_cnt = interrupt_info->pending_limt; + msix_cfg.coalesct_timer_cnt = interrupt_info->coalesc_timer_cfg; + msix_cfg.resend_timer_cnt = interrupt_info->resend_timer_cfg; err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, HINIC_MGMT_CMD_MSI_CTRL_REG_WR_BY_UP, @@ -1619,11 +1601,40 @@ int hinic_set_interrupt_cfg(void *hwdev, if (err || !out_size || msix_cfg.status) { sdk_err(nic_hwdev->dev_hdl, "Failed to set interrupt config, err: %d, status: 0x%x, out size: 0x%x\n", err, msix_cfg.status, out_size); - return -EINVAL; + return -EFAULT; } return 0; } + +int hinic_set_interrupt_cfg(void *hwdev, + struct nic_interrupt_info interrupt_info) +{ + struct nic_interrupt_info temp_info; + int err; + + if (!hwdev) + return -EINVAL; + + temp_info.msix_index = interrupt_info.msix_index; + + err = hinic_get_interrupt_cfg(hwdev, &temp_info); + if (err) + return -EINVAL; + + if (!interrupt_info.lli_set) { + interrupt_info.lli_credit_limit = temp_info.lli_credit_limit; + interrupt_info.lli_timer_cfg = temp_info.lli_timer_cfg; + } + + if (!interrupt_info.interrupt_coalesc_set) { + interrupt_info.pending_limt = temp_info.pending_limt; + interrupt_info.coalesc_timer_cfg = temp_info.coalesc_timer_cfg; + interrupt_info.resend_timer_cfg = temp_info.resend_timer_cfg; + } + + return hinic_set_interrupt_cfg_direct(hwdev, &interrupt_info); +} EXPORT_SYMBOL(hinic_set_interrupt_cfg); void hinic_misx_intr_clear_resend_bit(void *hwdev, u16 msix_idx, @@ -1650,7 +1661,7 @@ static int init_aeqs_msix_attr(struct hinic_hwdev *hwdev) struct hinic_aeqs *aeqs = hwdev->aeqs; struct nic_interrupt_info info = {0}; struct hinic_eq *eq; - u16 q_id; + int q_id; int err; info.lli_set = 0; @@ -1659,10 +1670,10 @@ static int init_aeqs_msix_attr(struct hinic_hwdev *hwdev) info.coalesc_timer_cfg = HINIC_DEAULT_EQ_MSIX_COALESC_TIMER_CFG; info.resend_timer_cfg = HINIC_DEAULT_EQ_MSIX_RESEND_TIMER_CFG; - for (q_id = 0; q_id < aeqs->num_aeqs; q_id++) { + for (q_id = aeqs->num_aeqs - 1; q_id >= 0; q_id--) { eq = &aeqs->aeq[q_id]; info.msix_index = eq->eq_irq.msix_entry_idx; - err = hinic_set_interrupt_cfg(hwdev, info); + err = hinic_set_interrupt_cfg_direct(hwdev, &info); if (err) { sdk_err(hwdev->dev_hdl, "Set msix attr for aeq %d failed\n", q_id); @@ -1670,6 +1681,8 @@ static int init_aeqs_msix_attr(struct hinic_hwdev *hwdev) } } + hinic_set_mbox_seg_ack_mod(hwdev, HINIC_MBOX_SEND_MSG_INT); + return 0; } @@ -2320,24 +2333,6 @@ static int __get_func_misc_info(struct hinic_hwdev *hwdev) return 0; } -static int __init_eqs_msix_attr(struct hinic_hwdev *hwdev) -{ - int err; - - err = init_aeqs_msix_attr(hwdev); - if (err) { - sdk_err(hwdev->dev_hdl, "Failed to init aeqs msix attr\n"); - return err; - } - - err = init_ceqs_msix_attr(hwdev); - if (err) { - sdk_err(hwdev->dev_hdl, "Failed to init ceqs msix attr\n"); - return err; - } - - return 0; -} /* initialize communication channel */ int hinic_init_comm_ch(struct hinic_hwdev *hwdev) @@ -2375,6 +2370,12 @@ int hinic_init_comm_ch(struct hinic_hwdev *hwdev) goto func_to_func_init_err; } + err = init_aeqs_msix_attr(hwdev); + if (err) { + sdk_err(hwdev->dev_hdl, "Failed to init aeqs msix attr\n"); + goto aeqs_msix_attr_init_err; + } + err = __get_func_misc_info(hwdev); if (err) { sdk_err(hwdev->dev_hdl, "Failed to get function msic information\n"); @@ -2406,9 +2407,11 @@ int hinic_init_comm_ch(struct hinic_hwdev *hwdev) goto ceqs_init_err; } - err = __init_eqs_msix_attr(hwdev); - if (err) + err = init_ceqs_msix_attr(hwdev); + if (err) { + sdk_err(hwdev->dev_hdl, "Failed to init ceqs msix attr\n"); goto init_eqs_msix_err; + } /* set default wq page_size */ hwdev->wq_page_size = HINIC_DEFAULT_WQ_PAGE_SIZE; @@ -2469,6 +2472,7 @@ int hinic_init_comm_ch(struct hinic_hwdev *hwdev) l2nic_reset_err: rectify_mode_err: get_func_info_err: +aeqs_msix_attr_init_err: func_to_func_init_err: return err; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_mbox.c b/drivers/net/ethernet/huawei/hinic/hinic_mbox.c index ce6aa361aa6f16b38edd09fb2eb5f56479ea8da8..32c27a1df78f6dffaf3ed87f0b85ecee3c0a5234 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_mbox.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_mbox.c @@ -173,10 +173,6 @@ enum hinic_hwif_direction_type { HINIC_HWIF_RESPONSE = 1, }; -enum mbox_send_mod { - MBOX_SEND_MSG_INT, -}; - enum mbox_seg_type { NOT_LAST_SEG, LAST_SEG, @@ -1146,7 +1142,8 @@ static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, } err = send_mbox_seg(func_to_func, header, dst_func, msg_seg, - seg_len, MBOX_SEND_MSG_INT, msg_info); + seg_len, func_to_func->send_ack_mod, + msg_info); if (err) { sdk_err(hwdev->dev_hdl, "Failed to send mbox seg, seq_id=0x%llx\n", HINIC_MBOX_HEADER_GET(header, SEQID)); @@ -1601,6 +1598,15 @@ int hinic_vf_mbox_random_id_init(struct hinic_hwdev *hwdev) return err; } +void hinic_set_mbox_seg_ack_mod(struct hinic_hwdev *hwdev, + enum hinic_mbox_send_mod mod) +{ + if (!hwdev || !hwdev->func_to_func) + return; + + hwdev->func_to_func->send_ack_mod = mod; +} + int hinic_func_to_func_init(struct hinic_hwdev *hwdev) { struct hinic_mbox_func_to_func *func_to_func; @@ -1646,6 +1652,8 @@ int hinic_func_to_func_init(struct hinic_hwdev *hwdev) prepare_send_mbox(func_to_func); + func_to_func->send_ack_mod = HINIC_MBOX_SEND_MSG_POLL; + return 0; alloc_wb_status_err: diff --git a/drivers/net/ethernet/huawei/hinic/hinic_mbox.h b/drivers/net/ethernet/huawei/hinic/hinic_mbox.h index cfb118a7d9d796e5e4d5657a0dcd43d3e83f0fd1..b76b960af6511acc7e50f2436dc40e306cbeded4 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_mbox.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_mbox.h @@ -101,6 +101,11 @@ enum hinic_mbox_cb_state { HINIC_PPF_TO_PF_MBOX_CB_RUNNIG, }; +enum hinic_mbox_send_mod { + HINIC_MBOX_SEND_MSG_INT, + HINIC_MBOX_SEND_MSG_POLL, +}; + struct hinic_mbox_func_to_func { struct hinic_hwdev *hwdev; @@ -130,6 +135,7 @@ struct hinic_mbox_func_to_func { u32 *vf_mbx_old_rand_id; u32 *vf_mbx_rand_id; bool support_vf_random; + enum hinic_mbox_send_mod send_ack_mod; }; struct hinic_mbox_work { @@ -229,4 +235,7 @@ int __hinic_mbox_to_vf(void *hwdev, int vf_to_pf_handler(void *handle, u16 vf_id, u8 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size); +void hinic_set_mbox_seg_ack_mod(struct hinic_hwdev *hwdev, + enum hinic_mbox_send_mod mod); + #endif