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>