From owner-svn-src-stable@freebsd.org Fri Jun 17 09:01:13 2016 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 13CCCA7811A; Fri, 17 Jun 2016 09:01:13 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E056B14B7; Fri, 17 Jun 2016 09:01:12 +0000 (UTC) (envelope-from arybchik@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u5H91CI2011502; Fri, 17 Jun 2016 09:01:12 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u5H91Bm9011496; Fri, 17 Jun 2016 09:01:11 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201606170901.u5H91Bm9011496@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: arybchik set sender to arybchik@FreeBSD.org using -f From: Andrew Rybchenko Date: Fri, 17 Jun 2016 09:01:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r301984 - stable/10/sys/dev/sfxge/common X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Jun 2016 09:01:13 -0000 Author: arybchik Date: Fri Jun 17 09:01:11 2016 New Revision: 301984 URL: https://svnweb.freebsd.org/changeset/base/301984 Log: MFC r301308 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 Sponsored by: Solarflare Communications, Inc. Differential Revision: https://reviews.freebsd.org/D6704 Modified: stable/10/sys/dev/sfxge/common/ef10_ev.c stable/10/sys/dev/sfxge/common/efx.h stable/10/sys/dev/sfxge/common/efx_ev.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sfxge/common/ef10_ev.c ============================================================================== --- stable/10/sys/dev/sfxge/common/ef10_ev.c Fri Jun 17 08:59:08 2016 (r301983) +++ stable/10/sys/dev/sfxge/common/ef10_ev.c Fri Jun 17 09:01:11 2016 (r301984) @@ -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: stable/10/sys/dev/sfxge/common/efx.h ============================================================================== --- stable/10/sys/dev/sfxge/common/efx.h Fri Jun 17 08:59:08 2016 (r301983) +++ stable/10/sys/dev/sfxge/common/efx.h Fri Jun 17 09:01:11 2016 (r301984) @@ -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: stable/10/sys/dev/sfxge/common/efx_ev.c ============================================================================== --- stable/10/sys/dev/sfxge/common/efx_ev.c Fri Jun 17 08:59:08 2016 (r301983) +++ stable/10/sys/dev/sfxge/common/efx_ev.c Fri Jun 17 09:01:11 2016 (r301984) @@ -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);