struct ixgbevf_q_vector *q_vector =
                container_of(napi, struct ixgbevf_q_vector, napi);
        struct ixgbevf_adapter *adapter = q_vector->adapter;
-       struct ixgbevf_ring *rx_ring = NULL;
        int work_done = 0;
-       long r_idx;
 
-       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-       rx_ring = &(adapter->rx_ring[r_idx]);
-
-       ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
+       ixgbevf_clean_rx_irq(q_vector, q_vector->rx.ring, &work_done, budget);
 
        /* If all Rx work done, exit the polling mode */
        if (work_done < budget) {
                if (adapter->itr_setting & 1)
                        ixgbevf_set_itr_msix(q_vector);
                if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
-                       ixgbevf_irq_enable_queues(adapter, rx_ring->v_idx);
+                       ixgbevf_irq_enable_queues(adapter,
+                                                 1 << q_vector->v_idx);
        }
 
        return work_done;
        struct ixgbevf_q_vector *q_vector =
                container_of(napi, struct ixgbevf_q_vector, napi);
        struct ixgbevf_adapter *adapter = q_vector->adapter;
-       struct ixgbevf_ring *rx_ring = NULL;
-       int work_done = 0, i;
-       long r_idx;
-       u64 enable_mask = 0;
+       struct ixgbevf_ring *rx_ring;
+       int work_done = 0;
 
        /* attempt to distribute budget to each queue fairly, but don't allow
         * the budget to go below 1 because we'll exit polling */
-       budget /= (q_vector->rxr_count ?: 1);
+       budget /= (q_vector->rx.count ?: 1);
        budget = max(budget, 1);
-       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-       for (i = 0; i < q_vector->rxr_count; i++) {
-               rx_ring = &(adapter->rx_ring[r_idx]);
-               ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
-               enable_mask |= rx_ring->v_idx;
-               r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
-                                     r_idx + 1);
-       }
 
-       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-       rx_ring = &(adapter->rx_ring[r_idx]);
+       ixgbevf_for_each_ring(rx_ring, q_vector->rx)
+               ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
 
        /* If all Rx work done, exit the polling mode */
        if (work_done < budget) {
                if (adapter->itr_setting & 1)
                        ixgbevf_set_itr_msix(q_vector);
                if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
-                       ixgbevf_irq_enable_queues(adapter, enable_mask);
+                       ixgbevf_irq_enable_queues(adapter,
+                                                 1 << q_vector->v_idx);
        }
 
        return work_done;
 {
        struct ixgbevf_q_vector *q_vector;
        struct ixgbe_hw *hw = &adapter->hw;
-       int i, j, q_vectors, v_idx, r_idx;
+       int q_vectors, v_idx;
        u32 mask;
 
        q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
         * corresponding register.
         */
        for (v_idx = 0; v_idx < q_vectors; v_idx++) {
+               struct ixgbevf_ring *ring;
                q_vector = adapter->q_vector[v_idx];
-               /* XXX for_each_set_bit(...) */
-               r_idx = find_first_bit(q_vector->rxr_idx,
-                                      adapter->num_rx_queues);
-
-               for (i = 0; i < q_vector->rxr_count; i++) {
-                       j = adapter->rx_ring[r_idx].reg_idx;
-                       ixgbevf_set_ivar(adapter, 0, j, v_idx);
-                       r_idx = find_next_bit(q_vector->rxr_idx,
-                                             adapter->num_rx_queues,
-                                             r_idx + 1);
-               }
-               r_idx = find_first_bit(q_vector->txr_idx,
-                                      adapter->num_tx_queues);
-
-               for (i = 0; i < q_vector->txr_count; i++) {
-                       j = adapter->tx_ring[r_idx].reg_idx;
-                       ixgbevf_set_ivar(adapter, 1, j, v_idx);
-                       r_idx = find_next_bit(q_vector->txr_idx,
-                                             adapter->num_tx_queues,
-                                             r_idx + 1);
-               }
+
+               ixgbevf_for_each_ring(ring, q_vector->rx)
+                       ixgbevf_set_ivar(adapter, 0, ring->reg_idx, v_idx);
+
+               ixgbevf_for_each_ring(ring, q_vector->tx)
+                       ixgbevf_set_ivar(adapter, 1, ring->reg_idx, v_idx);
 
                /* if this is a tx only vector halve the interrupt rate */
-               if (q_vector->txr_count && !q_vector->rxr_count)
+               if (q_vector->tx.ring && !q_vector->rx.ring)
                        q_vector->eitr = (adapter->eitr_param >> 1);
-               else if (q_vector->rxr_count)
+               else if (q_vector->rx.ring)
                        /* rx only */
                        q_vector->eitr = adapter->eitr_param;
 
        struct ixgbevf_adapter *adapter = q_vector->adapter;
        u32 new_itr;
        u8 current_itr, ret_itr;
-       int i, r_idx, v_idx = q_vector->v_idx;
+       int v_idx = q_vector->v_idx;
        struct ixgbevf_ring *rx_ring, *tx_ring;
 
-       r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
-       for (i = 0; i < q_vector->txr_count; i++) {
-               tx_ring = &(adapter->tx_ring[r_idx]);
+       ixgbevf_for_each_ring(tx_ring, q_vector->tx) {
                ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
-                                            q_vector->tx_itr,
+                                            q_vector->tx.itr,
                                             tx_ring->total_packets,
                                             tx_ring->total_bytes);
                /* if the result for this queue would decrease interrupt
                 * rate for this vector then use that result */
-               q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ?
-                                   q_vector->tx_itr - 1 : ret_itr);
-               r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
-                                     r_idx + 1);
+               q_vector->tx.itr = ((q_vector->tx.itr > ret_itr) ?
+                                   q_vector->tx.itr - 1 : ret_itr);
        }
 
