Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 Jun 2016 09:17:45 +0000 (UTC)
From:      Andrew Rybchenko <arybchik@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r301308 - head/sys/dev/sfxge/common
Message-ID:  <201606040917.u549Hjbc072002@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: arybchik
Date: Sat Jun  4 09:17:45 2016
New Revision: 301308
URL: https://svnweb.freebsd.org/changeset/base/301308

Log:
  sfxge(4): add helper to compute timer quantum
  
  This also adjusts the timer values used to match the Linux net
  driver implementation:
  a) non-zero time intervals should result in at least one quantum
  b) timer load/reload values are only zero biased for Falcon/Siena
  
  Submitted by:   Andy Moreton <amoreton at solarflare.com>
  Sponsored by:   Solarflare Communications, Inc.
  MFC after:      1 week
  Differential Revision:  https://reviews.freebsd.org/D6704

Modified:
  head/sys/dev/sfxge/common/ef10_ev.c
  head/sys/dev/sfxge/common/efx.h
  head/sys/dev/sfxge/common/efx_ev.c

Modified: head/sys/dev/sfxge/common/ef10_ev.c
==============================================================================
--- head/sys/dev/sfxge/common/ef10_ev.c	Sat Jun  4 08:56:30 2016	(r301307)
+++ head/sys/dev/sfxge/common/ef10_ev.c	Sat Jun  4 09:17:45 2016	(r301308)
@@ -141,7 +141,6 @@ efx_mcdi_init_evq(
 	__in		uint32_t irq,
 	__in		uint32_t us)
 {
-	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_mcdi_req_t req;
 	uint8_t payload[
 	    MAX(MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
@@ -189,25 +188,22 @@ efx_mcdi_init_evq(
 	    INIT_EVQ_IN_FLAG_RX_MERGE, 1,
 	    INIT_EVQ_IN_FLAG_TX_MERGE, 1);
 
+	/* If the value is zero then disable the timer */
 	if (us == 0) {
 		MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_MODE,
 		    MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS);
 		MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_LOAD, 0);
 		MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_RELOAD, 0);
 	} else {
-		uint32_t timer_val;
+		unsigned int ticks;
 
-		/* Calculate the timer value in quanta */
-		timer_val = us * 1000 / encp->enc_evq_timer_quantum_ns;
-
-		/* Moderation value is base 0 so we need to deduct 1 */
-		if (timer_val > 0)
-			timer_val--;
+		if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
+			goto fail2;
 
 		MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_MODE,
 		    MC_CMD_INIT_EVQ_IN_TMR_INT_HLDOFF);
-		MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_LOAD, timer_val);
-		MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_RELOAD, timer_val);
+		MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_LOAD, ticks);
+		MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_RELOAD, ticks);
 	}
 
 	MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_MODE,
@@ -230,18 +226,20 @@ efx_mcdi_init_evq(
 
 	if (req.emr_rc != 0) {
 		rc = req.emr_rc;
-		goto fail2;
+		goto fail3;
 	}
 
 	if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN) {
 		rc = EMSGSIZE;
-		goto fail3;
+		goto fail4;
 	}
 
 	/* NOTE: ignore the returned IRQ param as firmware does not set it. */
 
 	return (0);
 
+fail4:
+	EFSYS_PROBE(fail4);
 fail3:
 	EFSYS_PROBE(fail3);
 fail2:
@@ -483,7 +481,7 @@ ef10_ev_qmoderate(
 	efx_nic_t *enp = eep->ee_enp;
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_dword_t dword;
-	uint32_t timer_ns, timer_val, mode;
+	uint32_t mode;
 	efx_rc_t rc;
 
 	/* Check that hardware and MCDI use the same timer MODE values */
@@ -503,37 +501,35 @@ ef10_ev_qmoderate(
 
 	/* If the value is zero then disable the timer */
 	if (us == 0) {
-		timer_ns = 0;
 		mode = FFE_CZ_TIMER_MODE_DIS;
 	} else {
-		timer_ns = us * 1000u;
 		mode = FFE_CZ_TIMER_MODE_INT_HLDOFF;
 	}
 
 	if (encp->enc_bug61265_workaround) {
-		rc = efx_mcdi_set_evq_tmr(enp, eep->ee_index, mode, timer_ns);
+		uint32_t ns = us * 1000;
+
+		rc = efx_mcdi_set_evq_tmr(enp, eep->ee_index, mode, ns);
 		if (rc != 0)
 			goto fail2;
 	} else {
-		/* Calculate the timer value in quanta */
-		timer_val = timer_ns / encp->enc_evq_timer_quantum_ns;
+		unsigned int ticks;
 
-		/* Moderation value is base 0 so we need to deduct 1 */
-		if (timer_val > 0)
-			timer_val--;
+		if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
+			goto fail3;
 
 		if (encp->enc_bug35388_workaround) {
 			EFX_POPULATE_DWORD_3(dword,
 			    ERF_DD_EVQ_IND_TIMER_FLAGS,
 			    EFE_DD_EVQ_IND_TIMER_FLAGS,
 			    ERF_DD_EVQ_IND_TIMER_MODE, mode,
-			    ERF_DD_EVQ_IND_TIMER_VAL, timer_val);
+			    ERF_DD_EVQ_IND_TIMER_VAL, ticks);
 			EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT,
 			    eep->ee_index, &dword, 0);
 		} else {
 			EFX_POPULATE_DWORD_2(dword,
 			    ERF_DZ_TC_TIMER_MODE, mode,
-			    ERF_DZ_TC_TIMER_VAL, timer_val);
+			    ERF_DZ_TC_TIMER_VAL, ticks);
 			EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_TMR_REG,
 			    eep->ee_index, &dword, 0);
 		}
