{
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct bnxt *bp = netdev_priv(netdev);
+       bool abort = false;
 
        netdev_info(netdev, "PCI I/O error detected\n");
 
 
        bnxt_ulp_stop(bp);
 
-       if (state == pci_channel_io_perm_failure) {
+       if (test_and_set_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
+               netdev_err(bp->dev, "Firmware reset already in progress\n");
+               abort = true;
+       }
+
+       if (abort || state == pci_channel_io_perm_failure) {
                rtnl_unlock();
                return PCI_ERS_RESULT_DISCONNECT;
        }
 
-       if (state == pci_channel_io_frozen)
+       /* Link is not reliable anymore if state is pci_channel_io_frozen
+        * so we disable bus master to prevent any potential bad DMAs before
+        * freeing kernel memory.
+        */
+       if (state == pci_channel_io_frozen) {
                set_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN, &bp->state);
+               bnxt_fw_fatal_close(bp);
+       }
 
        if (netif_running(netdev))
-               bnxt_close(netdev);
+               __bnxt_close_nic(bp, true, true);
 
        if (pci_is_enabled(pdev))
                pci_disable_device(pdev);
        }
 
 reset_exit:
+       clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
        bnxt_clear_reservations(bp, true);
        rtnl_unlock();