aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWendy Xiong <wendyx@us.ibm.com>2008-05-17 01:18:21 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-17 01:18:21 -0400
commit6ff2da49c8a68320c2564006c94a492db58de5cd (patch)
tree547db2972c71690e9ee48120b26f458e7417a3f1 /drivers
parent9a120bc570627342c17befaa6af9b0a556dfda48 (diff)
bnx2: Add EEH PCI recovery.
Add PCI recovery functions to the driver. The initial pci state is also saved so the the MSI state can be restored during PCI recovery. Signed-off-by: Wendy Xiong <wendyx@us.ibm.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bnx2.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 934c2bfc464d..2589b99a8597 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -7119,6 +7119,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
7119 } 7119 }
7120 7120
7121 pci_set_master(pdev); 7121 pci_set_master(pdev);
7122 pci_save_state(pdev);
7122 7123
7123 bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); 7124 bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
7124 if (bp->pm_cap == 0) { 7125 if (bp->pm_cap == 0) {
@@ -7628,6 +7629,92 @@ bnx2_resume(struct pci_dev *pdev)
7628 return 0; 7629 return 0;
7629} 7630}
7630 7631
7632/**
7633 * bnx2_io_error_detected - called when PCI error is detected
7634 * @pdev: Pointer to PCI device
7635 * @state: The current pci connection state
7636 *
7637 * This function is called after a PCI bus error affecting
7638 * this device has been detected.
7639 */
7640static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
7641 pci_channel_state_t state)
7642{
7643 struct net_device *dev = pci_get_drvdata(pdev);
7644 struct bnx2 *bp = netdev_priv(dev);
7645
7646 rtnl_lock();
7647 netif_device_detach(dev);
7648
7649 if (netif_running(dev)) {
7650 bnx2_netif_stop(bp);
7651 del_timer_sync(&bp->timer);
7652 bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
7653 }
7654
7655 pci_disable_device(pdev);
7656 rtnl_unlock();
7657
7658 /* Request a slot slot reset. */
7659 return PCI_ERS_RESULT_NEED_RESET;
7660}
7661
7662/**
7663 * bnx2_io_slot_reset - called after the pci bus has been reset.
7664 * @pdev: Pointer to PCI device
7665 *
7666 * Restart the card from scratch, as if from a cold-boot.
7667 */
7668static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev)
7669{
7670 struct net_device *dev = pci_get_drvdata(pdev);
7671 struct bnx2 *bp = netdev_priv(dev);
7672
7673 rtnl_lock();
7674 if (pci_enable_device(pdev)) {
7675 dev_err(&pdev->dev,
7676 "Cannot re-enable PCI device after reset.\n");
7677 rtnl_unlock();
7678 return PCI_ERS_RESULT_DISCONNECT;
7679 }
7680 pci_set_master(pdev);
7681 pci_restore_state(pdev);
7682
7683 if (netif_running(dev)) {
7684 bnx2_set_power_state(bp, PCI_D0);
7685 bnx2_init_nic(bp, 1);
7686 }
7687
7688 rtnl_unlock();
7689 return PCI_ERS_RESULT_RECOVERED;
7690}
7691
7692/**
7693 * bnx2_io_resume - called when traffic can start flowing again.
7694 * @pdev: Pointer to PCI device
7695 *
7696 * This callback is called when the error recovery driver tells us that
7697 * its OK to resume normal operation.
7698 */
7699static void bnx2_io_resume(struct pci_dev *pdev)
7700{
7701 struct net_device *dev = pci_get_drvdata(pdev);
7702 struct bnx2 *bp = netdev_priv(dev);
7703
7704 rtnl_lock();
7705 if (netif_running(dev))
7706 bnx2_netif_start(bp);
7707
7708 netif_device_attach(dev);
7709 rtnl_unlock();
7710}
7711
7712static struct pci_error_handlers bnx2_err_handler = {
7713 .error_detected = bnx2_io_error_detected,
7714 .slot_reset = bnx2_io_slot_reset,
7715 .resume = bnx2_io_resume,
7716};
7717
7631static struct pci_driver bnx2_pci_driver = { 7718static struct pci_driver bnx2_pci_driver = {
7632 .name = DRV_MODULE_NAME, 7719 .name = DRV_MODULE_NAME,
7633 .id_table = bnx2_pci_tbl, 7720 .id_table = bnx2_pci_tbl,
@@ -7635,6 +7722,7 @@ static struct pci_driver bnx2_pci_driver = {
7635 .remove = __devexit_p(bnx2_remove_one), 7722 .remove = __devexit_p(bnx2_remove_one),
7636 .suspend = bnx2_suspend, 7723 .suspend = bnx2_suspend,
7637 .resume = bnx2_resume, 7724 .resume = bnx2_resume,
7725 .err_handler = &bnx2_err_handler,
7638}; 7726};
7639 7727
7640static int __init bnx2_init(void) 7728static int __init bnx2_init(void)