@@ -541,6 +537,8 @@ ef10_ev_qmoderate(
 
 	return (0);
 
+fail3:
+	EFSYS_PROBE(fail3);
 fail2:
 	EFSYS_PROBE(fail2);
 fail1:

Modified: head/sys/dev/sfxge/common/efx.h
==============================================================================
--- head/sys/dev/sfxge/common/efx.h	Sat Jun  4 08:56:30 2016	(r301307)
+++ head/sys/dev/sfxge/common/efx.h	Sat Jun  4 09:17:45 2016	(r301308)
@@ -1773,6 +1773,12 @@ efx_ev_qpoll(
 	__in_opt	void *arg);
 
 extern	__checkReturn	efx_rc_t
+efx_ev_usecs_to_ticks(
+	__in		efx_nic_t *enp,
+	__in		unsigned int usecs,
+	__out		unsigned int *ticksp);
+
+extern	__checkReturn	efx_rc_t
 efx_ev_qmoderate(
 	__in		efx_evq_t *eep,
 	__in		unsigned int us);

Modified: head/sys/dev/sfxge/common/efx_ev.c
==============================================================================
--- head/sys/dev/sfxge/common/efx_ev.c	Sat Jun  4 08:56:30 2016	(r301307)
+++ head/sys/dev/sfxge/common/efx_ev.c	Sat Jun  4 09:17:45 2016	(r301308)
@@ -406,6 +406,27 @@ efx_ev_qpost(
 }
 
 	__checkReturn	efx_rc_t
+efx_ev_usecs_to_ticks(
+	__in		efx_nic_t *enp,
+	__in		unsigned int us,
+	__out		unsigned int *ticksp)
+{
+	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+	unsigned int ticks;
+
+	/* Convert microseconds to a timer tick count */
+	if (us == 0)
+		ticks = 0;
+	else if (us * 1000 < encp->enc_evq_timer_quantum_ns)
+		ticks = 1;	/* Never round down to zero */
+	else
+		ticks = us * 1000 / encp->enc_evq_timer_quantum_ns;
+
+	*ticksp = ticks;
+	return (0);
+}
+
+	__checkReturn	efx_rc_t
 efx_ev_qmoderate(
 	__in		efx_evq_t *eep,
 	__in		unsigned int us)
@@ -1224,18 +1245,15 @@ siena_ev_qmoderate(
 		    FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS,
 		    FRF_CZ_TC_TIMER_VAL, 0);
 	} else {
-		uint32_t timer_val;
+		unsigned int ticks;
 
-		/* Calculate the timer value in quanta */
-		timer_val = us * 1000 / encp->enc_evq_timer_quantum_ns;
-
-		/* Moderation value is base 0 so we need to deduct 1 */
-		if (timer_val > 0)
-			timer_val--;
+		if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
+			goto fail2;
 
+		EFSYS_ASSERT(ticks > 0);
 		EFX_POPULATE_DWORD_2(dword,
 		    FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_INT_HLDOFF,
-		    FRF_CZ_TC_TIMER_VAL, timer_val);
+		    FRF_CZ_TC_TIMER_VAL, ticks - 1);
 	}
 
 	locked = (eep->ee_index == 0) ? 1 : 0;
@@ -1245,6 +1263,8 @@ siena_ev_qmoderate(
 
 	return (0);
 
+fail2:
+	EFSYS_PROBE(fail2);
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606040917.u549Hjbc072002>