aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r--drivers/net/netxen/Makefile2
-rw-r--r--drivers/net/netxen/netxen_nic.h8
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c2
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c2
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h5
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c19
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h2
-rw-r--r--drivers/net/netxen/netxen_nic_init.c5
-rw-r--r--drivers/net/netxen/netxen_nic_main.c213
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
1430int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); 1430int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac);
1431int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); 1431int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac);
1432extern void netxen_change_ringparam(struct netxen_adapter *adapter); 1432extern void netxen_change_ringparam(struct netxen_adapter *adapter);
1433extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, 1433extern 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)
777int netxen_config_intr_coalesce(struct netxen_adapter *adapter) 777int 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
1036int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac) 1039int 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
1061int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) 1064int 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
39MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); 40MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver");
40MODULE_LICENSE("GPL"); 41MODULE_LICENSE("GPL");
@@ -84,6 +85,7 @@ static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
84static void netxen_create_diag_entries(struct netxen_adapter *adapter); 85static void netxen_create_diag_entries(struct netxen_adapter *adapter);
85static void netxen_remove_diag_entries(struct netxen_adapter *adapter); 86static void netxen_remove_diag_entries(struct netxen_adapter *adapter);
86 87
88static int nx_dev_request_aer(struct netxen_adapter *adapter);
87static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter); 89static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter);
88static int netxen_can_start_firmware(struct netxen_adapter *adapter); 90static 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
101static struct pci_device_id netxen_pci_tbl[] __devinitdata = { 103static 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}
1418static int __netxen_nic_shutdown(struct pci_dev *pdev) 1426
1427static 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}
1455static void netxen_nic_shutdown(struct pci_dev *pdev)
1456{
1457 if (__netxen_nic_shutdown(pdev))
1458 return;
1459}
1460#ifdef CONFIG_PM
1461static int
1462netxen_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)); 1450static int netxen_nic_attach_func(struct pci_dev *pdev)
1471 return 0;
1472}
1473
1474static int
1475netxen_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
1496static 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
1514static 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
1523static void netxen_io_resume(struct pci_dev *pdev)
1524{
1525 pci_cleanup_aer_uncorrect_error_status(pdev);
1526}
1527
1528static 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
1546static int
1547netxen_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
1569static int
1570netxen_nic_resume(struct pci_dev *pdev)
1571{
1572 return netxen_nic_attach_func(pdev);
1573}
1520#endif 1574#endif
1521 1575
1522static int netxen_nic_open(struct net_device *netdev) 1576static 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
2107static void 2161static int
2162nx_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
2183static int
2108nx_dev_request_reset(struct netxen_adapter *adapter) 2184nx_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
2123static int 2206static 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
2501ssize_t netxen_sysfs_write_mem(struct kobject *kobj, 2601static 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
2828static 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
2728static struct pci_driver netxen_driver = { 2834static 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
2740static int __init netxen_init_module(void) 2847static int __init netxen_init_module(void)