-       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-       for (i = 0; i < q_vector->rxr_count; i++) {
-               rx_ring = &(adapter->rx_ring[r_idx]);
+       ixgbevf_for_each_ring(rx_ring, q_vector->rx) {
                ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
-                                            q_vector->rx_itr,
+                                            q_vector->rx.itr,
                                             rx_ring->total_packets,
                                             rx_ring->total_bytes);
                /* if the result for this queue would decrease interrupt
                 * rate for this vector then use that result */
-               q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ?
-                                   q_vector->rx_itr - 1 : ret_itr);
-               r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
-                                     r_idx + 1);
+               q_vector->rx.itr = ((q_vector->rx.itr > ret_itr) ?
+                                   q_vector->rx.itr - 1 : ret_itr);
        }
 
-       current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
+       current_itr = max(q_vector->rx.itr, q_vector->tx.itr);
 
        switch (current_itr) {
        /* counts and packets in update_itr are dependent on these numbers */
        struct ixgbevf_q_vector *q_vector = data;
        struct ixgbevf_adapter  *adapter = q_vector->adapter;
        struct ixgbevf_ring     *tx_ring;
-       int i, r_idx;
 
-       if (!q_vector->txr_count)
+       if (!q_vector->tx.ring)
                return IRQ_HANDLED;
 
-       r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
-       for (i = 0; i < q_vector->txr_count; i++) {
-               tx_ring = &(adapter->tx_ring[r_idx]);
+       ixgbevf_for_each_ring(tx_ring, q_vector->tx) {
                tx_ring->total_bytes = 0;
                tx_ring->total_packets = 0;
                ixgbevf_clean_tx_irq(adapter, tx_ring);
-               r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
-                                     r_idx + 1);
        }
 
        if (adapter->itr_setting & 1)
        struct ixgbevf_adapter  *adapter = q_vector->adapter;
        struct ixgbe_hw *hw = &adapter->hw;
        struct ixgbevf_ring  *rx_ring;
-       int r_idx;
-       int i;
 
-       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-       for (i = 0; i < q_vector->rxr_count; i++) {
-               rx_ring = &(adapter->rx_ring[r_idx]);
+       ixgbevf_for_each_ring(rx_ring, q_vector->rx) {
                rx_ring->total_bytes = 0;
                rx_ring->total_packets = 0;
-               r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
-                                     r_idx + 1);
        }
 
-       if (!q_vector->rxr_count)
+       if (!q_vector->rx.ring)
                return IRQ_HANDLED;
 
-       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-       rx_ring = &(adapter->rx_ring[r_idx]);
        /* disable interrupts on this vector only */
-       IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, rx_ring->v_idx);
+       IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, 1 << q_vector->v_idx);
        napi_schedule(&q_vector->napi);
 
 
 {
        struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
 
-       set_bit(r_idx, q_vector->rxr_idx);
-       q_vector->rxr_count++;
+       a->rx_ring[r_idx].next = q_vector->rx.ring;
+       q_vector->rx.ring = &a->rx_ring[r_idx];
+       q_vector->rx.count++;
        a->rx_ring[r_idx].v_idx = 1 << v_idx;
 }
 
 {
        struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
 
-       set_bit(t_idx, q_vector->txr_idx);
-       q_vector->txr_count++;
+       a->tx_ring[t_idx].next = q_vector->tx.ring;
+       q_vector->tx.ring = &a->tx_ring[t_idx];
+       q_vector->tx.count++;
        a->tx_ring[t_idx].v_idx = 1 << v_idx;
 }
 
        /* Decrement for Other and TCP Timer vectors */
        q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
 
