diff options
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 8 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 5 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 19 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.h | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 5 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 213 |
9 files changed, 186 insertions, 72 deletions
diff --git a/drivers/net/netxen/Makefile b/drivers/net/netxen/Makefile index 11d94e2434e4..861a0590b1f4 100644 --- a/drivers/net/netxen/Makefile +++ b/drivers/net/netxen/Makefile | |||
@@ -18,7 +18,7 @@ | |||
18 | # MA 02111-1307, USA. | 18 | # MA 02111-1307, USA. |
19 | # | 19 | # |
20 | # The full GNU General Public License is included in this distribution | 20 | # The full GNU General Public License is included in this distribution |
21 | # in the file called LICENSE. | 21 | # in the file called "COPYING". |
22 | # | 22 | # |
23 | # | 23 | # |
24 | 24 | ||
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 9bc5bd1d538a..144d2e880422 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -19,7 +19,7 @@ | |||
19 | * MA 02111-1307, USA. | 19 | * MA 02111-1307, USA. |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
22 | * in the file called LICENSE. | 22 | * in the file called "COPYING". |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
@@ -420,7 +420,7 @@ struct status_desc { | |||
420 | } __attribute__ ((aligned(16))); | 420 | } __attribute__ ((aligned(16))); |
421 | 421 | ||
422 | /* UNIFIED ROMIMAGE *************************/ | 422 | /* UNIFIED ROMIMAGE *************************/ |
423 | #define NX_UNI_FW_MIN_SIZE 0x3eb000 | 423 | #define NX_UNI_FW_MIN_SIZE 0xc8000 |
424 | #define NX_UNI_DIR_SECT_PRODUCT_TBL 0x0 | 424 | #define NX_UNI_DIR_SECT_PRODUCT_TBL 0x0 |
425 | #define NX_UNI_DIR_SECT_BOOTLD 0x6 | 425 | #define NX_UNI_DIR_SECT_BOOTLD 0x6 |
426 | #define NX_UNI_DIR_SECT_FW 0x7 | 426 | #define NX_UNI_DIR_SECT_FW 0x7 |
@@ -1427,8 +1427,8 @@ static inline u32 netxen_tx_avail(struct nx_host_tx_ring *tx_ring) | |||
1427 | 1427 | ||
1428 | } | 1428 | } |
1429 | 1429 | ||
1430 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); | 1430 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac); |
1431 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); | 1431 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac); |
1432 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); | 1432 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); |
1433 | extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, | 1433 | extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, |
1434 | int *valp); | 1434 | int *valp); |
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 9cb8f6878047..2a8ef5fc9663 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * MA 02111-1307, USA. | 19 | * MA 02111-1307, USA. |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
22 | * in the file called LICENSE. | 22 | * in the file called "COPYING". |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 542f408333ff..f8499e56cbee 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * MA 02111-1307, USA. | 19 | * MA 02111-1307, USA. |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
22 | * in the file called LICENSE. | 22 | * in the file called "COPYING". |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index d138fc22927a..622e4c8be937 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -19,7 +19,7 @@ | |||
19 | * MA 02111-1307, USA. | 19 | * MA 02111-1307, USA. |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
22 | * in the file called LICENSE. | 22 | * in the file called "COPYING". |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
@@ -969,7 +969,8 @@ enum { | |||
969 | #define NX_DEV_READY 3 | 969 | #define NX_DEV_READY 3 |
970 | #define NX_DEV_NEED_RESET 4 | 970 | #define NX_DEV_NEED_RESET 4 |
971 | #define NX_DEV_NEED_QUISCENT 5 | 971 | #define NX_DEV_NEED_QUISCENT 5 |
972 | #define NX_DEV_FAILED 6 | 972 | #define NX_DEV_NEED_AER 6 |
973 | #define NX_DEV_FAILED 7 | ||
973 | 974 | ||
974 | #define NX_RCODE_DRIVER_INFO 0x20000000 | 975 | #define NX_RCODE_DRIVER_INFO 0x20000000 |
975 | #define NX_RCODE_DRIVER_CAN_RELOAD 0x40000000 | 976 | #define NX_RCODE_DRIVER_CAN_RELOAD 0x40000000 |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 85e28e60ecf1..dd45c7a9122e 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * MA 02111-1307, USA. | 19 | * MA 02111-1307, USA. |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
22 | * in the file called LICENSE. | 22 | * in the file called "COPYING". |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
@@ -777,17 +777,20 @@ int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) | |||
777 | int netxen_config_intr_coalesce(struct netxen_adapter *adapter) | 777 | int netxen_config_intr_coalesce(struct netxen_adapter *adapter) |
778 | { | 778 | { |
779 | nx_nic_req_t req; | 779 | nx_nic_req_t req; |
780 | u64 word; | 780 | u64 word[6]; |
781 | int rv; | 781 | int rv, i; |
782 | 782 | ||
783 | memset(&req, 0, sizeof(nx_nic_req_t)); | 783 | memset(&req, 0, sizeof(nx_nic_req_t)); |
784 | memset(word, 0, sizeof(word)); | ||
784 | 785 | ||
785 | req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); | 786 | req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); |
786 | 787 | ||
787 | word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); | 788 | word[0] = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); |
788 | req.req_hdr = cpu_to_le64(word); | 789 | req.req_hdr = cpu_to_le64(word[0]); |
789 | 790 | ||
790 | memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal)); | 791 | memcpy(&word[0], &adapter->coal, sizeof(adapter->coal)); |
792 | for (i = 0; i < 6; i++) | ||
793 | req.words[i] = cpu_to_le64(word[i]); | ||
791 | 794 | ||
792 | rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); | 795 | rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); |
793 | if (rv != 0) { | 796 | if (rv != 0) { |
@@ -1033,7 +1036,7 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base, | |||
1033 | return 0; | 1036 | return 0; |
1034 | } | 1037 | } |
1035 | 1038 | ||
1036 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac) | 1039 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac) |
1037 | { | 1040 | { |
1038 | __le32 *pmac = (__le32 *) mac; | 1041 | __le32 *pmac = (__le32 *) mac; |
1039 | u32 offset; | 1042 | u32 offset; |
@@ -1058,7 +1061,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac) | |||
1058 | return 0; | 1061 | return 0; |
1059 | } | 1062 | } |
1060 | 1063 | ||
1061 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) | 1064 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac) |
1062 | { | 1065 | { |
1063 | uint32_t crbaddr, mac_hi, mac_lo; | 1066 | uint32_t crbaddr, mac_hi, mac_lo; |
1064 | int pci_func = adapter->ahw.pci_func; | 1067 | int pci_func = adapter->ahw.pci_func; |
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index 3fd1dcb3583a..e2c5b6f2df03 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h | |||
@@ -19,7 +19,7 @@ | |||
19 | * MA 02111-1307, USA. | 19 | * MA 02111-1307, USA. |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
22 | * in the file called LICENSE. | 22 | * in the file called "COPYING". |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 64cff68d372c..1c63610ead42 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * MA 02111-1307, USA. | 19 | * MA 02111-1307, USA. |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
22 | * in the file called LICENSE. | 22 | * in the file called "COPYING". |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
@@ -780,6 +780,9 @@ netxen_need_fw_reset(struct netxen_adapter *adapter) | |||
780 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | 780 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
781 | return 1; | 781 | return 1; |
782 | 782 | ||
783 | if (adapter->need_fw_reset) | ||
784 | return 1; | ||
785 | |||
783 | /* last attempt had failed */ | 786 | /* last attempt had failed */ |
784 | if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) | 787 | if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) |
785 | return 1; | 788 | return 1; |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 24279e6e55f5..08780ef1c1f8 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * MA 02111-1307, USA. | 19 | * MA 02111-1307, USA. |
20 | * | 20 | * |
21 | * The full GNU General Public License is included in this distribution | 21 | * The full GNU General Public License is included in this distribution |
22 | * in the file called LICENSE. | 22 | * in the file called "COPYING". |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/ipv6.h> | 35 | #include <linux/ipv6.h> |
36 | #include <linux/inetdevice.h> | 36 | #include <linux/inetdevice.h> |
37 | #include <linux/sysfs.h> | 37 | #include <linux/sysfs.h> |
38 | #include <linux/aer.h> | ||
38 | 39 | ||
39 | MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); | 40 | MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); |
40 | MODULE_LICENSE("GPL"); | 41 | MODULE_LICENSE("GPL"); |
@@ -84,6 +85,7 @@ static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter); | |||
84 | static void netxen_create_diag_entries(struct netxen_adapter *adapter); | 85 | static void netxen_create_diag_entries(struct netxen_adapter *adapter); |
85 | static void netxen_remove_diag_entries(struct netxen_adapter *adapter); | 86 | static void netxen_remove_diag_entries(struct netxen_adapter *adapter); |
86 | 87 | ||
88 | static int nx_dev_request_aer(struct netxen_adapter *adapter); | ||
87 | static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter); | 89 | static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter); |
88 | static int netxen_can_start_firmware(struct netxen_adapter *adapter); | 90 | static int netxen_can_start_firmware(struct netxen_adapter *adapter); |
89 | 91 | ||
@@ -98,7 +100,7 @@ static void netxen_config_indev_addr(struct net_device *dev, unsigned long); | |||
98 | {PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \ | 100 | {PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \ |
99 | .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} | 101 | .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} |
100 | 102 | ||
101 | static struct pci_device_id netxen_pci_tbl[] __devinitdata = { | 103 | static DEFINE_PCI_DEVICE_TABLE(netxen_pci_tbl) = { |
102 | ENTRY(PCI_DEVICE_ID_NX2031_10GXSR), | 104 | ENTRY(PCI_DEVICE_ID_NX2031_10GXSR), |
103 | ENTRY(PCI_DEVICE_ID_NX2031_10GCX4), | 105 | ENTRY(PCI_DEVICE_ID_NX2031_10GCX4), |
104 | ENTRY(PCI_DEVICE_ID_NX2031_4GCU), | 106 | ENTRY(PCI_DEVICE_ID_NX2031_4GCU), |
@@ -430,7 +432,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter) | |||
430 | { | 432 | { |
431 | int i; | 433 | int i; |
432 | unsigned char *p; | 434 | unsigned char *p; |
433 | __le64 mac_addr; | 435 | u64 mac_addr; |
434 | struct net_device *netdev = adapter->netdev; | 436 | struct net_device *netdev = adapter->netdev; |
435 | struct pci_dev *pdev = adapter->pdev; | 437 | struct pci_dev *pdev = adapter->pdev; |
436 | 438 | ||
@@ -1262,6 +1264,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1262 | if ((err = pci_request_regions(pdev, netxen_nic_driver_name))) | 1264 | if ((err = pci_request_regions(pdev, netxen_nic_driver_name))) |
1263 | goto err_out_disable_pdev; | 1265 | goto err_out_disable_pdev; |
1264 | 1266 | ||
1267 | if (NX_IS_REVISION_P3(pdev->revision)) | ||
1268 | pci_enable_pcie_error_reporting(pdev); | ||
1269 | |||
1265 | pci_set_master(pdev); | 1270 | pci_set_master(pdev); |
1266 | 1271 | ||
1267 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); | 1272 | netdev = alloc_etherdev(sizeof(struct netxen_adapter)); |
@@ -1409,17 +1414,19 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
1409 | 1414 | ||
1410 | netxen_release_firmware(adapter); | 1415 | netxen_release_firmware(adapter); |
1411 | 1416 | ||
1417 | if (NX_IS_REVISION_P3(pdev->revision)) | ||
1418 | pci_disable_pcie_error_reporting(pdev); | ||
1419 | |||
1412 | pci_release_regions(pdev); | 1420 | pci_release_regions(pdev); |
1413 | pci_disable_device(pdev); | 1421 | pci_disable_device(pdev); |
1414 | pci_set_drvdata(pdev, NULL); | 1422 | pci_set_drvdata(pdev, NULL); |
1415 | 1423 | ||
1416 | free_netdev(netdev); | 1424 | free_netdev(netdev); |
1417 | } | 1425 | } |
1418 | static int __netxen_nic_shutdown(struct pci_dev *pdev) | 1426 | |
1427 | static void netxen_nic_detach_func(struct netxen_adapter *adapter) | ||
1419 | { | 1428 | { |
1420 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1421 | struct net_device *netdev = adapter->netdev; | 1429 | struct net_device *netdev = adapter->netdev; |
1422 | int retval; | ||
1423 | 1430 | ||
1424 | netif_device_detach(netdev); | 1431 | netif_device_detach(netdev); |
1425 | 1432 | ||
@@ -1438,53 +1445,22 @@ static int __netxen_nic_shutdown(struct pci_dev *pdev) | |||
1438 | nx_decr_dev_ref_cnt(adapter); | 1445 | nx_decr_dev_ref_cnt(adapter); |
1439 | 1446 | ||
1440 | clear_bit(__NX_RESETTING, &adapter->state); | 1447 | clear_bit(__NX_RESETTING, &adapter->state); |
1441 | |||
1442 | retval = pci_save_state(pdev); | ||
1443 | if (retval) | ||
1444 | return retval; | ||
1445 | |||
1446 | if (netxen_nic_wol_supported(adapter)) { | ||
1447 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
1448 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
1449 | } | ||
1450 | |||
1451 | pci_disable_device(pdev); | ||
1452 | |||
1453 | return 0; | ||
1454 | } | 1448 | } |
1455 | static void netxen_nic_shutdown(struct pci_dev *pdev) | ||
1456 | { | ||
1457 | if (__netxen_nic_shutdown(pdev)) | ||
1458 | return; | ||
1459 | } | ||
1460 | #ifdef CONFIG_PM | ||
1461 | static int | ||
1462 | netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1463 | { | ||
1464 | int retval; | ||
1465 | |||
1466 | retval = __netxen_nic_shutdown(pdev); | ||
1467 | if (retval) | ||
1468 | return retval; | ||
1469 | 1449 | ||
1470 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 1450 | static int netxen_nic_attach_func(struct pci_dev *pdev) |
1471 | return 0; | ||
1472 | } | ||
1473 | |||
1474 | static int | ||
1475 | netxen_nic_resume(struct pci_dev *pdev) | ||
1476 | { | 1451 | { |
1477 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | 1452 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); |
1478 | struct net_device *netdev = adapter->netdev; | 1453 | struct net_device *netdev = adapter->netdev; |
1479 | int err; | 1454 | int err; |
1480 | 1455 | ||
1481 | pci_set_power_state(pdev, PCI_D0); | ||
1482 | pci_restore_state(pdev); | ||
1483 | |||
1484 | err = pci_enable_device(pdev); | 1456 | err = pci_enable_device(pdev); |
1485 | if (err) | 1457 | if (err) |
1486 | return err; | 1458 | return err; |
1487 | 1459 | ||
1460 | pci_set_power_state(pdev, PCI_D0); | ||
1461 | pci_set_master(pdev); | ||
1462 | pci_restore_state(pdev); | ||
1463 | |||
1488 | adapter->ahw.crb_win = -1; | 1464 | adapter->ahw.crb_win = -1; |
1489 | adapter->ahw.ocm_win = -1; | 1465 | adapter->ahw.ocm_win = -1; |
1490 | 1466 | ||
@@ -1503,11 +1479,10 @@ netxen_nic_resume(struct pci_dev *pdev) | |||
1503 | if (err) | 1479 | if (err) |
1504 | goto err_out_detach; | 1480 | goto err_out_detach; |
1505 | 1481 | ||
1506 | netif_device_attach(netdev); | ||
1507 | |||
1508 | netxen_config_indev_addr(netdev, NETDEV_UP); | 1482 | netxen_config_indev_addr(netdev, NETDEV_UP); |
1509 | } | 1483 | } |
1510 | 1484 | ||
1485 | netif_device_attach(netdev); | ||
1511 | netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY); | 1486 | netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY); |
1512 | return 0; | 1487 | return 0; |
1513 | 1488 | ||
@@ -1517,6 +1492,85 @@ err_out: | |||
1517 | nx_decr_dev_ref_cnt(adapter); | 1492 | nx_decr_dev_ref_cnt(adapter); |
1518 | return err; | 1493 | return err; |
1519 | } | 1494 | } |
1495 | |||
1496 | static pci_ers_result_t netxen_io_error_detected(struct pci_dev *pdev, | ||
1497 | pci_channel_state_t state) | ||
1498 | { | ||
1499 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1500 | |||
1501 | if (state == pci_channel_io_perm_failure) | ||
1502 | return PCI_ERS_RESULT_DISCONNECT; | ||
1503 | |||
1504 | if (nx_dev_request_aer(adapter)) | ||
1505 | return PCI_ERS_RESULT_RECOVERED; | ||
1506 | |||
1507 | netxen_nic_detach_func(adapter); | ||
1508 | |||
1509 | pci_disable_device(pdev); | ||
1510 | |||
1511 | return PCI_ERS_RESULT_NEED_RESET; | ||
1512 | } | ||
1513 | |||
1514 | static pci_ers_result_t netxen_io_slot_reset(struct pci_dev *pdev) | ||
1515 | { | ||
1516 | int err = 0; | ||
1517 | |||
1518 | err = netxen_nic_attach_func(pdev); | ||
1519 | |||
1520 | return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; | ||
1521 | } | ||
1522 | |||
1523 | static void netxen_io_resume(struct pci_dev *pdev) | ||
1524 | { | ||
1525 | pci_cleanup_aer_uncorrect_error_status(pdev); | ||
1526 | } | ||
1527 | |||
1528 | static void netxen_nic_shutdown(struct pci_dev *pdev) | ||
1529 | { | ||
1530 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1531 | |||
1532 | netxen_nic_detach_func(adapter); | ||
1533 | |||
1534 | if (pci_save_state(pdev)) | ||
1535 | return; | ||
1536 | |||
1537 | if (netxen_nic_wol_supported(adapter)) { | ||
1538 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
1539 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
1540 | } | ||
1541 | |||
1542 | pci_disable_device(pdev); | ||
1543 | } | ||
1544 | |||
1545 | #ifdef CONFIG_PM | ||
1546 | static int | ||
1547 | netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state) | ||
1548 | { | ||
1549 | struct netxen_adapter *adapter = pci_get_drvdata(pdev); | ||
1550 | int retval; | ||
1551 | |||
1552 | netxen_nic_detach_func(adapter); | ||
1553 | |||
1554 | retval = pci_save_state(pdev); | ||
1555 | if (retval) | ||
1556 | return retval; | ||
1557 | |||
1558 | if (netxen_nic_wol_supported(adapter)) { | ||
1559 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
1560 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
1561 | } | ||
1562 | |||
1563 | pci_disable_device(pdev); | ||
1564 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
1565 | |||
1566 | return 0; | ||
1567 | } | ||
1568 | |||
1569 | static int | ||
1570 | netxen_nic_resume(struct pci_dev *pdev) | ||
1571 | { | ||
1572 | return netxen_nic_attach_func(pdev); | ||
1573 | } | ||
1520 | #endif | 1574 | #endif |
1521 | 1575 | ||
1522 | static int netxen_nic_open(struct net_device *netdev) | 1576 | static int netxen_nic_open(struct net_device *netdev) |
@@ -2104,20 +2158,49 @@ nx_decr_dev_ref_cnt(struct netxen_adapter *adapter) | |||
2104 | return count; | 2158 | return count; |
2105 | } | 2159 | } |
2106 | 2160 | ||
2107 | static void | 2161 | static int |
2162 | nx_dev_request_aer(struct netxen_adapter *adapter) | ||
2163 | { | ||
2164 | u32 state; | ||
2165 | int ret = -EINVAL; | ||
2166 | |||
2167 | if (netxen_api_lock(adapter)) | ||
2168 | return ret; | ||
2169 | |||
2170 | state = NXRD32(adapter, NX_CRB_DEV_STATE); | ||
2171 | |||
2172 | if (state == NX_DEV_NEED_AER) | ||
2173 | ret = 0; | ||
2174 | else if (state == NX_DEV_READY) { | ||
2175 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_AER); | ||
2176 | ret = 0; | ||
2177 | } | ||
2178 | |||
2179 | netxen_api_unlock(adapter); | ||
2180 | return ret; | ||
2181 | } | ||
2182 | |||
2183 | static int | ||
2108 | nx_dev_request_reset(struct netxen_adapter *adapter) | 2184 | nx_dev_request_reset(struct netxen_adapter *adapter) |
2109 | { | 2185 | { |
2110 | u32 state; | 2186 | u32 state; |
2187 | int ret = -EINVAL; | ||
2111 | 2188 | ||
2112 | if (netxen_api_lock(adapter)) | 2189 | if (netxen_api_lock(adapter)) |
2113 | return; | 2190 | return ret; |
2114 | 2191 | ||
2115 | state = NXRD32(adapter, NX_CRB_DEV_STATE); | 2192 | state = NXRD32(adapter, NX_CRB_DEV_STATE); |
2116 | 2193 | ||
2117 | if (state != NX_DEV_INITALIZING) | 2194 | if (state == NX_DEV_NEED_RESET) |
2195 | ret = 0; | ||
2196 | else if (state != NX_DEV_INITALIZING && state != NX_DEV_NEED_AER) { | ||
2118 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET); | 2197 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET); |
2198 | ret = 0; | ||
2199 | } | ||
2119 | 2200 | ||
2120 | netxen_api_unlock(adapter); | 2201 | netxen_api_unlock(adapter); |
2202 | |||
2203 | return ret; | ||
2121 | } | 2204 | } |
2122 | 2205 | ||
2123 | static int | 2206 | static int |
@@ -2271,17 +2354,29 @@ netxen_check_health(struct netxen_adapter *adapter) | |||
2271 | u32 state, heartbit; | 2354 | u32 state, heartbit; |
2272 | struct net_device *netdev = adapter->netdev; | 2355 | struct net_device *netdev = adapter->netdev; |
2273 | 2356 | ||
2357 | state = NXRD32(adapter, NX_CRB_DEV_STATE); | ||
2358 | if (state == NX_DEV_NEED_AER) | ||
2359 | return 0; | ||
2360 | |||
2274 | if (netxen_nic_check_temp(adapter)) | 2361 | if (netxen_nic_check_temp(adapter)) |
2275 | goto detach; | 2362 | goto detach; |
2276 | 2363 | ||
2277 | if (adapter->need_fw_reset) { | 2364 | if (adapter->need_fw_reset) { |
2278 | nx_dev_request_reset(adapter); | 2365 | if (nx_dev_request_reset(adapter)) |
2366 | return 0; | ||
2279 | goto detach; | 2367 | goto detach; |
2280 | } | 2368 | } |
2281 | 2369 | ||
2282 | state = NXRD32(adapter, NX_CRB_DEV_STATE); | 2370 | /* NX_DEV_NEED_RESET, this state can be marked in two cases |
2283 | if (state == NX_DEV_NEED_RESET) | 2371 | * 1. Tx timeout 2. Fw hang |
2284 | goto detach; | 2372 | * Send request to destroy context in case of tx timeout only |
2373 | * and doesn't required in case of Fw hang | ||
2374 | */ | ||
2375 | if (state == NX_DEV_NEED_RESET) { | ||
2376 | adapter->need_fw_reset = 1; | ||
2377 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | ||
2378 | goto detach; | ||
2379 | } | ||
2285 | 2380 | ||
2286 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | 2381 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
2287 | return 0; | 2382 | return 0; |
@@ -2290,12 +2385,17 @@ netxen_check_health(struct netxen_adapter *adapter) | |||
2290 | if (heartbit != adapter->heartbit) { | 2385 | if (heartbit != adapter->heartbit) { |
2291 | adapter->heartbit = heartbit; | 2386 | adapter->heartbit = heartbit; |
2292 | adapter->fw_fail_cnt = 0; | 2387 | adapter->fw_fail_cnt = 0; |
2388 | if (adapter->need_fw_reset) | ||
2389 | goto detach; | ||
2293 | return 0; | 2390 | return 0; |
2294 | } | 2391 | } |
2295 | 2392 | ||
2296 | if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) | 2393 | if (++adapter->fw_fail_cnt < FW_FAIL_THRESH) |
2297 | return 0; | 2394 | return 0; |
2298 | 2395 | ||
2396 | if (nx_dev_request_reset(adapter)) | ||
2397 | return 0; | ||
2398 | |||
2299 | clear_bit(__NX_FW_ATTACHED, &adapter->state); | 2399 | clear_bit(__NX_FW_ATTACHED, &adapter->state); |
2300 | 2400 | ||
2301 | dev_info(&netdev->dev, "firmware hang detected\n"); | 2401 | dev_info(&netdev->dev, "firmware hang detected\n"); |
@@ -2498,7 +2598,7 @@ netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, | |||
2498 | return size; | 2598 | return size; |
2499 | } | 2599 | } |
2500 | 2600 | ||
2501 | ssize_t netxen_sysfs_write_mem(struct kobject *kobj, | 2601 | static ssize_t netxen_sysfs_write_mem(struct kobject *kobj, |
2502 | struct bin_attribute *attr, char *buf, | 2602 | struct bin_attribute *attr, char *buf, |
2503 | loff_t offset, size_t size) | 2603 | loff_t offset, size_t size) |
2504 | { | 2604 | { |
@@ -2725,6 +2825,12 @@ netxen_config_indev_addr(struct net_device *dev, unsigned long event) | |||
2725 | { } | 2825 | { } |
2726 | #endif | 2826 | #endif |
2727 | 2827 | ||
2828 | static struct pci_error_handlers netxen_err_handler = { | ||
2829 | .error_detected = netxen_io_error_detected, | ||
2830 | .slot_reset = netxen_io_slot_reset, | ||
2831 | .resume = netxen_io_resume, | ||
2832 | }; | ||
2833 | |||
2728 | static struct pci_driver netxen_driver = { | 2834 | static struct pci_driver netxen_driver = { |
2729 | .name = netxen_nic_driver_name, | 2835 | .name = netxen_nic_driver_name, |
2730 | .id_table = netxen_pci_tbl, | 2836 | .id_table = netxen_pci_tbl, |
@@ -2734,7 +2840,8 @@ static struct pci_driver netxen_driver = { | |||
2734 | .suspend = netxen_nic_suspend, | 2840 | .suspend = netxen_nic_suspend, |
2735 | .resume = netxen_nic_resume, | 2841 | .resume = netxen_nic_resume, |
2736 | #endif | 2842 | #endif |
2737 | .shutdown = netxen_nic_shutdown | 2843 | .shutdown = netxen_nic_shutdown, |
2844 | .err_handler = &netxen_err_handler | ||
2738 | }; | 2845 | }; |
2739 | 2846 | ||
2740 | static int __init netxen_init_module(void) | 2847 | static int __init netxen_init_module(void) |