aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 9d14652ffdc3..1b9a711beb85 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -2316,6 +2316,112 @@ void t3_fatal_err(struct adapter *adapter)
2316 2316
2317} 2317}
2318 2318
2319/**
2320 * t3_io_error_detected - called when PCI error is detected
2321 * @pdev: Pointer to PCI device
2322 * @state: The current pci connection state
2323 *
2324 * This function is called after a PCI bus error affecting
2325 * this device has been detected.
2326 */
2327static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
2328 pci_channel_state_t state)
2329{
2330 struct net_device *dev = pci_get_drvdata(pdev);
2331 struct port_info *pi = netdev_priv(dev);
2332 struct adapter *adapter = pi->adapter;
2333 int i;
2334
2335 /* Stop all ports */
2336 for_each_port(adapter, i) {
2337 struct net_device *netdev = adapter->port[i];
2338
2339 if (netif_running(netdev))
2340 cxgb_close(netdev);
2341 }
2342
2343 if (is_offload(adapter) &&
2344 test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
2345 offload_close(&adapter->tdev);
2346
2347 /* Free sge resources */
2348 t3_free_sge_resources(adapter);
2349
2350 adapter->flags &= ~FULL_INIT_DONE;
2351
2352 pci_disable_device(pdev);
2353
2354 /* Request a slot slot reset. */
2355 return PCI_ERS_RESULT_NEED_RESET;
2356}
2357
2358/**
2359 * t3_io_slot_reset - called after the pci bus has been reset.
2360 * @pdev: Pointer to PCI device
2361 *
2362 * Restart the card from scratch, as if from a cold-boot.
2363 */
2364static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev)
2365{
2366 struct net_device *dev = pci_get_drvdata(pdev);
2367 struct port_info *pi = netdev_priv(dev);
2368 struct adapter *adapter = pi->adapter;
2369
2370 if (pci_enable_device(pdev)) {
2371 dev_err(&pdev->dev,
2372 "Cannot re-enable PCI device after reset.\n");
2373 return PCI_ERS_RESULT_DISCONNECT;
2374 }
2375 pci_set_master(pdev);
2376
2377 t3_prep_adapter(adapter, adapter->params.info, 1);
2378
2379 return PCI_ERS_RESULT_RECOVERED;
2380}
2381
2382/**
2383 * t3_io_resume - called when traffic can start flowing again.
2384 * @pdev: Pointer to PCI device
2385 *
2386 * This callback is called when the error recovery driver tells us that
2387 * its OK to resume normal operation.
2388 */
2389static void t3_io_resume(struct pci_dev *pdev)
2390{
2391 struct net_device *dev = pci_get_drvdata(pdev);
2392 struct port_info *pi = netdev_priv(dev);
2393 struct adapter *adapter = pi->adapter;
2394 int i;
2395
2396 /* Restart the ports */
2397 for_each_port(adapter, i) {
2398 struct net_device *netdev = adapter->port[i];
2399
2400 if (netif_running(netdev)) {
2401 if (cxgb_open(netdev)) {
2402 dev_err(&pdev->dev,
2403 "can't bring device back up"
2404 " after reset\n");
2405 continue;
2406 }
2407 netif_device_attach(netdev);
2408 }
2409 }
2410
2411 if (is_offload(adapter)) {
2412 __set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map);
2413 if (offload_open(dev))
2414 printk(KERN_WARNING
2415 "Could not bring back offload capabilities\n");
2416 }
2417}
2418
2419static struct pci_error_handlers t3_err_handler = {
2420 .error_detected = t3_io_error_detected,
2421 .slot_reset = t3_io_slot_reset,
2422 .resume = t3_io_resume,
2423};
2424
2319static int __devinit cxgb_enable_msix(struct adapter *adap) 2425static int __devinit cxgb_enable_msix(struct adapter *adap)
2320{ 2426{
2321 struct msix_entry entries[SGE_QSETS + 1]; 2427 struct msix_entry entries[SGE_QSETS + 1];
@@ -2616,6 +2722,7 @@ static struct pci_driver driver = {
2616 .id_table = cxgb3_pci_tbl, 2722 .id_table = cxgb3_pci_tbl,
2617 .probe = init_one, 2723 .probe = init_one,
2618 .remove = __devexit_p(remove_one), 2724 .remove = __devexit_p(remove_one),
2725 .err_handler = &t3_err_handler,
2619}; 2726};
2620 2727
2621static int __init cxgb3_init_module(void) 2728static int __init cxgb3_init_module(void)