@@ -9718,6 +9718,31 @@ static struct bnx2x_prev_path_list *
9718
9718
return NULL ;
9719
9719
}
9720
9720
9721
+ static int bnx2x_prev_path_mark_eeh (struct bnx2x * bp )
9722
+ {
9723
+ struct bnx2x_prev_path_list * tmp_list ;
9724
+ int rc ;
9725
+
9726
+ rc = down_interruptible (& bnx2x_prev_sem );
9727
+ if (rc ) {
9728
+ BNX2X_ERR ("Received %d when tried to take lock\n" , rc );
9729
+ return rc ;
9730
+ }
9731
+
9732
+ tmp_list = bnx2x_prev_path_get_entry (bp );
9733
+ if (tmp_list ) {
9734
+ tmp_list -> aer = 1 ;
9735
+ rc = 0 ;
9736
+ } else {
9737
+ BNX2X_ERR ("path %d: Entry does not exist for eeh; Flow occurs before initial insmod is over ?\n" ,
9738
+ BP_PATH (bp ));
9739
+ }
9740
+
9741
+ up (& bnx2x_prev_sem );
9742
+
9743
+ return rc ;
9744
+ }
9745
+
9721
9746
static bool bnx2x_prev_is_path_marked (struct bnx2x * bp )
9722
9747
{
9723
9748
struct bnx2x_prev_path_list * tmp_list ;
@@ -9726,14 +9751,15 @@ static bool bnx2x_prev_is_path_marked(struct bnx2x *bp)
9726
9751
if (down_trylock (& bnx2x_prev_sem ))
9727
9752
return false;
9728
9753
9729
- list_for_each_entry (tmp_list , & bnx2x_prev_list , list ) {
9730
- if (PCI_SLOT (bp -> pdev -> devfn ) == tmp_list -> slot &&
9731
- bp -> pdev -> bus -> number == tmp_list -> bus &&
9732
- BP_PATH (bp ) == tmp_list -> path ) {
9754
+ tmp_list = bnx2x_prev_path_get_entry (bp );
9755
+ if (tmp_list ) {
9756
+ if (tmp_list -> aer ) {
9757
+ DP (NETIF_MSG_HW , "Path %d was marked by AER\n" ,
9758
+ BP_PATH (bp ));
9759
+ } else {
9733
9760
rc = true;
9734
9761
BNX2X_DEV_INFO ("Path %d was already cleaned from previous drivers\n" ,
9735
9762
BP_PATH (bp ));
9736
- break ;
9737
9763
}
9738
9764
}
9739
9765
@@ -9747,6 +9773,28 @@ static int bnx2x_prev_mark_path(struct bnx2x *bp, bool after_undi)
9747
9773
struct bnx2x_prev_path_list * tmp_list ;
9748
9774
int rc ;
9749
9775
9776
+ rc = down_interruptible (& bnx2x_prev_sem );
9777
+ if (rc ) {
9778
+ BNX2X_ERR ("Received %d when tried to take lock\n" , rc );
9779
+ return rc ;
9780
+ }
9781
+
9782
+ /* Check whether the entry for this path already exists */
9783
+ tmp_list = bnx2x_prev_path_get_entry (bp );
9784
+ if (tmp_list ) {
9785
+ if (!tmp_list -> aer ) {
9786
+ BNX2X_ERR ("Re-Marking the path.\n" );
9787
+ } else {
9788
+ DP (NETIF_MSG_HW , "Removing AER indication from path %d\n" ,
9789
+ BP_PATH (bp ));
9790
+ tmp_list -> aer = 0 ;
9791
+ }
9792
+ up (& bnx2x_prev_sem );
9793
+ return 0 ;
9794
+ }
9795
+ up (& bnx2x_prev_sem );
9796
+
9797
+ /* Create an entry for this path and add it */
9750
9798
tmp_list = kmalloc (sizeof (struct bnx2x_prev_path_list ), GFP_KERNEL );
9751
9799
if (!tmp_list ) {
9752
9800
BNX2X_ERR ("Failed to allocate 'bnx2x_prev_path_list'\n" );
@@ -9756,15 +9804,16 @@ static int bnx2x_prev_mark_path(struct bnx2x *bp, bool after_undi)
9756
9804
tmp_list -> bus = bp -> pdev -> bus -> number ;
9757
9805
tmp_list -> slot = PCI_SLOT (bp -> pdev -> devfn );
9758
9806
tmp_list -> path = BP_PATH (bp );
9807
+ tmp_list -> aer = 0 ;
9759
9808
tmp_list -> undi = after_undi ? (1 << BP_PORT (bp )) : 0 ;
9760
9809
9761
9810
rc = down_interruptible (& bnx2x_prev_sem );
9762
9811
if (rc ) {
9763
9812
BNX2X_ERR ("Received %d when tried to take lock\n" , rc );
9764
9813
kfree (tmp_list );
9765
9814
} else {
9766
- BNX2X_DEV_INFO ( "Marked path [%d] - finished previous unload\n" ,
9767
- BP_PATH (bp ));
9815
+ DP ( NETIF_MSG_HW , "Marked path [%d] - finished previous unload\n" ,
9816
+ BP_PATH (bp ));
9768
9817
list_add (& tmp_list -> list , & bnx2x_prev_list );
9769
9818
up (& bnx2x_prev_sem );
9770
9819
}
@@ -10003,6 +10052,7 @@ static int bnx2x_prev_unload(struct bnx2x *bp)
10003
10052
}
10004
10053
10005
10054
do {
10055
+ int aer = 0 ;
10006
10056
/* Lock MCP using an unload request */
10007
10057
fw = bnx2x_fw_command (bp , DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS , 0 );
10008
10058
if (!fw ) {
@@ -10011,7 +10061,18 @@ static int bnx2x_prev_unload(struct bnx2x *bp)
10011
10061
break ;
10012
10062
}
10013
10063
10014
- if (fw == FW_MSG_CODE_DRV_UNLOAD_COMMON ) {
10064
+ rc = down_interruptible (& bnx2x_prev_sem );
10065
+ if (rc ) {
10066
+ BNX2X_ERR ("Cannot check for AER; Received %d when tried to take lock\n" ,
10067
+ rc );
10068
+ } else {
10069
+ /* If Path is marked by EEH, ignore unload status */
10070
+ aer = !!(bnx2x_prev_path_get_entry (bp ) &&
10071
+ bnx2x_prev_path_get_entry (bp )-> aer );
10072
+ }
10073
+ up (& bnx2x_prev_sem );
10074
+
10075
+ if (fw == FW_MSG_CODE_DRV_UNLOAD_COMMON || aer ) {
10015
10076
rc = bnx2x_prev_unload_common (bp );
10016
10077
break ;
10017
10078
}
@@ -12632,9 +12693,7 @@ static void bnx2x_remove_one(struct pci_dev *pdev)
12632
12693
12633
12694
static int bnx2x_eeh_nic_unload (struct bnx2x * bp )
12634
12695
{
12635
- int i ;
12636
-
12637
- bp -> state = BNX2X_STATE_ERROR ;
12696
+ bp -> state = BNX2X_STATE_CLOSING_WAIT4_HALT ;
12638
12697
12639
12698
bp -> rx_mode = BNX2X_RX_MODE_NONE ;
12640
12699
@@ -12643,29 +12702,21 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
12643
12702
12644
12703
/* Stop Tx */
12645
12704
bnx2x_tx_disable (bp );
12646
-
12647
- bnx2x_netif_stop (bp , 0 );
12648
12705
/* Delete all NAPI objects */
12649
12706
bnx2x_del_all_napi (bp );
12650
12707
if (CNIC_LOADED (bp ))
12651
12708
bnx2x_del_all_napi_cnic (bp );
12709
+ netdev_reset_tc (bp -> dev );
12652
12710
12653
12711
del_timer_sync (& bp -> timer );
12712
+ cancel_delayed_work (& bp -> sp_task );
12713
+ cancel_delayed_work (& bp -> period_task );
12654
12714
12655
- bnx2x_stats_handle (bp , STATS_EVENT_STOP );
12656
-
12657
- /* Release IRQs */
12658
- bnx2x_free_irq (bp );
12659
-
12660
- /* Free SKBs, SGEs, TPA pool and driver internals */
12661
- bnx2x_free_skbs (bp );
12662
-
12663
- for_each_rx_queue (bp , i )
12664
- bnx2x_free_rx_sge_range (bp , bp -> fp + i , NUM_RX_SGE );
12665
-
12666
- bnx2x_free_mem (bp );
12715
+ spin_lock_bh (& bp -> stats_lock );
12716
+ bp -> stats_state = STATS_STATE_DISABLED ;
12717
+ spin_unlock_bh (& bp -> stats_lock );
12667
12718
12668
- bp -> state = BNX2X_STATE_CLOSED ;
12719
+ bnx2x_save_statistics ( bp ) ;
12669
12720
12670
12721
netif_carrier_off (bp -> dev );
12671
12722
@@ -12701,6 +12752,8 @@ static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev,
12701
12752
12702
12753
rtnl_lock ();
12703
12754
12755
+ BNX2X_ERR ("IO error detected\n" );
12756
+
12704
12757
netif_device_detach (dev );
12705
12758
12706
12759
if (state == pci_channel_io_perm_failure ) {
@@ -12711,6 +12764,8 @@ static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev,
12711
12764
if (netif_running (dev ))
12712
12765
bnx2x_eeh_nic_unload (bp );
12713
12766
12767
+ bnx2x_prev_path_mark_eeh (bp );
12768
+
12714
12769
pci_disable_device (pdev );
12715
12770
12716
12771
rtnl_unlock ();
@@ -12729,9 +12784,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
12729
12784
{
12730
12785
struct net_device * dev = pci_get_drvdata (pdev );
12731
12786
struct bnx2x * bp = netdev_priv (dev );
12787
+ int i ;
12732
12788
12733
12789
rtnl_lock ();
12734
-
12790
+ BNX2X_ERR ( "IO slot reset initializing...\n" );
12735
12791
if (pci_enable_device (pdev )) {
12736
12792
dev_err (& pdev -> dev ,
12737
12793
"Cannot re-enable PCI device after reset\n" );
@@ -12745,6 +12801,42 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
12745
12801
if (netif_running (dev ))
12746
12802
bnx2x_set_power_state (bp , PCI_D0 );
12747
12803
12804
+ if (netif_running (dev )) {
12805
+ BNX2X_ERR ("IO slot reset --> driver unload\n" );
12806
+ if (IS_PF (bp ) && SHMEM2_HAS (bp , drv_capabilities_flag )) {
12807
+ u32 v ;
12808
+
12809
+ v = SHMEM2_RD (bp ,
12810
+ drv_capabilities_flag [BP_FW_MB_IDX (bp )]);
12811
+ SHMEM2_WR (bp , drv_capabilities_flag [BP_FW_MB_IDX (bp )],
12812
+ v & ~DRV_FLAGS_CAPABILITIES_LOADED_L2 );
12813
+ }
12814
+ bnx2x_drain_tx_queues (bp );
12815
+ bnx2x_send_unload_req (bp , UNLOAD_RECOVERY );
12816
+ bnx2x_netif_stop (bp , 1 );
12817
+ bnx2x_free_irq (bp );
12818
+
12819
+ /* Report UNLOAD_DONE to MCP */
12820
+ bnx2x_send_unload_done (bp , true);
12821
+
12822
+ bp -> sp_state = 0 ;
12823
+ bp -> port .pmf = 0 ;
12824
+
12825
+ bnx2x_prev_unload (bp );
12826
+
12827
+ /* We should have resetted the engine, so It's fair to
12828
+ * assume the FW will no longer write to the bnx2x driver.
12829
+ */
12830
+ bnx2x_squeeze_objects (bp );
12831
+ bnx2x_free_skbs (bp );
12832
+ for_each_rx_queue (bp , i )
12833
+ bnx2x_free_rx_sge_range (bp , bp -> fp + i , NUM_RX_SGE );
12834
+ bnx2x_free_fp_mem (bp );
12835
+ bnx2x_free_mem (bp );
12836
+
12837
+ bp -> state = BNX2X_STATE_CLOSED ;
12838
+ }
12839
+
12748
12840
rtnl_unlock ();
12749
12841
12750
12842
return PCI_ERS_RESULT_RECOVERED ;
@@ -12771,6 +12863,9 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
12771
12863
12772
12864
bnx2x_eeh_recover (bp );
12773
12865
12866
+ bp -> fw_seq = SHMEM_RD (bp , func_mb [BP_FW_MB_IDX (bp )].drv_mb_header ) &
12867
+ DRV_MSG_SEQ_NUMBER_MASK ;
12868
+
12774
12869
if (netif_running (dev ))
12775
12870
bnx2x_nic_load (bp , LOAD_NORMAL );
12776
12871
0 commit comments