BNX2X_SP_RTNL_AFEX_F_UPDATE,
        BNX2X_SP_RTNL_ENABLE_SRIOV,
        BNX2X_SP_RTNL_VFPF_MCAST,
+       BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
        BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
        BNX2X_SP_RTNL_HYPERVISOR_VLAN,
 };
 #define USING_SINGLE_MSIX_FLAG         (1 << 20)
 #define BC_SUPPORTS_DCBX_MSG_NON_PMF   (1 << 21)
 #define IS_VF_FLAG                     (1 << 22)
+#define INTERRUPTS_ENABLED_FLAG                (1 << 23)
 
 #define BP_NOMCP(bp)                   ((bp)->flags & NO_MCP_FLAG)
 
 
        bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
        smp_mb();
 
+       /* indicate to VFs that the PF is going down */
+       bnx2x_iov_channel_down(bp);
+
        if (CNIC_LOADED(bp))
                bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD);
 
 
                bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
 
        /* sample pf vf bulletin board for new posts from pf */
-       if (IS_VF(bp))
+       if (IS_VF(bp)) {
                bnx2x_sample_bulletin(bp);
 
+               /* if channel is down we need to self destruct */
+               if (bp->old_bulletin.valid_bitmap & 1 << CHANNEL_DOWN) {
+                       smp_mb__before_clear_bit();
+                       set_bit(BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
+                               &bp->sp_rtnl_state);
+                       smp_mb__after_clear_bit();
+                       schedule_delayed_work(&bp->sp_rtnl_task, 0);
+               }
+       }
+
        mod_timer(&bp->timer, jiffies + bp->current_interval);
 }
 
                   "sending set mcast vf pf channel message from rtnl sp-task\n");
                bnx2x_vfpf_set_mcast(bp->dev);
        }
+       if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
+                              &bp->sp_rtnl_state)){
+               if (!test_bit(__LINK_STATE_NOCARRIER, &bp->dev->state)) {
+                       bnx2x_tx_disable(bp);
+                       BNX2X_ERR("PF indicated channel is not servicable anymore. This means this VF device is no longer operational\n");
+               }
+       }
 
        if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
                               &bp->sp_rtnl_state)) {
                rtnl_unlock();
        }
 
+       bnx2x_iov_remove_one(bp);
+
        /* Power on: we can't let PCI layer write to us while we are in D3 */
        if (IS_PF(bp))
                bnx2x_set_power_state(bp, PCI_D0);
        /* Make sure RESET task is not scheduled before continuing */
        cancel_delayed_work_sync(&bp->sp_rtnl_task);
 
-       bnx2x_iov_remove_one(bp);
-
        /* send message via vfpf channel to release the resources of this vf */
        if (IS_VF(bp))
                bnx2x_vfpf_release(bp);
 
        struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
 
        if (!vf)
-               goto unknown_dev;
+               return false;
 
        dev = pci_get_bus_and_slot(vf->bus, vf->devfn);
        if (dev)
                return bnx2x_is_pcie_pending(dev);
-
-unknown_dev:
        return false;
 }
 
 
        return 0;
 }
+
+void bnx2x_iov_channel_down(struct bnx2x *bp)
+{
+       int vf_idx;
+       struct pf_vf_bulletin_content *bulletin;
+
+       if (!IS_SRIOV(bp))
+               return;
+
+       for_each_vf(bp, vf_idx) {
+               /* locate this VFs bulletin board and update the channel down
+                * bit
+                */
+               bulletin = BP_VF_BULLETIN(bp, vf_idx);
+               bulletin->valid_bitmap |= 1 << CHANNEL_DOWN;
+
+               /* update vf bulletin board */
+               bnx2x_post_vf_bulletin(bp, vf_idx);
+       }
+}
 
 }
 void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp);
 int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs);
+void bnx2x_iov_channel_down(struct bnx2x *bp);
 int bnx2x_open_epilog(struct bnx2x *bp);
 
 #else /* CONFIG_BNX2X_SRIOV */
 static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; }
 static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {}
 static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; }
+static inline void bnx2x_iov_channel_down(struct bnx2x *bp) {}
 static inline int bnx2x_open_epilog(struct bnx2x *bp) {return 0; }
 
 #endif /* CONFIG_BNX2X_SRIOV */
 
 {
        struct cstorm_vf_zone_data __iomem *zone_data =
                REG_ADDR(bp, PXP_VF_ADDR_CSDM_GLOBAL_START);
-       int tout = 600, interval = 100; /* wait for 60 seconds */
+       int tout = 100, interval = 100; /* wait for 10 seconds */
 
        if (*done) {
                BNX2X_ERR("done was non zero before message to pf was sent\n");
                return -EINVAL;
        }
 
+       /* if PF indicated channel is down avoid sending message. Return success
+        * so calling flow can continue
+        */
+       bnx2x_sample_bulletin(bp);
+       if (bp->old_bulletin.valid_bitmap & 1 << CHANNEL_DOWN) {
+               DP(BNX2X_MSG_IOV, "detecting channel down. Aborting message\n");
+               *done = PFVF_STATUS_SUCCESS;
+               return 0;
+       }
+
        /* Write message address */
        writel(U64_LO(msg_mapping),
               &zone_data->non_trigger.vf_pf_channel.msg_addr_lo);
 
 #define VLAN_VALID             1       /* when set, the vf should not access
                                         * the vfpf channel
                                         */
-
+#define CHANNEL_DOWN           2       /* vfpf channel is disabled. VFs are not
+                                        * to attempt to send messages on the
+                                        * channel after this bit is set
+                                        */
        u8 mac[ETH_ALEN];
        u8 mac_padding[2];