-#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count)          \
-                                         ? &ixgbevf_msix_clean_many : \
-                         (_v)->rxr_count ? &ixgbevf_msix_clean_rx   : \
-                         (_v)->txr_count ? &ixgbevf_msix_clean_tx   : \
+#define SET_HANDLER(_v) (((_v)->rx.ring && (_v)->tx.ring)          \
+                                       ? &ixgbevf_msix_clean_many : \
+                         (_v)->rx.ring ? &ixgbevf_msix_clean_rx   : \
+                         (_v)->tx.ring ? &ixgbevf_msix_clean_tx   : \
                          NULL)
        for (vector = 0; vector < q_vectors; vector++) {
                handler = SET_HANDLER(adapter->q_vector[vector]);
 
        for (i = 0; i < q_vectors; i++) {
                struct ixgbevf_q_vector *q_vector = adapter->q_vector[i];
-               bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES);
-               bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES);
-               q_vector->rxr_count = 0;
-               q_vector->txr_count = 0;
+               q_vector->rx.ring = NULL;
+               q_vector->tx.ring = NULL;
+               q_vector->rx.count = 0;
+               q_vector->tx.count = 0;
                q_vector->eitr = adapter->eitr_param;
        }
 }
        for (q_idx = 0; q_idx < q_vectors; q_idx++) {
                struct napi_struct *napi;
                q_vector = adapter->q_vector[q_idx];
-               if (!q_vector->rxr_count)
+               if (!q_vector->rx.ring)
                        continue;
                napi = &q_vector->napi;
-               if (q_vector->rxr_count > 1)
+               if (q_vector->rx.count > 1)
                        napi->poll = &ixgbevf_clean_rxonly_many;
 
                napi_enable(napi);
 
        for (q_idx = 0; q_idx < q_vectors; q_idx++) {
                q_vector = adapter->q_vector[q_idx];
-               if (!q_vector->rxr_count)
+               if (!q_vector->rx.ring)
                        continue;
                napi_disable(&q_vector->napi);
        }
        /* get one bit for every active tx/rx interrupt vector */
        for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
                struct ixgbevf_q_vector *qv = adapter->q_vector[i];
-               if (qv->rxr_count || qv->txr_count)
+               if (qv->rx.ring || qv->tx.ring)
                        eics |= (1 << i);
        }