diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
| -rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 35 | 
1 files changed, 24 insertions, 11 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index a77ee2f8fb8d..c1841db1b500 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -820,7 +820,7 @@ static int tg3_ape_event_lock(struct tg3 *tp, u32 timeout_us)  		tg3_ape_unlock(tp, TG3_APE_LOCK_MEM); -		udelay(10); +		usleep_range(10, 20);  		timeout_us -= (timeout_us > 10) ? 10 : timeout_us;  	} @@ -922,8 +922,8 @@ static int tg3_ape_send_event(struct tg3 *tp, u32 event)  	if (!(apedata & APE_FW_STATUS_READY))  		return -EAGAIN; -	/* Wait for up to 1 millisecond for APE to service previous event. */ -	err = tg3_ape_event_lock(tp, 1000); +	/* Wait for up to 20 millisecond for APE to service previous event. */ +	err = tg3_ape_event_lock(tp, 20000);  	if (err)  		return err; @@ -946,6 +946,7 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)  	switch (kind) {  	case RESET_KIND_INIT: +		tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++);  		tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG,  				APE_HOST_SEG_SIG_MAGIC);  		tg3_ape_write32(tp, TG3_APE_HOST_SEG_LEN, @@ -962,13 +963,6 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)  		event = APE_EVENT_STATUS_STATE_START;  		break;  	case RESET_KIND_SHUTDOWN: -		/* With the interface we are currently using, -		 * APE does not track driver state.  Wiping -		 * out the HOST SEGMENT SIGNATURE forces -		 * the APE to assume OS absent status. -		 */ -		tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0); -  		if (device_may_wakeup(&tp->pdev->dev) &&  		    tg3_flag(tp, WOL_ENABLE)) {  			tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED, @@ -990,6 +984,18 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)  	tg3_ape_send_event(tp, event);  } +static void tg3_send_ape_heartbeat(struct tg3 *tp, +				   unsigned long interval) +{ +	/* Check if hb interval has exceeded */ +	if (!tg3_flag(tp, ENABLE_APE) || +	    time_before(jiffies, tp->ape_hb_jiffies + interval)) +		return; + +	tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_COUNT, tp->ape_hb++); +	tp->ape_hb_jiffies = jiffies; +} +  static void tg3_disable_ints(struct tg3 *tp)  {  	int i; @@ -7262,6 +7268,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget)  		}  	} +	tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1);  	return work_done;  tx_recovery: @@ -7344,6 +7351,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)  		}  	} +	tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL << 1);  	return work_done;  tx_recovery: @@ -10732,7 +10740,7 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)  	if (tg3_flag(tp, ENABLE_APE))  		/* Write our heartbeat update interval to APE. */  		tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS, -				APE_HOST_HEARTBEAT_INT_DISABLE); +				APE_HOST_HEARTBEAT_INT_5SEC);  	tg3_write_sig_post_reset(tp, RESET_KIND_INIT); @@ -11077,6 +11085,9 @@ static void tg3_timer(struct timer_list *t)  		tp->asf_counter = tp->asf_multiplier;  	} +	/* Update the APE heartbeat every 5 seconds.*/ +	tg3_send_ape_heartbeat(tp, TG3_APE_HB_INTERVAL); +  	spin_unlock(&tp->lock);  restart_timer: @@ -16653,6 +16664,8 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)  				       pci_state_reg);  		tg3_ape_lock_init(tp); +		tp->ape_hb_interval = +			msecs_to_jiffies(APE_HOST_HEARTBEAT_INT_5SEC);  	}  	/* Set up tp->grc_local_ctrl before calling  |