diff options
Diffstat (limited to 'drivers/net/ethernet/sfc/mcdi.c')
| -rw-r--r-- | drivers/net/ethernet/sfc/mcdi.c | 23 | 
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index aea43cbd052..0095ce95150 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -22,7 +22,7 @@   **************************************************************************   */ -#define MCDI_RPC_TIMEOUT       10 /*seconds */ +#define MCDI_RPC_TIMEOUT       (10 * HZ)  #define MCDI_PDU(efx)							\  	(efx_port_num(efx) ? MC_SMEM_P1_PDU_OFST : MC_SMEM_P0_PDU_OFST) @@ -120,7 +120,7 @@ static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen)  static int efx_mcdi_poll(struct efx_nic *efx)  {  	struct efx_mcdi_iface *mcdi = efx_mcdi(efx); -	unsigned int time, finish; +	unsigned long time, finish;  	unsigned int respseq, respcmd, error;  	unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);  	unsigned int rc, spins; @@ -136,7 +136,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)  	 * and poll once a jiffy (approximately)  	 */  	spins = TICK_USEC; -	finish = get_seconds() + MCDI_RPC_TIMEOUT; +	finish = jiffies + MCDI_RPC_TIMEOUT;  	while (1) {  		if (spins != 0) { @@ -146,7 +146,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)  			schedule_timeout_uninterruptible(1);  		} -		time = get_seconds(); +		time = jiffies;  		rmb();  		efx_readd(efx, ®, pdu); @@ -158,7 +158,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)  		    EFX_DWORD_FIELD(reg, MCDI_HEADER_RESPONSE))  			break; -		if (time >= finish) +		if (time_after(time, finish))  			return -ETIMEDOUT;  	} @@ -207,7 +207,9 @@ out:  	return 0;  } -/* Test and clear MC-rebooted flag for this port/function */ +/* Test and clear MC-rebooted flag for this port/function; reset + * software state as necessary. + */  int efx_mcdi_poll_reboot(struct efx_nic *efx)  {  	unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_STATUS(efx); @@ -223,6 +225,11 @@ int efx_mcdi_poll_reboot(struct efx_nic *efx)  	if (value == 0)  		return 0; +	/* MAC statistics have been cleared on the NIC; clear our copy +	 * so that efx_update_diff_stat() can continue to work. +	 */ +	memset(&efx->mac_stats, 0, sizeof(efx->mac_stats)); +  	EFX_ZERO_DWORD(reg);  	efx_writed(efx, ®, addr); @@ -250,7 +257,7 @@ static int efx_mcdi_await_completion(struct efx_nic *efx)  	if (wait_event_timeout(  		    mcdi->wq,  		    atomic_read(&mcdi->state) == MCDI_STATE_COMPLETED, -		    msecs_to_jiffies(MCDI_RPC_TIMEOUT * 1000)) == 0) +		    MCDI_RPC_TIMEOUT) == 0)  		return -ETIMEDOUT;  	/* Check if efx_mcdi_set_mode() switched us back to polled completions. @@ -1216,7 +1223,7 @@ int efx_mcdi_flush_rxqs(struct efx_nic *efx)  	rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, (u8 *)qid,  			  count * sizeof(*qid), NULL, 0, NULL); -	WARN_ON(rc > 0); +	WARN_ON(rc < 0);  	kfree(qid);  |