diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2009-03-13 10:52:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-14 17:00:31 -0400 |
commit | 0b72e659a10ec50acbef90756bf04177b66c8266 (patch) | |
tree | 233dc05b96c10a7e0694542589a4d80304e4d52d /drivers/net/netxen | |
parent | fbb52f2272e6265295f0e5f6187b628e4c162eca (diff) |
netxen: add suspend resume support
Detach network interface on PCI suspend and recreate hardware
context after resumes.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 1 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 17 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 102 |
3 files changed, 102 insertions, 18 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 618507074bdd..75cb30f27ae2 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -1389,6 +1389,7 @@ void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value); | |||
1389 | 1389 | ||
1390 | int netxen_nic_get_board_info(struct netxen_adapter *adapter); | 1390 | int netxen_nic_get_board_info(struct netxen_adapter *adapter); |
1391 | void netxen_nic_get_firmware_info(struct netxen_adapter *adapter); | 1391 | void netxen_nic_get_firmware_info(struct netxen_adapter *adapter); |
1392 | int netxen_nic_wol_supported(struct netxen_adapter *adapter); | ||
1392 | 1393 | ||
1393 | int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, | 1394 | int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, |
1394 | ulong off, void *data, int len); | 1395 | ulong off, void *data, int len); |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 8db4ac344146..c8faa53d27af 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -2320,3 +2320,20 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter) | |||
2320 | } | 2320 | } |
2321 | } | 2321 | } |
2322 | 2322 | ||
2323 | int | ||
2324 | netxen_nic_wol_supported(struct netxen_adapter *adapter) | ||
2325 | { | ||
2326 | u32 wol_cfg; | ||
2327 | |||
2328 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
2329 | return 0; | ||
2330 | |||
2331 | wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV); | ||
2332 | if (wol_cfg & (1UL << adapter->portnum)) { | ||
2333 | wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG); | ||
2334 | if (wol_cfg & (1 << adapter->portnum)) | ||
2335 | return 1; | ||
2336 | } | ||
2337 | |||
2338 | return 0; | ||
2339 | } | ||
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 9445277321d7..555b4596b0fe 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -643,6 +643,18 @@ netxen_start_firmware(struct netxen_adapter *adapter) | |||
643 | int val, err, first_boot; | 643 | int val, err, first_boot; |
644 | struct pci_dev *pdev = adapter->pdev; | 644 | struct pci_dev *pdev = adapter->pdev; |
645 | 645 | ||
646 | int first_driver = 0; | ||
647 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
648 | if (adapter->ahw.pci_func == 0) | ||
649 | first_driver = 1; | ||
650 | } else { | ||
651 | if (adapter->portnum == 0) | ||
652 | first_driver = 1; | ||
653 | } | ||
654 | |||
655 | if (!first_driver) | ||
656 | return 0; | ||
657 | |||
646 | first_boot = adapter->pci_read_normalize(adapter, | 658 | first_boot = adapter->pci_read_normalize(adapter, |
647 | NETXEN_CAM_RAM(0x1fc)); | 659 | NETXEN_CAM_RAM(0x1fc)); |
648 | 660 | ||
@@ -859,7 +871,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
859 | struct net_device *netdev = NULL; | 871 | struct net_device *netdev = NULL; |
860 | struct netxen_adapter *adapter = NULL; | 872 | struct netxen_adapter *adapter = NULL; |
861 | int i = 0, err; | 873 | int i = 0, err; |
862 | int first_driver; | ||
863 | int pci_func_id = PCI_FUNC(pdev->devfn); | 874 | int pci_func_id = PCI_FUNC(pdev->devfn); |
864 | uint8_t revision_id; | 875 | uint8_t revision_id; |
865 | 876 | ||
@@ -978,20 +989,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
978 | */ | 989 | */ |
979 | netxen_check_options(adapter); | 990 | netxen_check_options(adapter); |
980 | 991 | ||
981 | first_driver = 0; | 992 | err = netxen_start_firmware(adapter); |
982 | if (NX_IS_REVISION_P3(revision_id)) { | 993 | if (err) |
983 | if (adapter->ahw.pci_func == 0) | 994 | goto err_out_iounmap; |
984 | first_driver = 1; | ||
985 | } else { | ||
986 | if (adapter->portnum == 0) | ||
987 | first_driver = 1; | ||
988 | } | ||
989 | |||
990 | if (first_driver) { | ||
991 | err = netxen_start_firmware(adapter); | ||
992 | if (err) | ||
993 | goto err_out_iounmap; | ||
994 | } | ||
995 | 995 | ||
996 | nx_update_dma_mask(adapter); | 996 | nx_update_dma_mask(adapter); |
997 | 997 | ||
@@ -1062,8 +1062,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1062 | err_out_disable_msi: | 1062 | err_out_disable_msi: |
1063 | netxen_teardown_intr(adapter); | 1063 | netxen_teardown_intr(adapter); |
1064 | 1064 | ||
1065 | if (first_driver) | 1065 | netxen_free_adapter_offload(adapter); |
1066 | netxen_free_adapter_offload(adapter); | ||
1067 | 1066 | ||
1068 | err_out_iounmap: | 1067 | err_out_iounmap: |
1069 | netxen_cleanup_pci_map(adapter); | 1068 | netxen_cleanup_pci_map(adapter); |
@@ -1114,6 +1113,71 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
1114 | free_netdev(netdev); | 1113 | free_netdev(netdev); |
1115 | } | 1114 | } |
1116 | 1115 | ||
1116 | static int | ||
1117 | netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1118 | { | ||
1119 | |||
1120 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1121 | struct net_device *netdev = adapter->netdev; | ||
1122 | |||
1123 | netif_device_detach(netdev); | ||
1124 | |||
1125 | if (netif_running(netdev)) | ||
1126 | netxen_nic_down(adapter, netdev); | ||
1127 | |||
1128 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) | ||
1129 | netxen_nic_detach(adapter); | ||
1130 | |||
1131 | pci_save_state(pdev); | ||
1132 | |||
1133 | if (netxen_nic_wol_supported(adapter)) { | ||
1134 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
1135 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
1136 | } | ||
1137 | |||
1138 | pci_disable_device(pdev); | ||
1139 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1140 | |||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | static int | ||
1145 | netxen_nic_resume(struct pci_dev *pdev) | ||
1146 | { | ||
1147 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1148 | struct net_device *netdev = adapter->netdev; | ||
1149 | int err; | ||
1150 | |||
1151 | pci_set_power_state(pdev, PCI_D0); | ||
1152 | pci_restore_state(pdev); | ||
1153 | |||
1154 | err = pci_enable_device(pdev); | ||
1155 | if (err) | ||
1156 | return err; | ||
1157 | |||
1158 | adapter->curr_window = 255; | ||
1159 | |||
1160 | err = netxen_start_firmware(adapter); | ||
1161 | if (err) { | ||
1162 | dev_err(&pdev->dev, "failed to start firmware\n"); | ||
1163 | return err; | ||
1164 | } | ||
1165 | |||
1166 | if (netif_running(netdev)) { | ||
1167 | err = netxen_nic_attach(adapter); | ||
1168 | if (err) | ||
1169 | return err; | ||
1170 | |||
1171 | err = netxen_nic_up(adapter, netdev); | ||
1172 | if (err) | ||
1173 | return err; | ||
1174 | |||
1175 | netif_device_attach(netdev); | ||
1176 | } | ||
1177 | |||
1178 | return 0; | ||
1179 | } | ||
1180 | |||
1117 | static int netxen_nic_open(struct net_device *netdev) | 1181 | static int netxen_nic_open(struct net_device *netdev) |
1118 | { | 1182 | { |
1119 | struct netxen_adapter *adapter = netdev_priv(netdev); | 1183 | struct netxen_adapter *adapter = netdev_priv(netdev); |
@@ -1649,7 +1713,9 @@ static struct pci_driver netxen_driver = { | |||
1649 | .name = netxen_nic_driver_name, | 1713 | .name = netxen_nic_driver_name, |
1650 | .id_table = netxen_pci_tbl, | 1714 | .id_table = netxen_pci_tbl, |
1651 | .probe = netxen_nic_probe, | 1715 | .probe = netxen_nic_probe, |
1652 | .remove = __devexit_p(netxen_nic_remove) | 1716 | .remove = __devexit_p(netxen_nic_remove), |
1717 | .suspend = netxen_nic_suspend, | ||
1718 | .resume = netxen_nic_resume | ||
1653 | }; | 1719 | }; |
1654 | 1720 | ||
1655 | /* Driver Registration on NetXen card */ | 1721 | /* Driver Registration on NetXen card */ |