提交 97c844e0 编写于 作者: C Chiqijun 提交者: Yang Yingliang

net/hinic: Adjust AEQ interrupt retransmission settings

driver inclusion
category: bugfix
bugzilla: 4472

-----------------------------------------------------------------------

The communication between the VF driver and the firmware depends on the AEQ
channel. During the hot migration process, interruption may be lost. If the
interrupt retransmission is not configured, polling is used, and the AEQ
interrupt retransmission is preferentially configured.
Signed-off-by: NChiqijun <chiqijun@huawei.com>
Reviewed-by: NLuoshaokai <luoshaokai@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 0a44be25
...@@ -199,7 +199,8 @@ struct nic_interrupt_info { ...@@ -199,7 +199,8 @@ struct nic_interrupt_info {
int hinic_get_interrupt_cfg(void *hwdev, int hinic_get_interrupt_cfg(void *hwdev,
struct nic_interrupt_info *interrupt_info); 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, int hinic_set_interrupt_cfg(void *hwdev,
struct nic_interrupt_info interrupt_info); struct nic_interrupt_info interrupt_info);
......
...@@ -1572,45 +1572,27 @@ int hinic_get_interrupt_cfg(void *hwdev, ...@@ -1572,45 +1572,27 @@ int hinic_get_interrupt_cfg(void *hwdev,
} }
EXPORT_SYMBOL(hinic_get_interrupt_cfg); EXPORT_SYMBOL(hinic_get_interrupt_cfg);
int hinic_set_interrupt_cfg(void *hwdev, int hinic_set_interrupt_cfg_direct(void *hwdev,
struct nic_interrupt_info interrupt_info) struct nic_interrupt_info *interrupt_info)
{ {
struct hinic_hwdev *nic_hwdev = hwdev; struct hinic_hwdev *nic_hwdev = hwdev;
struct hinic_msix_config msix_cfg = {0}; struct hinic_msix_config msix_cfg = {0};
struct nic_interrupt_info temp_info;
u16 out_size = sizeof(msix_cfg); u16 out_size = sizeof(msix_cfg);
int err; int err;
if (!hwdev) if (!hwdev)
return -EINVAL; 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); err = hinic_global_func_id_get(hwdev, &msix_cfg.func_id);
if (err) if (err)
return err; return err;
msix_cfg.msix_index = (u16)interrupt_info.msix_index; msix_cfg.msix_index = (u16)interrupt_info->msix_index;
msix_cfg.lli_credit_cnt = temp_info.lli_credit_limit; msix_cfg.lli_credit_cnt = interrupt_info->lli_credit_limit;
msix_cfg.lli_tmier_cnt = temp_info.lli_timer_cfg; msix_cfg.lli_tmier_cnt = interrupt_info->lli_timer_cfg;
msix_cfg.pending_cnt = temp_info.pending_limt; msix_cfg.pending_cnt = interrupt_info->pending_limt;
msix_cfg.coalesct_timer_cnt = temp_info.coalesc_timer_cfg; msix_cfg.coalesct_timer_cnt = interrupt_info->coalesc_timer_cfg;
msix_cfg.resend_timer_cnt = temp_info.resend_timer_cfg; msix_cfg.resend_timer_cnt = interrupt_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;
}
err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM, err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
HINIC_MGMT_CMD_MSI_CTRL_REG_WR_BY_UP, HINIC_MGMT_CMD_MSI_CTRL_REG_WR_BY_UP,
...@@ -1619,11 +1601,40 @@ int hinic_set_interrupt_cfg(void *hwdev, ...@@ -1619,11 +1601,40 @@ int hinic_set_interrupt_cfg(void *hwdev,
if (err || !out_size || msix_cfg.status) { 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", 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); err, msix_cfg.status, out_size);
return -EINVAL; return -EFAULT;
} }
return 0; 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); EXPORT_SYMBOL(hinic_set_interrupt_cfg);
void hinic_misx_intr_clear_resend_bit(void *hwdev, u16 msix_idx, 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) ...@@ -1650,7 +1661,7 @@ static int init_aeqs_msix_attr(struct hinic_hwdev *hwdev)
struct hinic_aeqs *aeqs = hwdev->aeqs; struct hinic_aeqs *aeqs = hwdev->aeqs;
struct nic_interrupt_info info = {0}; struct nic_interrupt_info info = {0};
struct hinic_eq *eq; struct hinic_eq *eq;
u16 q_id; int q_id;
int err; int err;
info.lli_set = 0; info.lli_set = 0;
...@@ -1659,10 +1670,10 @@ static int init_aeqs_msix_attr(struct hinic_hwdev *hwdev) ...@@ -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.coalesc_timer_cfg = HINIC_DEAULT_EQ_MSIX_COALESC_TIMER_CFG;
info.resend_timer_cfg = HINIC_DEAULT_EQ_MSIX_RESEND_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]; eq = &aeqs->aeq[q_id];
info.msix_index = eq->eq_irq.msix_entry_idx; 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) { if (err) {
sdk_err(hwdev->dev_hdl, "Set msix attr for aeq %d failed\n", sdk_err(hwdev->dev_hdl, "Set msix attr for aeq %d failed\n",
q_id); q_id);
...@@ -1670,6 +1681,8 @@ static int init_aeqs_msix_attr(struct hinic_hwdev *hwdev) ...@@ -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; return 0;
} }
...@@ -2320,24 +2333,6 @@ static int __get_func_misc_info(struct hinic_hwdev *hwdev) ...@@ -2320,24 +2333,6 @@ static int __get_func_misc_info(struct hinic_hwdev *hwdev)
return 0; 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 */ /* initialize communication channel */
int hinic_init_comm_ch(struct hinic_hwdev *hwdev) int hinic_init_comm_ch(struct hinic_hwdev *hwdev)
...@@ -2375,6 +2370,12 @@ 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; 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); err = __get_func_misc_info(hwdev);
if (err) { if (err) {
sdk_err(hwdev->dev_hdl, "Failed to get function msic information\n"); 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) ...@@ -2406,9 +2407,11 @@ int hinic_init_comm_ch(struct hinic_hwdev *hwdev)
goto ceqs_init_err; goto ceqs_init_err;
} }
err = __init_eqs_msix_attr(hwdev); err = init_ceqs_msix_attr(hwdev);
if (err) if (err) {
sdk_err(hwdev->dev_hdl, "Failed to init ceqs msix attr\n");
goto init_eqs_msix_err; goto init_eqs_msix_err;
}
/* set default wq page_size */ /* set default wq page_size */
hwdev->wq_page_size = HINIC_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) ...@@ -2469,6 +2472,7 @@ int hinic_init_comm_ch(struct hinic_hwdev *hwdev)
l2nic_reset_err: l2nic_reset_err:
rectify_mode_err: rectify_mode_err:
get_func_info_err: get_func_info_err:
aeqs_msix_attr_init_err:
func_to_func_init_err: func_to_func_init_err:
return err; return err;
......
...@@ -173,10 +173,6 @@ enum hinic_hwif_direction_type { ...@@ -173,10 +173,6 @@ enum hinic_hwif_direction_type {
HINIC_HWIF_RESPONSE = 1, HINIC_HWIF_RESPONSE = 1,
}; };
enum mbox_send_mod {
MBOX_SEND_MSG_INT,
};
enum mbox_seg_type { enum mbox_seg_type {
NOT_LAST_SEG, NOT_LAST_SEG,
LAST_SEG, LAST_SEG,
...@@ -1146,7 +1142,8 @@ static int send_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func, ...@@ -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, 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) { if (err) {
sdk_err(hwdev->dev_hdl, "Failed to send mbox seg, seq_id=0x%llx\n", sdk_err(hwdev->dev_hdl, "Failed to send mbox seg, seq_id=0x%llx\n",
HINIC_MBOX_HEADER_GET(header, SEQID)); HINIC_MBOX_HEADER_GET(header, SEQID));
...@@ -1601,6 +1598,15 @@ int hinic_vf_mbox_random_id_init(struct hinic_hwdev *hwdev) ...@@ -1601,6 +1598,15 @@ int hinic_vf_mbox_random_id_init(struct hinic_hwdev *hwdev)
return err; 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) int hinic_func_to_func_init(struct hinic_hwdev *hwdev)
{ {
struct hinic_mbox_func_to_func *func_to_func; struct hinic_mbox_func_to_func *func_to_func;
...@@ -1646,6 +1652,8 @@ int hinic_func_to_func_init(struct hinic_hwdev *hwdev) ...@@ -1646,6 +1652,8 @@ int hinic_func_to_func_init(struct hinic_hwdev *hwdev)
prepare_send_mbox(func_to_func); prepare_send_mbox(func_to_func);
func_to_func->send_ack_mod = HINIC_MBOX_SEND_MSG_POLL;
return 0; return 0;
alloc_wb_status_err: alloc_wb_status_err:
......
...@@ -101,6 +101,11 @@ enum hinic_mbox_cb_state { ...@@ -101,6 +101,11 @@ enum hinic_mbox_cb_state {
HINIC_PPF_TO_PF_MBOX_CB_RUNNIG, 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_mbox_func_to_func {
struct hinic_hwdev *hwdev; struct hinic_hwdev *hwdev;
...@@ -130,6 +135,7 @@ struct hinic_mbox_func_to_func { ...@@ -130,6 +135,7 @@ struct hinic_mbox_func_to_func {
u32 *vf_mbx_old_rand_id; u32 *vf_mbx_old_rand_id;
u32 *vf_mbx_rand_id; u32 *vf_mbx_rand_id;
bool support_vf_random; bool support_vf_random;
enum hinic_mbox_send_mod send_ack_mod;
}; };
struct hinic_mbox_work { struct hinic_mbox_work {
...@@ -229,4 +235,7 @@ int __hinic_mbox_to_vf(void *hwdev, ...@@ -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, int vf_to_pf_handler(void *handle, u16 vf_id, u8 cmd, void *buf_in,
u16 in_size, void *buf_out, u16 *out_size); 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 #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册