{
        struct rx_ring *rx_ring = container_of(napi, struct rx_ring, napi);
        struct ql_adapter *qdev = rx_ring->qdev;
-       int work_done = ql_clean_inbound_rx_ring(rx_ring, budget);
+       struct rx_ring *trx_ring;
+       int i, work_done = 0;
+       struct intr_context *ctx = &qdev->intr_context[rx_ring->cq_id];
 
        QPRINTK(qdev, RX_STATUS, DEBUG, "Enter, NAPI POLL cq_id = %d.\n",
                rx_ring->cq_id);
 
+       /* Service the TX rings first.  They start
+        * right after the RSS rings. */
+       for (i = qdev->rss_ring_count; i < qdev->rx_ring_count; i++) {
+               trx_ring = &qdev->rx_ring[i];
+               /* If this TX completion ring belongs to this vector and
+                * it's not empty then service it.
+                */
+               if ((ctx->irq_mask & (1 << trx_ring->cq_id)) &&
+                       (ql_read_sh_reg(trx_ring->prod_idx_sh_reg) !=
+                                       trx_ring->cnsmr_idx)) {
+                       QPRINTK(qdev, INTR, DEBUG,
+                               "%s: Servicing TX completion ring %d.\n",
+                               __func__, trx_ring->cq_id);
+                       ql_clean_outbound_rx_ring(trx_ring);
+               }
+       }
+
+       /*
+        * Now service the RSS ring if it's active.
+        */
+       if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) !=
+                                       rx_ring->cnsmr_idx) {
+               QPRINTK(qdev, INTR, DEBUG,
+                       "%s: Servicing RX completion ring %d.\n",
+                       __func__, rx_ring->cq_id);
+               work_done = ql_clean_inbound_rx_ring(rx_ring, budget);
+       }
+
        if (work_done < budget) {
                napi_complete(napi);
                ql_enable_completion_interrupt(qdev, rx_ring->irq);
 
 }
 
-/* Worker thread to process a given rx_ring that is dedicated
- * to outbound completions.
- */
-static void ql_tx_clean(struct work_struct *work)
-{
-       struct rx_ring *rx_ring =
-           container_of(work, struct rx_ring, rx_work.work);
-       ql_clean_outbound_rx_ring(rx_ring);
-       ql_enable_completion_interrupt(rx_ring->qdev, rx_ring->irq);
-
-}
-
-/* Worker thread to process a given rx_ring that is dedicated
- * to inbound completions.
- */
-static void ql_rx_clean(struct work_struct *work)
-{
-       struct rx_ring *rx_ring =
-           container_of(work, struct rx_ring, rx_work.work);
-       ql_clean_inbound_rx_ring(rx_ring, 64);
-       ql_enable_completion_interrupt(rx_ring->qdev, rx_ring->irq);
-}
-
-/* MSI-X Multiple Vector Interrupt Handler for outbound completions. */
-static irqreturn_t qlge_msix_tx_isr(int irq, void *dev_id)
-{
-       struct rx_ring *rx_ring = dev_id;
-       queue_delayed_work_on(rx_ring->cpu, rx_ring->qdev->q_workqueue,
-                             &rx_ring->rx_work, 0);
-       return IRQ_HANDLED;
-}
-
 /* MSI-X Multiple Vector Interrupt Handler for inbound completions. */
 static irqreturn_t qlge_msix_rx_isr(int irq, void *dev_id)
 {
        struct ql_adapter *qdev = rx_ring->qdev;
        struct intr_context *intr_context = &qdev->intr_context[0];
        u32 var;
-       int i;
        int work_done = 0;
 
        spin_lock(&qdev->hw_lock);
        }
 
        /*
-        * Check the default queue and wake handler if active.
+        * Get the bit-mask that shows the active queues for this
+        * pass.  Compare it to the queues that this irq services
+        * and call napi if there's a match.
         */
-       rx_ring = &qdev->rx_ring[0];
-       if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) {
-               QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[0].\n");
-               ql_disable_completion_interrupt(qdev, intr_context->intr);
-               queue_delayed_work_on(smp_processor_id(), qdev->q_workqueue,
-                                     &rx_ring->rx_work, 0);
-               work_done++;
-       }
-
-       if (!test_bit(QL_MSIX_ENABLED, &qdev->flags)) {
-               /*
-                * Start the DPC for each active queue.
-                */
-               for (i = 1; i < qdev->rx_ring_count; i++) {
-                       rx_ring = &qdev->rx_ring[i];
-                       if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) !=
-                           rx_ring->cnsmr_idx) {
+       var = ql_read32(qdev, ISR1);
+       if (var & intr_context->irq_mask) {
                                QPRINTK(qdev, INTR, INFO,
-                                       "Waking handler for rx_ring[%d].\n", i);
-                               ql_disable_completion_interrupt(qdev,
-                                                               intr_context->
-                                                               intr);
-                               if (i >= qdev->rss_ring_count)
-                                       queue_delayed_work_on(rx_ring->cpu,
-                                                             qdev->q_workqueue,
-                                                             &rx_ring->rx_work,
-                                                             0);
-                               else
+                       "Waking handler for rx_ring[0].\n");
+               ql_disable_completion_interrupt(qdev, intr_context->intr);
                                        napi_schedule(&rx_ring->napi);
                                work_done++;
                        }
