Index: head/sys/dev/sfxge/common/ef10_ev.c =================================================================== --- head/sys/dev/sfxge/common/ef10_ev.c +++ head/sys/dev/sfxge/common/ef10_ev.c @@ -141,7 +141,6 @@ __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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ return (0); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: Index: head/sys/dev/sfxge/common/efx.h =================================================================== --- head/sys/dev/sfxge/common/efx.h +++ head/sys/dev/sfxge/common/efx.h @@ -1773,6 +1773,12 @@ __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); Index: head/sys/dev/sfxge/common/efx_ev.c =================================================================== --- head/sys/dev/sfxge/common/efx_ev.c +++ head/sys/dev/sfxge/common/efx_ev.c @@ -406,6 +406,27 @@ } __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 @@ 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 @@ return (0); +fail2: + EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc);