aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tlan.c
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@iki.fi>2011-01-21 05:59:31 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-24 18:07:06 -0500
commitfa6d5d4f2b0df1e9b613b7b5926805b8a4306d44 (patch)
tree607fd5c8087821d0d140ad66707c7598c7c40de6 /drivers/net/tlan.c
parentc659c38b2796578638548b77ef626d93609ec8ac (diff)
tlan: add suspend/resume support
Add suspend/resume support to tlan driver. This allows not unloading the driver over suspend/resume. Also, start (or now, wake) the queue after resetting the adapter --- not the other way around. Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tlan.c')
-rw-r--r--drivers/net/tlan.c88
1 files changed, 72 insertions, 16 deletions
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 57380b1b3b60..0678e7e71f19 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -168,6 +168,7 @@
168 * 168 *
169 * v1.15a Dec 15 2008 - Remove bbuf support, it doesn't work anyway. 169 * v1.15a Dec 15 2008 - Remove bbuf support, it doesn't work anyway.
170 * v1.16 Jan 6 2011 - Make checkpatch.pl happy. 170 * v1.16 Jan 6 2011 - Make checkpatch.pl happy.
171 * v1.17 Jan 6 2011 - Add suspend/resume support.
171 * 172 *
172 ******************************************************************************/ 173 ******************************************************************************/
173 174
@@ -219,7 +220,7 @@ module_param(debug, int, 0);
219MODULE_PARM_DESC(debug, "ThunderLAN debug mask"); 220MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
220 221
221static const char tlan_signature[] = "TLAN"; 222static const char tlan_signature[] = "TLAN";
222static const char tlan_banner[] = "ThunderLAN driver v1.16\n"; 223static const char tlan_banner[] = "ThunderLAN driver v1.17\n";
223static int tlan_have_pci; 224static int tlan_have_pci;
224static int tlan_have_eisa; 225static int tlan_have_eisa;
225 226
@@ -462,11 +463,79 @@ static void __devexit tlan_remove_one(struct pci_dev *pdev)
462 pci_set_drvdata(pdev, NULL); 463 pci_set_drvdata(pdev, NULL);
463} 464}
464 465
466static void tlan_start(struct net_device *dev)
467{
468 tlan_reset_lists(dev);
469 /* NOTE: It might not be necessary to read the stats before a
470 reset if you don't care what the values are.
471 */
472 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
473 tlan_reset_adapter(dev);
474 netif_wake_queue(dev);
475}
476
477static void tlan_stop(struct net_device *dev)
478{
479 struct tlan_priv *priv = netdev_priv(dev);
480
481 tlan_read_and_clear_stats(dev, TLAN_RECORD);
482 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
483 /* Reset and power down phy */
484 tlan_reset_adapter(dev);
485 if (priv->timer.function != NULL) {
486 del_timer_sync(&priv->timer);
487 priv->timer.function = NULL;
488 }
489}
490
491#ifdef CONFIG_PM
492
493static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
494{
495 struct net_device *dev = pci_get_drvdata(pdev);
496
497 if (netif_running(dev))
498 tlan_stop(dev);
499
500 netif_device_detach(dev);
501 pci_save_state(pdev);
502 pci_disable_device(pdev);
503 pci_wake_from_d3(pdev, false);
504 pci_set_power_state(pdev, PCI_D3hot);
505
506 return 0;
507}
508
509static int tlan_resume(struct pci_dev *pdev)
510{
511 struct net_device *dev = pci_get_drvdata(pdev);
512
513 pci_set_power_state(pdev, PCI_D0);
514 pci_restore_state(pdev);
515 pci_enable_wake(pdev, 0, 0);
516 netif_device_attach(dev);
517
518 if (netif_running(dev))
519 tlan_start(dev);
520
521 return 0;
522}
523
524#else /* CONFIG_PM */
525
526#define tlan_suspend NULL
527#define tlan_resume NULL
528
529#endif /* CONFIG_PM */
530
531
465static struct pci_driver tlan_driver = { 532static struct pci_driver tlan_driver = {
466 .name = "tlan", 533 .name = "tlan",
467 .id_table = tlan_pci_tbl, 534 .id_table = tlan_pci_tbl,
468 .probe = tlan_init_one, 535 .probe = tlan_init_one,
469 .remove = __devexit_p(tlan_remove_one), 536 .remove = __devexit_p(tlan_remove_one),
537 .suspend = tlan_suspend,
538 .resume = tlan_resume,
470}; 539};
471 540
472static int __init tlan_probe(void) 541static int __init tlan_probe(void)
@@ -965,14 +1034,8 @@ static int tlan_open(struct net_device *dev)
965 } 1034 }
966 1035
967 init_timer(&priv->timer); 1036 init_timer(&priv->timer);
968 netif_start_queue(dev);
969 1037
970 /* NOTE: It might not be necessary to read the stats before a 1038 tlan_start(dev);
971 reset if you don't care what the values are.
972 */
973 tlan_reset_lists(dev);
974 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
975 tlan_reset_adapter(dev);
976 1039
977 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n", 1040 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n",
978 dev->name, priv->tlan_rev); 1041 dev->name, priv->tlan_rev);
@@ -1243,15 +1306,8 @@ static int tlan_close(struct net_device *dev)
1243{ 1306{
1244 struct tlan_priv *priv = netdev_priv(dev); 1307 struct tlan_priv *priv = netdev_priv(dev);
1245 1308
1246 netif_stop_queue(dev);
1247 priv->neg_be_verbose = 0; 1309 priv->neg_be_verbose = 0;
1248 1310 tlan_stop(dev);
1249 tlan_read_and_clear_stats(dev, TLAN_RECORD);
1250 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
1251 if (priv->timer.function != NULL) {
1252 del_timer_sync(&priv->timer);
1253 priv->timer.function = NULL;
1254 }
1255 1311
1256 free_irq(dev->irq, dev); 1312 free_irq(dev->irq, dev);
1257 tlan_free_lists(dev); 1313 tlan_free_lists(dev);