-               }
-       }
        ql_enable_completion_interrupt(qdev, intr_context->intr);
        return work_done ? IRQ_HANDLED : IRQ_NONE;
 }
        }
        switch (rx_ring->type) {
        case TX_Q:
-               /* If there's only one interrupt, then we use
-                * worker threads to process the outbound
-                * completion handling rx_rings. We do this so
-                * they can be run on multiple CPUs. There is
-                * room to play with this more where we would only
-                * run in a worker if there are more than x number
-                * of outbound completions on the queue and more
-                * than one queue active.  Some threshold that
-                * would indicate a benefit in spite of the cost
-                * of a context switch.
-                * If there's more than one interrupt, then the
-                * outbound completions are processed in the ISR.
-                */
-               if (!test_bit(QL_MSIX_ENABLED, &qdev->flags))
-                       INIT_DELAYED_WORK(&rx_ring->rx_work, ql_tx_clean);
-               else {
-                       /* With all debug warnings on we see a WARN_ON message
-                        * when we free the skb in the interrupt context.
-                        */
-                       INIT_DELAYED_WORK(&rx_ring->rx_work, ql_tx_clean);
-               }
                cqicb->irq_delay = cpu_to_le16(qdev->tx_coalesce_usecs);
                cqicb->pkt_delay = cpu_to_le16(qdev->tx_max_coalesced_frames);
                break;
-       case DEFAULT_Q:
-               INIT_DELAYED_WORK(&rx_ring->rx_work, ql_rx_clean);
-               cqicb->irq_delay = 0;
-               cqicb->pkt_delay = 0;
-               break;
        case RX_Q:
                /* Inbound completion handling rx_rings run in
                 * separate NAPI contexts.
        QPRINTK(qdev, IFUP, DEBUG, "Running with legacy interrupts.\n");
 }
 
+/* Each vector services 1 RSS ring and and 1 or more
+ * TX completion rings.  This function loops through
+ * the TX completion rings and assigns the vector that
+ * will service it.  An example would be if there are
+ * 2 vectors (so 2 RSS rings) and 8 TX completion rings.
+ * This would mean that vector 0 would service RSS ring 0
+ * and TX competion rings 0,1,2 and 3.  Vector 1 would
+ * service RSS ring 1 and TX completion rings 4,5,6 and 7.
+ */
+static void ql_set_tx_vect(struct ql_adapter *qdev)
+{
+       int i, j, vect;
+       u32 tx_rings_per_vector = qdev->tx_ring_count / qdev->intr_count;
+
+       if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) {
+               /* Assign irq vectors to TX rx_rings.*/
+               for (vect = 0, j = 0, i = qdev->rss_ring_count;
+                                        i < qdev->rx_ring_count; i++) {
+                       if (j == tx_rings_per_vector) {
+                               vect++;
+                               j = 0;
+                       }
+                       qdev->rx_ring[i].irq = vect;
+                       j++;
+               }
+       } else {
+               /* For single vector all rings have an irq
+                * of zero.
+                */
+               for (i = 0; i < qdev->rx_ring_count; i++)
+                       qdev->rx_ring[i].irq = 0;
+       }
+}
+
+/* Set the interrupt mask for this vector.  Each vector
+ * will service 1 RSS ring and 1 or more TX completion
+ * rings.  This function sets up a bit mask per vector
+ * that indicates which rings it services.
+ */
+static void ql_set_irq_mask(struct ql_adapter *qdev, struct intr_context *ctx)
+{
+       int j, vect = ctx->intr;
+       u32 tx_rings_per_vector = qdev->tx_ring_count / qdev->intr_count;
+
+       if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) {
+               /* Add the RSS ring serviced by this vector
+                * to the mask.
+                */
+               ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id);
+               /* Add the TX ring(s) serviced by this vector
+                * to the mask. */
+               for (j = 0; j < tx_rings_per_vector; j++) {
+                       ctx->irq_mask |=
+                       (1 << qdev->rx_ring[qdev->rss_ring_count +
+                       (vect * tx_rings_per_vector) + j].cq_id);
+               }
+       } else {
+               /* For single vector we just shift each queue's
+                * ID into the mask.
+                */
+               for (j = 0; j < qdev->rx_ring_count; j++)
+                       ctx->irq_mask |= (1 << qdev->rx_ring[j].cq_id);
+       }
+}
+
 /*
  * Here we build the intr_context structures based on
  * our rx_ring count and intr vector count.
                /* Each rx_ring has it's
                 * own intr_context since we have separate
                 * vectors for each queue.
-                * This only true when MSI-X is enabled.
                 */
                for (i = 0; i < qdev->intr_count; i++, intr_context++) {
                        qdev->rx_ring[i].irq = i;
                        intr_context->intr = i;
                        intr_context->qdev = qdev;
+                       /* Set up this vector's bit-mask that indicates
+                        * which queues it services.
+                        */
+                       ql_set_irq_mask(qdev, intr_context);
                        /*
                         * We set up each vectors enable/disable/read bits so
                         * there's no bit/mask calculations in the critical path.
                            INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
                            INTR_EN_TYPE_READ | INTR_EN_IHD_MASK | INTR_EN_IHD |
                            i;
-
-                       if (i < qdev->rss_ring_count) {
-                               /*
-                                * Inbound queues handle unicast frames only.
+                       if (i == 0) {
+                               /* The first vector/queue handles
+                                * broadcast/multicast, fatal errors,
+                                * and firmware events.  This in addition
+                                * to normal inbound NAPI processing.
                                 */
-                               intr_context->handler = qlge_msix_rx_isr;
+                               intr_context->handler = qlge_isr;
                                sprintf(intr_context->name, "%s-rx-%d",
                                        qdev->ndev->name, i);
                        } else {
                                /*
-                                * Outbound queue is for outbound completions only.
+                                * Inbound queues handle unicast frames only.
                                 */
-                               intr_context->handler = qlge_msix_tx_isr;
-                               sprintf(intr_context->name, "%s-tx-%d",
+                               intr_context->handler = qlge_msix_rx_isr;
+                               sprintf(intr_context->name, "%s-rx-%d",
                                        qdev->ndev->name, i);
                        }
                }
                 */
                intr_context->handler = qlge_isr;
                sprintf(intr_context->name, "%s-single_irq", qdev->ndev->name);
