struct ravb_private *priv = netdev_priv(ndev);
        const struct ravb_hw_info *info = priv->info;
        int entry = priv->cur_rx[q] % priv->num_rx_ring[q];
-       int boguscnt = (priv->dirty_rx[q] + priv->num_rx_ring[q]) -
-                       priv->cur_rx[q];
        struct net_device_stats *stats = &priv->stats[q];
        struct ravb_ex_rx_desc *desc;
+       unsigned int limit, i;
        struct sk_buff *skb;
        dma_addr_t dma_addr;
        struct timespec64 ts;
+       int rx_packets = 0;
        u8  desc_status;
        u16 pkt_len;
-       int limit;
 
-       boguscnt = min(boguscnt, *quota);
-       limit = boguscnt;
+       limit = priv->dirty_rx[q] + priv->num_rx_ring[q] - priv->cur_rx[q];
        desc = &priv->rx_ring[q].ex_desc[entry];
-       while (desc->die_dt != DT_FEMPTY) {
+       for (i = 0; i < limit && rx_packets < *quota && desc->die_dt != DT_FEMPTY; i++) {
                /* Descriptor type must be checked before all other reads */
                dma_rmb();
                desc_status = desc->msc;
                pkt_len = le16_to_cpu(desc->ds_cc) & RX_DS;
 
-               if (--boguscnt < 0)
-                       break;
-
                /* We use 0-byte descriptors to mark the DMA mapping errors */
                if (!pkt_len)
                        continue;
                        if (ndev->features & NETIF_F_RXCSUM)
                                ravb_rx_csum(skb);
                        napi_gro_receive(&priv->napi[q], skb);
-                       stats->rx_packets++;
+                       rx_packets++;
                        stats->rx_bytes += pkt_len;
                }
 
                desc->die_dt = DT_FEMPTY;
        }
 
-       *quota -= limit - (++boguscnt);
-
-       return boguscnt <= 0;
+       stats->rx_packets += rx_packets;
+       *quota -= rx_packets;
+       return *quota == 0;
 }
 
 /* Packet receive function for Ethernet AVB */