35
35
#include <linux/ipv6.h>
36
36
#include <linux/inetdevice.h>
37
37
#include <linux/sysfs.h>
38
+ #include <linux/aer.h>
38
39
39
40
MODULE_DESCRIPTION ("QLogic/NetXen (1/10) GbE Converged Ethernet Driver" );
40
41
MODULE_LICENSE ("GPL" );
@@ -84,6 +85,7 @@ static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
84
85
static void netxen_create_diag_entries (struct netxen_adapter * adapter );
85
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
89
static int nx_decr_dev_ref_cnt (struct netxen_adapter * adapter );
88
90
static int netxen_can_start_firmware (struct netxen_adapter * adapter );
89
91
@@ -1262,6 +1264,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1262
1264
if ((err = pci_request_regions (pdev , netxen_nic_driver_name )))
1263
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
1270
pci_set_master (pdev );
1266
1271
1267
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
1415
netxen_release_firmware (adapter );
1411
1416
1417
+ if (NX_IS_REVISION_P3 (pdev -> revision ))
1418
+ pci_disable_pcie_error_reporting (pdev );
1419
+
1412
1420
pci_release_regions (pdev );
1413
1421
pci_disable_device (pdev );
1414
1422
pci_set_drvdata (pdev , NULL );
1415
1423
1416
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
1429
struct net_device * netdev = adapter -> netdev ;
1422
- int retval ;
1423
1430
1424
1431
netif_device_detach (netdev );
1425
1432
@@ -1438,43 +1445,9 @@ static int __netxen_nic_shutdown(struct pci_dev *pdev)
1438
1445
nx_decr_dev_ref_cnt (adapter );
1439
1446
1440
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
- return 0 ;
1452
- }
1453
- static void netxen_nic_shutdown (struct pci_dev * pdev )
1454
- {
1455
- if (__netxen_nic_shutdown (pdev ))
1456
- return ;
1457
-
1458
- pci_disable_device (pdev );
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
-
1470
- pci_set_power_state (pdev , pci_choose_state (pdev , state ));
1471
-
1472
- pci_disable_device (pdev );
1473
- return 0 ;
1474
1448
}
1475
1449
1476
- static int
1477
- netxen_nic_resume (struct pci_dev * pdev )
1450
+ static int netxen_nic_attach_func (struct pci_dev * pdev )
1478
1451
{
1479
1452
struct netxen_adapter * adapter = pci_get_drvdata (pdev );
1480
1453
struct net_device * netdev = adapter -> netdev ;
@@ -1519,6 +1492,85 @@ netxen_nic_resume(struct pci_dev *pdev)
1519
1492
nx_decr_dev_ref_cnt (adapter );
1520
1493
return err ;
1521
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
+ }
1522
1574
#endif
1523
1575
1524
1576
static int netxen_nic_open (struct net_device * netdev )
@@ -2110,20 +2162,49 @@ nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
2110
2162
return count ;
2111
2163
}
2112
2164
2113
- static void
2165
+ static int
2166
+ nx_dev_request_aer (struct netxen_adapter * adapter )
2167
+ {
2168
+ u32 state ;
2169
+ int ret = - EINVAL ;
2170
+
2171
+ if (netxen_api_lock (adapter ))
2172
+ return ret ;
2173
+
2174
+ state = NXRD32 (adapter , NX_CRB_DEV_STATE );
2175
+
2176
+ if (state == NX_DEV_NEED_AER )
2177
+ ret = 0 ;
2178
+ else if (state == NX_DEV_READY ) {
2179
+ NXWR32 (adapter , NX_CRB_DEV_STATE , NX_DEV_NEED_AER );
2180
+ ret = 0 ;
2181
+ }
2182
+
2183
+ netxen_api_unlock (adapter );
2184
+ return ret ;
2185
+ }
2186
+
2187
+ static int
2114
2188
nx_dev_request_reset (struct netxen_adapter * adapter )
2115
2189
{
2116
2190
u32 state ;
2191
+ int ret = - EINVAL ;
2117
2192
2118
2193
if (netxen_api_lock (adapter ))
2119
- return ;
2194
+ return ret ;
2120
2195
2121
2196
state = NXRD32 (adapter , NX_CRB_DEV_STATE );
2122
2197
2123
- if (state != NX_DEV_INITALIZING )
2198
+ if (state == NX_DEV_NEED_RESET )
2199
+ ret = 0 ;
2200
+ else if (state != NX_DEV_INITALIZING && state != NX_DEV_NEED_AER ) {
2124
2201
NXWR32 (adapter , NX_CRB_DEV_STATE , NX_DEV_NEED_RESET );
2202
+ ret = 0 ;
2203
+ }
2125
2204
2126
2205
netxen_api_unlock (adapter );
2206
+
2207
+ return ret ;
2127
2208
}
2128
2209
2129
2210
static int
@@ -2275,18 +2356,28 @@ netxen_check_health(struct netxen_adapter *adapter)
2275
2356
u32 state , heartbit ;
2276
2357
struct net_device * netdev = adapter -> netdev ;
2277
2358
2359
+ state = NXRD32 (adapter , NX_CRB_DEV_STATE );
2360
+ if (state == NX_DEV_NEED_AER )
2361
+ return 0 ;
2362
+
2278
2363
if (netxen_nic_check_temp (adapter ))
2279
2364
goto detach ;
2280
2365
2281
2366
if (adapter -> need_fw_reset ) {
2282
- nx_dev_request_reset (adapter );
2367
+ if (nx_dev_request_reset (adapter ))
2368
+ return 0 ;
2283
2369
goto detach ;
2284
2370
}
2285
2371
2286
- state = NXRD32 (adapter , NX_CRB_DEV_STATE );
2372
+ /* NX_DEV_NEED_RESET, this state can be marked in two cases
2373
+ * 1. Tx timeout 2. Fw hang
2374
+ * Send request to destroy context in case of tx timeout only
2375
+ * and doesn't required in case of Fw hang
2376
+ */
2287
2377
if (state == NX_DEV_NEED_RESET ) {
2288
2378
adapter -> need_fw_reset = 1 ;
2289
- goto detach ;
2379
+ if (NX_IS_REVISION_P2 (adapter -> ahw .revision_id ))
2380
+ goto detach ;
2290
2381
}
2291
2382
2292
2383
if (NX_IS_REVISION_P2 (adapter -> ahw .revision_id ))
@@ -2296,12 +2387,17 @@ netxen_check_health(struct netxen_adapter *adapter)
2296
2387
if (heartbit != adapter -> heartbit ) {
2297
2388
adapter -> heartbit = heartbit ;
2298
2389
adapter -> fw_fail_cnt = 0 ;
2390
+ if (adapter -> need_fw_reset )
2391
+ goto detach ;
2299
2392
return 0 ;
2300
2393
}
2301
2394
2302
2395
if (++ adapter -> fw_fail_cnt < FW_FAIL_THRESH )
2303
2396
return 0 ;
2304
2397
2398
+ if (nx_dev_request_reset (adapter ))
2399
+ return 0 ;
2400
+
2305
2401
clear_bit (__NX_FW_ATTACHED , & adapter -> state );
2306
2402
2307
2403
dev_info (& netdev -> dev , "firmware hang detected\n" );
@@ -2731,6 +2827,12 @@ netxen_config_indev_addr(struct net_device *dev, unsigned long event)
2731
2827
{ }
2732
2828
#endif
2733
2829
2830
+ static struct pci_error_handlers netxen_err_handler = {
2831
+ .error_detected = netxen_io_error_detected ,
2832
+ .slot_reset = netxen_io_slot_reset ,
2833
+ .resume = netxen_io_resume ,
2834
+ };
2835
+
2734
2836
static struct pci_driver netxen_driver = {
2735
2837
.name = netxen_nic_driver_name ,
2736
2838
.id_table = netxen_pci_tbl ,
@@ -2740,7 +2842,8 @@ static struct pci_driver netxen_driver = {
2740
2842
.suspend = netxen_nic_suspend ,
2741
2843
.resume = netxen_nic_resume ,
2742
2844
#endif
2743
- .shutdown = netxen_nic_shutdown
2845
+ .shutdown = netxen_nic_shutdown ,
2846
+ .err_handler = & netxen_err_handler
2744
2847
};
2745
2848
2746
2849
static int __init netxen_init_module (void )
0 commit comments