The new flag will be set in subsequent patches when firmware is going through reset. Delay close and SRIOV disable operations until the flag is cleared.
Store the registered_vfs value from the firmware. This value will be polled in subsequent patches to determine if SR-IOV is in quiescent state. Signed-off-by: Michael Chan <michael.c...@broadcom.com> --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 16 ++++++++++++++++ drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 ++ drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index f522f3b..be0eb1c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -6326,6 +6326,8 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp) struct bnxt_vf_info *vf = &bp->vf; vf->vlan = le16_to_cpu(resp->vlan) & VLAN_VID_MASK; + } else { + bp->pf.registered_vfs = le16_to_cpu(resp->registered_vfs); } #endif flags = le16_to_cpu(resp->flags); @@ -8710,6 +8712,10 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up) if (flags & FUNC_DRV_IF_CHANGE_RESP_FLAGS_HOT_FW_RESET_DONE) fw_reset = true; + if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) && !fw_reset) { + netdev_err(bp->dev, "RESET_DONE not set during FW reset.\n"); + return -ENODEV; + } if (resc_reinit || fw_reset) { if (fw_reset) { rc = bnxt_fw_init_one(bp); @@ -9218,6 +9224,9 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bnxt_debug_dev_exit(bp); bnxt_disable_napi(bp); del_timer_sync(&bp->timer); + if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) + pci_disable_device(bp->pdev); + bnxt_free_skbs(bp); /* Save ring stats before shutdown */ @@ -9234,6 +9243,13 @@ int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) { int rc = 0; + while (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { + netdev_info(bp->dev, "FW reset in progress, delaying close"); + rtnl_unlock(); + msleep(250); + rtnl_lock(); + } + #ifdef CONFIG_BNXT_SRIOV if (bp->sriov_cfg) { rc = wait_event_interruptible_timeout(bp->sriov_cfg_wait, diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 96f2e12..c316de5 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1066,6 +1066,7 @@ struct bnxt_pf_info { u8 mac_addr[ETH_ALEN]; u32 first_vf_id; u16 active_vfs; + u16 registered_vfs; u16 max_vfs; u32 max_encap_records; u32 max_decap_records; @@ -1605,6 +1606,7 @@ struct bnxt { #define BNXT_STATE_IN_SP_TASK 1 #define BNXT_STATE_READ_STATS 2 #define BNXT_STATE_FW_RESET_DET 3 +#define BNXT_STATE_IN_FW_RESET 4 #define BNXT_STATE_PROBE_ERR 5 struct bnxt_irq *irq_tbl; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 93524d7..e435374 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -802,6 +802,10 @@ void bnxt_sriov_disable(struct bnxt *bp) { u16 num_vfs = pci_num_vf(bp->pdev); + while (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { + netdev_info(bp->dev, "FW reset in progress, delaying SR-IOV config"); + msleep(250); + } if (!num_vfs) return; -- 2.5.1