From: Fan Gong Date: Tue, 10 Mar 2026 01:04:55 +0000 (+0800) Subject: hinic3: Add PF FLR wait and timeout handling X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=33cf53672b6f386585998366c40369834f882ddb;p=thirdparty%2Flinux.git hinic3: Add PF FLR wait and timeout handling Add a mechanism for PF to wait for the completion of FLR, ensuring hardware state consistency after an FLR event. Co-developed-by: Zhu Yikai Signed-off-by: Zhu Yikai Signed-off-by: Fan Gong Link: https://patch.msgid.link/7a1b21426fd4274831733aca962eb209b806f4bd.1773062356.git.zhuyikai1@h-partners.com Signed-off-by: Paolo Abeni --- diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c index 1defd68007909..a6e4e99683343 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c @@ -292,6 +292,32 @@ int hinic3_set_cmdq_depth(struct hinic3_hwdev *hwdev, u16 cmdq_depth) return 0; } +#define HINIC3_FLR_TIMEOUT 1000 + +static enum hinic3_wait_return hinic3_check_flr_finish_handler(void *priv_data) +{ + struct hinic3_hwdev *hwdev = priv_data; + struct hinic3_hwif *hwif = hwdev->hwif; + enum hinic3_pf_status status; + + if (!hwdev->chip_present_flag) + return HINIC3_WAIT_PROCESS_ERR; + + status = hinic3_get_pf_status(hwif); + if (status == HINIC3_PF_STATUS_FLR_FINISH_FLAG) { + hinic3_set_pf_status(hwif, HINIC3_PF_STATUS_ACTIVE_FLAG); + return HINIC3_WAIT_PROCESS_CPL; + } + + return HINIC3_WAIT_PROCESS_WAITING; +} + +static int hinic3_wait_for_flr_finish(struct hinic3_hwdev *hwdev) +{ + return hinic3_wait_for_timeout(hwdev, hinic3_check_flr_finish_handler, + HINIC3_FLR_TIMEOUT, 0xa * USEC_PER_MSEC); +} + #define HINIC3_WAIT_CMDQ_IDLE_TIMEOUT 5000 static enum hinic3_wait_return check_cmdq_stop_handler(void *priv_data) @@ -389,6 +415,14 @@ int hinic3_func_rx_tx_flush(struct hinic3_hwdev *hwdev) ret = err; } + if (HINIC3_FUNC_TYPE(hwdev) != HINIC3_FUNC_TYPE_VF) { + err = hinic3_wait_for_flr_finish(hwdev); + if (err) { + dev_warn(hwdev->dev, "Wait firmware FLR timeout\n"); + ret = err; + } + } + hinic3_toggle_doorbell(hwif, ENABLE_DOORBELL); err = hinic3_reinit_cmdq_ctxts(hwdev);