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

Reply via email to