]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bnx2: Try to recover from PCI block reset
authorMichael Chan <mchan@broadcom.com>
Mon, 16 Jul 2012 14:25:56 +0000 (14:25 +0000)
committerJoe Jin <joe.jin@oracle.com>
Tue, 28 Aug 2012 07:23:14 +0000 (15:23 +0800)
If the PCI block has reset, the memory enable bit will be reset and
the device will not respond to MMIO access.  bnx2_reset_task() currently
will not recover when this happens.  Add code to detect this condition
and restore the PCI state.  This scenario has been reported by some
users.

(cherry picked from commit efdfad3205403e1d1c5c0bdcbdb647ddd89bfaa3)
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/net/bnx2.c

index 4cf9ae0ce47890ced64bd25ecb48ee06b0eef9ca..b0c9ddfba092ff33f7d607e96b5f3a67c85836bc 100644 (file)
@@ -6387,6 +6387,7 @@ bnx2_reset_task(struct work_struct *work)
 {
        struct bnx2 *bp = container_of(work, struct bnx2, reset_task);
        int rc;
+       u16 pcicmd;
 
        rtnl_lock();
        if (!netif_running(bp->dev)) {
@@ -6396,6 +6397,12 @@ bnx2_reset_task(struct work_struct *work)
 
        bnx2_netif_stop(bp, true);
 
+       pci_read_config_word(bp->pdev, PCI_COMMAND, &pcicmd);
+       if (!(pcicmd & PCI_COMMAND_MEMORY)) {
+               /* in case PCI block has reset */
+               pci_restore_state(bp->pdev);
+               pci_save_state(bp->pdev);
+       }
        rc = bnx2_init_nic(bp, 1);
        if (rc) {
                netdev_err(bp->dev, "failed to reset NIC, closing\n");