@@ -9718,6 +9718,31 @@ static struct bnx2x_prev_path_list *
97189718	return  NULL ;
97199719}
97209720
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+ 
97219746static  bool  bnx2x_prev_is_path_marked (struct  bnx2x  * bp )
97229747{
97239748	struct  bnx2x_prev_path_list  * tmp_list ;
@@ -9726,14 +9751,15 @@ static bool bnx2x_prev_is_path_marked(struct bnx2x *bp)
97269751	if  (down_trylock (& bnx2x_prev_sem ))
97279752		return  false;
97289753
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  {
97339760			rc  =  true;
97349761			BNX2X_DEV_INFO ("Path %d was already cleaned from previous drivers\n" ,
97359762				       BP_PATH (bp ));
9736- 			break ;
97379763		}
97389764	}
97399765
@@ -9747,6 +9773,28 @@ static int bnx2x_prev_mark_path(struct bnx2x *bp, bool after_undi)
97479773	struct  bnx2x_prev_path_list  * tmp_list ;
97489774	int  rc ;
97499775
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 */ 
97509798	tmp_list  =  kmalloc (sizeof (struct  bnx2x_prev_path_list ), GFP_KERNEL );
97519799	if  (!tmp_list ) {
97529800		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)
97569804	tmp_list -> bus  =  bp -> pdev -> bus -> number ;
97579805	tmp_list -> slot  =  PCI_SLOT (bp -> pdev -> devfn );
97589806	tmp_list -> path  =  BP_PATH (bp );
9807+ 	tmp_list -> aer  =  0 ;
97599808	tmp_list -> undi  =  after_undi  ? (1  << BP_PORT (bp )) : 0 ;
97609809
97619810	rc  =  down_interruptible (& bnx2x_prev_sem );
97629811	if  (rc ) {
97639812		BNX2X_ERR ("Received %d when tried to take lock\n" , rc );
97649813		kfree (tmp_list );
97659814	} 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 ));
97689817		list_add (& tmp_list -> list , & bnx2x_prev_list );
97699818		up (& bnx2x_prev_sem );
97709819	}
@@ -10003,6 +10052,7 @@ static int bnx2x_prev_unload(struct bnx2x *bp)
1000310052	}
1000410053
1000510054	do  {
10055+ 		int  aer  =  0 ;
1000610056		/* Lock MCP using an unload request */ 
1000710057		fw  =  bnx2x_fw_command (bp , DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS , 0 );
1000810058		if  (!fw ) {
@@ -10011,7 +10061,18 @@ static int bnx2x_prev_unload(struct bnx2x *bp)
1001110061			break ;
1001210062		}
1001310063
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 ) {
1001510076			rc  =  bnx2x_prev_unload_common (bp );
1001610077			break ;
1001710078		}
@@ -12632,9 +12693,7 @@ static void bnx2x_remove_one(struct pci_dev *pdev)
1263212693
1263312694static  int  bnx2x_eeh_nic_unload (struct  bnx2x  * bp )
1263412695{
12635- 	int  i ;
12636- 
12637- 	bp -> state  =  BNX2X_STATE_ERROR ;
12696+ 	bp -> state  =  BNX2X_STATE_CLOSING_WAIT4_HALT ;
1263812697
1263912698	bp -> rx_mode  =  BNX2X_RX_MODE_NONE ;
1264012699
@@ -12643,29 +12702,21 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
1264312702
1264412703	/* Stop Tx */ 
1264512704	bnx2x_tx_disable (bp );
12646- 
12647- 	bnx2x_netif_stop (bp , 0 );
1264812705	/* Delete all NAPI objects */ 
1264912706	bnx2x_del_all_napi (bp );
1265012707	if  (CNIC_LOADED (bp ))
1265112708		bnx2x_del_all_napi_cnic (bp );
12709+ 	netdev_reset_tc (bp -> dev );
1265212710
1265312711	del_timer_sync (& bp -> timer );
12712+ 	cancel_delayed_work (& bp -> sp_task );
12713+ 	cancel_delayed_work (& bp -> period_task );
1265412714
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 );
1266712718
12668- 	bp -> state   =   BNX2X_STATE_CLOSED ;
12719+ 	bnx2x_save_statistics ( bp ) ;
1266912720
1267012721	netif_carrier_off (bp -> dev );
1267112722
@@ -12701,6 +12752,8 @@ static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev,
1270112752
1270212753	rtnl_lock ();
1270312754
12755+ 	BNX2X_ERR ("IO error detected\n" );
12756+ 
1270412757	netif_device_detach (dev );
1270512758
1270612759	if  (state  ==  pci_channel_io_perm_failure ) {
@@ -12711,6 +12764,8 @@ static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev,
1271112764	if  (netif_running (dev ))
1271212765		bnx2x_eeh_nic_unload (bp );
1271312766
12767+ 	bnx2x_prev_path_mark_eeh (bp );
12768+ 
1271412769	pci_disable_device (pdev );
1271512770
1271612771	rtnl_unlock ();
@@ -12729,9 +12784,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
1272912784{
1273012785	struct  net_device  * dev  =  pci_get_drvdata (pdev );
1273112786	struct  bnx2x  * bp  =  netdev_priv (dev );
12787+ 	int  i ;
1273212788
1273312789	rtnl_lock ();
12734- 
12790+ 	 BNX2X_ERR ( "IO slot reset initializing...\n" ); 
1273512791	if  (pci_enable_device (pdev )) {
1273612792		dev_err (& pdev -> dev ,
1273712793			"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)
1274512801	if  (netif_running (dev ))
1274612802		bnx2x_set_power_state (bp , PCI_D0 );
1274712803
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+ 
1274812840	rtnl_unlock ();
1274912841
1275012842	return  PCI_ERS_RESULT_RECOVERED ;
@@ -12771,6 +12863,9 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
1277112863
1277212864	bnx2x_eeh_recover (bp );
1277312865
12866+ 	bp -> fw_seq  =  SHMEM_RD (bp , func_mb [BP_FW_MB_IDX (bp )].drv_mb_header ) & 
12867+ 							DRV_MSG_SEQ_NUMBER_MASK ;
12868+ 
1277412869	if  (netif_running (dev ))
1277512870		bnx2x_nic_load (bp , LOAD_NORMAL );
1277612871
0 commit comments