if (channel->used_flags & EFX_USED_BY_RX &&
                    efx->irq_rx_adaptive &&
                    unlikely(++channel->irq_count == 1000)) {
-                       unsigned old_irq_moderation = channel->irq_moderation;
-
                        if (unlikely(channel->irq_mod_score <
                                     irq_adapt_low_thresh)) {
-                               channel->irq_moderation =
-                                       max_t(int,
-                                             channel->irq_moderation -
-                                             FALCON_IRQ_MOD_RESOLUTION,
-                                             FALCON_IRQ_MOD_RESOLUTION);
+                               if (channel->irq_moderation > 1) {
+                                       channel->irq_moderation -= 1;
+                                       falcon_set_int_moderation(channel);
+                               }
                        } else if (unlikely(channel->irq_mod_score >
                                            irq_adapt_high_thresh)) {
-                               channel->irq_moderation =
-                                       min(channel->irq_moderation +
-                                           FALCON_IRQ_MOD_RESOLUTION,
-                                           efx->irq_rx_moderation);
+                               if (channel->irq_moderation <
+                                   efx->irq_rx_moderation) {
+                                       channel->irq_moderation += 1;
+                                       falcon_set_int_moderation(channel);
+                               }
                        }
-
-                       if (channel->irq_moderation != old_irq_moderation)
-                               falcon_set_int_moderation(channel);
-
                        channel->irq_count = 0;
                        channel->irq_mod_score = 0;
                }
  *
  **************************************************************************/
 
+static unsigned irq_mod_ticks(int usecs, int resolution)
+{
+       if (usecs <= 0)
+               return 0; /* cannot receive interrupts ahead of time :-) */
+       if (usecs < resolution)
+               return 1; /* never round down to 0 */
+       return usecs / resolution;
+}
+
 /* Set interrupt moderation parameters */
 void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
                             bool rx_adaptive)
 {
        struct efx_tx_queue *tx_queue;
        struct efx_rx_queue *rx_queue;
+       unsigned tx_ticks = irq_mod_ticks(tx_usecs, FALCON_IRQ_MOD_RESOLUTION);
+       unsigned rx_ticks = irq_mod_ticks(rx_usecs, FALCON_IRQ_MOD_RESOLUTION);
 
        EFX_ASSERT_RESET_SERIALISED(efx);
 
        efx_for_each_tx_queue(tx_queue, efx)
-               tx_queue->channel->irq_moderation = tx_usecs;
+               tx_queue->channel->irq_moderation = tx_ticks;
 
        efx->irq_rx_adaptive = rx_adaptive;
-       efx->irq_rx_moderation = rx_usecs;
+       efx->irq_rx_moderation = rx_ticks;
        efx_for_each_rx_queue(rx_queue, efx)
-               rx_queue->channel->irq_moderation = rx_usecs;
+               rx_queue->channel->irq_moderation = rx_ticks;
 }
 
 /**************************************************************************
 
        coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive;
        coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation;
 
+       coalesce->tx_coalesce_usecs_irq *= FALCON_IRQ_MOD_RESOLUTION;
+       coalesce->rx_coalesce_usecs_irq *= FALCON_IRQ_MOD_RESOLUTION;
+
        return 0;
 }
 
        }
 
        efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive);
-
-       /* Reset channel to pick up new moderation value.  Note that
-        * this may change the value of the irq_moderation field
-        * (e.g. to allow for hardware timer granularity).
-        */
        efx_for_each_channel(channel, efx)
                falcon_set_int_moderation(channel);
 
 
 
        /* Set timer register */
        if (channel->irq_moderation) {
-               /* Round to resolution supported by hardware.  The value we
-                * program is based at 0.  So actual interrupt moderation
-                * achieved is ((x + 1) * res).
-                */
-               channel->irq_moderation -= (channel->irq_moderation %
-                                           FALCON_IRQ_MOD_RESOLUTION);
-               if (channel->irq_moderation < FALCON_IRQ_MOD_RESOLUTION)
-                       channel->irq_moderation = FALCON_IRQ_MOD_RESOLUTION;
                EFX_POPULATE_DWORD_2(timer_cmd,
                                     FRF_AB_TC_TIMER_MODE,
                                     FFE_BB_TIMER_MODE_INT_HLDOFF,
                                     FRF_AB_TC_TIMER_VAL,
-                                    channel->irq_moderation /
-                                    FALCON_IRQ_MOD_RESOLUTION - 1);
+                                    channel->irq_moderation - 1);
        } else {
                EFX_POPULATE_DWORD_2(timer_cmd,
                                     FRF_AB_TC_TIMER_MODE,