diff options
author | Wendy Xiong <wendyx@us.ibm.com> | 2008-06-23 23:36:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-23 23:36:22 -0400 |
commit | 493adb1fee89eaad4f6cb1018ef4c48fccd79ab5 (patch) | |
tree | 5000f49d823fe8e9df751a543144e8d094494f02 /drivers | |
parent | f3c87cddfe3fa667f31a9c03a2eec0f3ae1b4bb3 (diff) |
bnx2x: Add PCIE EEH support
Add PCI recovery functions to the driver. The initial PCI state is
also saved so the MSI state can be restored during PCI recovery.
Signed-off-by: Wendy Xiong <wendyx@us.ibm.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bnx2x_main.c | 101 |
1 files changed, 95 insertions, 6 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index e9037131a04e..d21dc89d1e77 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -10181,13 +10181,102 @@ static int bnx2x_resume(struct pci_dev *pdev) | |||
10181 | return rc; | 10181 | return rc; |
10182 | } | 10182 | } |
10183 | 10183 | ||
10184 | /** | ||
10185 | * bnx2x_io_error_detected - called when PCI error is detected | ||
10186 | * @pdev: Pointer to PCI device | ||
10187 | * @state: The current pci connection state | ||
10188 | * | ||
10189 | * This function is called after a PCI bus error affecting | ||
10190 | * this device has been detected. | ||
10191 | */ | ||
10192 | static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev, | ||
10193 | pci_channel_state_t state) | ||
10194 | { | ||
10195 | struct net_device *dev = pci_get_drvdata(pdev); | ||
10196 | struct bnx2x *bp = netdev_priv(dev); | ||
10197 | |||
10198 | rtnl_lock(); | ||
10199 | |||
10200 | netif_device_detach(dev); | ||
10201 | |||
10202 | if (netif_running(dev)) | ||
10203 | bnx2x_nic_unload(bp, UNLOAD_CLOSE); | ||
10204 | |||
10205 | pci_disable_device(pdev); | ||
10206 | |||
10207 | rtnl_unlock(); | ||
10208 | |||
10209 | /* Request a slot reset */ | ||
10210 | return PCI_ERS_RESULT_NEED_RESET; | ||
10211 | } | ||
10212 | |||
10213 | /** | ||
10214 | * bnx2x_io_slot_reset - called after the PCI bus has been reset | ||
10215 | * @pdev: Pointer to PCI device | ||
10216 | * | ||
10217 | * Restart the card from scratch, as if from a cold-boot. | ||
10218 | */ | ||
10219 | static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev) | ||
10220 | { | ||
10221 | struct net_device *dev = pci_get_drvdata(pdev); | ||
10222 | struct bnx2x *bp = netdev_priv(dev); | ||
10223 | |||
10224 | rtnl_lock(); | ||
10225 | |||
10226 | if (pci_enable_device(pdev)) { | ||
10227 | dev_err(&pdev->dev, | ||
10228 | "Cannot re-enable PCI device after reset\n"); | ||
10229 | rtnl_unlock(); | ||
10230 | return PCI_ERS_RESULT_DISCONNECT; | ||
10231 | } | ||
10232 | |||
10233 | pci_set_master(pdev); | ||
10234 | pci_restore_state(pdev); | ||
10235 | |||
10236 | if (netif_running(dev)) | ||
10237 | bnx2x_set_power_state(bp, PCI_D0); | ||
10238 | |||
10239 | rtnl_unlock(); | ||
10240 | |||
10241 | return PCI_ERS_RESULT_RECOVERED; | ||
10242 | } | ||
10243 | |||
10244 | /** | ||
10245 | * bnx2x_io_resume - called when traffic can start flowing again | ||
10246 | * @pdev: Pointer to PCI device | ||
10247 | * | ||
10248 | * This callback is called when the error recovery driver tells us that | ||
10249 | * its OK to resume normal operation. | ||
10250 | */ | ||
10251 | static void bnx2x_io_resume(struct pci_dev *pdev) | ||
10252 | { | ||
10253 | struct net_device *dev = pci_get_drvdata(pdev); | ||
10254 | struct bnx2x *bp = netdev_priv(dev); | ||
10255 | |||
10256 | rtnl_lock(); | ||
10257 | |||
10258 | if (netif_running(dev)) | ||
10259 | bnx2x_nic_load(bp, LOAD_OPEN); | ||
10260 | |||
10261 | netif_device_attach(dev); | ||
10262 | |||
10263 | rtnl_unlock(); | ||
10264 | } | ||
10265 | |||
10266 | static struct pci_error_handlers bnx2x_err_handler = { | ||
10267 | .error_detected = bnx2x_io_error_detected, | ||
10268 | .slot_reset = bnx2x_io_slot_reset, | ||
10269 | .resume = bnx2x_io_resume, | ||
10270 | }; | ||
10271 | |||
10184 | static struct pci_driver bnx2x_pci_driver = { | 10272 | static struct pci_driver bnx2x_pci_driver = { |
10185 | .name = DRV_MODULE_NAME, | 10273 | .name = DRV_MODULE_NAME, |
10186 | .id_table = bnx2x_pci_tbl, | 10274 | .id_table = bnx2x_pci_tbl, |
10187 | .probe = bnx2x_init_one, | 10275 | .probe = bnx2x_init_one, |
10188 | .remove = __devexit_p(bnx2x_remove_one), | 10276 | .remove = __devexit_p(bnx2x_remove_one), |
10189 | .suspend = bnx2x_suspend, | 10277 | .suspend = bnx2x_suspend, |
10190 | .resume = bnx2x_resume, | 10278 | .resume = bnx2x_resume, |
10279 | .err_handler = &bnx2x_err_handler, | ||
10191 | }; | 10280 | }; |
10192 | 10281 | ||
10193 | static int __init bnx2x_init(void) | 10282 | static int __init bnx2x_init(void) |