enum i40e_latency_range new_latency_range = rc->latency_range;
        u32 new_itr = rc->itr;
        int bytes_per_int;
-       int usecs;
+       unsigned int usecs, estimated_usecs;
 
        if (rc->total_packets == 0 || !rc->itr)
                return false;
 
+       usecs = (rc->itr << 1) * ITR_COUNTDOWN_START;
+       bytes_per_int = rc->total_bytes / usecs;
+
+       /* The calculations in this algorithm depend on interrupts actually
+        * firing at the ITR rate. This may not happen if the packet rate is
+        * really low, or if we've been napi polling. Check to make sure
+        * that's not the case before we continue.
+        */
+       estimated_usecs = jiffies_to_usecs(jiffies - rc->last_itr_update);
+       if (estimated_usecs > usecs) {
+               new_latency_range = I40E_LOW_LATENCY;
+               goto reset_latency;
+       }
+
        /* simple throttlerate management
         *   0-10MB/s   lowest (50000 ints/s)
         *  10-20MB/s   low    (20000 ints/s)
         * are in 2 usec increments in the ITR registers, and make sure
         * to use the smoothed values that the countdown timer gives us.
         */
-       usecs = (rc->itr << 1) * ITR_COUNTDOWN_START;
-       bytes_per_int = rc->total_bytes / usecs;
-
        switch (new_latency_range) {
        case I40E_LOWEST_LATENCY:
                if (bytes_per_int > 10)
                break;
        }
 
+reset_latency:
        rc->latency_range = new_latency_range;
 
        switch (new_latency_range) {
 
        rc->total_bytes = 0;
        rc->total_packets = 0;
+       rc->last_itr_update = jiffies;
 
        if (new_itr != rc->itr) {
                rc->itr = new_itr;
                return true;
        }
-
        return false;
 }
 
 
        struct i40e_ring *ring;
        unsigned int total_bytes;       /* total bytes processed this int */
        unsigned int total_packets;     /* total packets processed this int */
+       unsigned long last_itr_update;  /* jiffies of last ITR update */
        u16 count;
        enum i40e_latency_range latency_range;
        u16 itr;
 
        enum i40e_latency_range new_latency_range = rc->latency_range;
        u32 new_itr = rc->itr;
        int bytes_per_int;
-       int usecs;
+       unsigned int usecs, estimated_usecs;
 
        if (rc->total_packets == 0 || !rc->itr)
                return false;
 
+       usecs = (rc->itr << 1) * ITR_COUNTDOWN_START;
+       bytes_per_int = rc->total_bytes / usecs;
+
+       /* The calculations in this algorithm depend on interrupts actually
+        * firing at the ITR rate. This may not happen if the packet rate is
+        * really low, or if we've been napi polling. Check to make sure
+        * that's not the case before we continue.
+        */
+       estimated_usecs = jiffies_to_usecs(jiffies - rc->last_itr_update);
+       if (estimated_usecs > usecs) {
+               new_latency_range = I40E_LOW_LATENCY;
+               goto reset_latency;
+       }
+
        /* simple throttlerate management
         *   0-10MB/s   lowest (50000 ints/s)
         *  10-20MB/s   low    (20000 ints/s)
         * are in 2 usec increments in the ITR registers, and make sure
         * to use the smoothed values that the countdown timer gives us.
         */
-       usecs = (rc->itr << 1) * ITR_COUNTDOWN_START;
-       bytes_per_int = rc->total_bytes / usecs;
-
        switch (new_latency_range) {
        case I40E_LOWEST_LATENCY:
                if (bytes_per_int > 10)
                break;
        }
 
+reset_latency:
        rc->latency_range = new_latency_range;
 
        switch (new_latency_range) {
 
        rc->total_bytes = 0;
        rc->total_packets = 0;
+       rc->last_itr_update = jiffies;
 
        if (new_itr != rc->itr) {
                rc->itr = new_itr;
                return true;
        }
-
        return false;
 }
 
 
        struct i40e_ring *ring;
        unsigned int total_bytes;       /* total bytes processed this int */
        unsigned int total_packets;     /* total packets processed this int */
+       unsigned long last_itr_update;  /* jiffies of last ITR update */
        u16 count;
        enum i40e_latency_range latency_range;
        u16 itr;