-               for (i = 0; i < qdev->rx_ring_count; i++)
-                       qdev->rx_ring[i].irq = 0;
+               /* Set up this vector's bit-mask that indicates
+                * which queues it services. In this case there is
+                * a single vector so it will service all RSS and
+                * TX completion rings.
+                */
+               ql_set_irq_mask(qdev, intr_context);
        }
+       /* Tell the TX completion rings which MSIx vector
+        * they will be using.
+        */
+       ql_set_tx_vect(qdev);
 }
 
 static void ql_free_irq(struct ql_adapter *qdev)
 static int ql_adapter_down(struct ql_adapter *qdev)
 {
        int i, status = 0;
-       struct rx_ring *rx_ring;
 
        ql_link_off(qdev);
 
        cancel_delayed_work_sync(&qdev->mpi_idc_work);
        cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
 
-       /* The default queue at index 0 is always processed in
-        * a workqueue.
-        */
-       cancel_delayed_work_sync(&qdev->rx_ring[0].rx_work);
-
-       /* The rest of the rx_rings are processed in
-        * a workqueue only if it's a single interrupt
-        * environment (MSI/Legacy).
-        */
-       for (i = 1; i < qdev->rx_ring_count; i++) {
-               rx_ring = &qdev->rx_ring[i];
-               /* Only the RSS rings use NAPI on multi irq
-                * environment.  Outbound completion processing
-                * is done in interrupt context.
-                */
-               if (i <= qdev->rss_ring_count) {
-                       napi_disable(&rx_ring->napi);
-               } else {
-                       cancel_delayed_work_sync(&rx_ring->rx_work);
-               }
-       }
+       for (i = 0; i < qdev->rss_ring_count; i++)
+               napi_disable(&qdev->rx_ring[i].napi);
 
        clear_bit(QL_ADAPTER_UP, &qdev->flags);
 
 
                /*
                 * The completion queue ID for the tx rings start
-                * immediately after the default Q ID, which is zero.
+                * immediately after the rss rings.
                 */
-               tx_ring->cq_id = i + qdev->rss_ring_count;
+               tx_ring->cq_id = qdev->rss_ring_count + i;
        }
 
        for (i = 0; i < qdev->rx_ring_count; i++) {
                rx_ring->cq_id = i;
                rx_ring->cpu = i % cpu_cnt;     /* CPU to run handler on. */
                if (i < qdev->rss_ring_count) {
-                       /* Inbound completions (RSS) queues */
+                       /*
+                        * Inbound (RSS) queues.
+                        */
                        rx_ring->cq_len = qdev->rx_ring_size;
                        rx_ring->cq_size =
                            rx_ring->cq_len * sizeof(struct ql_net_rsp_iocb);
                destroy_workqueue(qdev->workqueue);
                qdev->workqueue = NULL;
        }
-       if (qdev->q_workqueue) {
-               destroy_workqueue(qdev->q_workqueue);
-               qdev->q_workqueue = NULL;
-       }
+
        if (qdev->reg_base)
                iounmap(qdev->reg_base);
        if (qdev->doorbell_area)
         * Set up the operating parameters.
         */
        qdev->rx_csum = 1;
-
-       qdev->q_workqueue = create_workqueue(ndev->name);
        qdev->workqueue = create_singlethread_workqueue(ndev->name);
        INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
        INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);