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 <amoreton at solarflare.com>
  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);
 
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to