cq->mcq.comp  = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq;
        cq->mcq.event = mlx4_en_cq_event;
 
-       if (!cq->is_tx) {
+       if (cq->is_tx) {
+               netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_tx_cq,
+                              NAPI_POLL_WEIGHT);
+       } else {
                netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64);
                napi_hash_add(&cq->napi);
-               napi_enable(&cq->napi);
        }
 
+       napi_enable(&cq->napi);
+
        return 0;
 }
 
 
 void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
 {
+       napi_disable(&cq->napi);
        if (!cq->is_tx) {
-               napi_disable(&cq->napi);
                napi_hash_del(&cq->napi);
                synchronize_rcu();
-               netif_napi_del(&cq->napi);
        }
+       netif_napi_del(&cq->napi);
 
        mlx4_cq_free(priv->mdev->dev, &cq->mcq);
 }
 
                        }
                }
        }
-       dev_kfree_skb_any(skb);
+       dev_kfree_skb(skb);
        return tx_info->nr_txbb;
 }
 
        return cnt;
 }
 
-static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
+static int mlx4_en_process_tx_cq(struct net_device *dev,
+                                struct mlx4_en_cq *cq,
+                                int budget)
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_cq *mcq = &cq->mcq;
        u32 bytes = 0;
        int factor = priv->cqe_factor;
        u64 timestamp = 0;
+       int done = 0;
 
        if (!priv->port_up)
-               return;
+               return 0;
 
        index = cons_index & size_mask;
        cqe = &buf[(index << factor) + factor];
 
        /* Process all completed CQEs */
        while (XNOR(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK,
-                       cons_index & size)) {
+                       cons_index & size) && (done < budget)) {
                /*
                 * make sure we read the CQE after we read the
                 * ownership bit
                        txbbs_stamp = txbbs_skipped;
                        packets++;
                        bytes += ring->tx_info[ring_index].nr_bytes;
-               } while (ring_index != new_index);
+               } while ((++done < budget) && (ring_index != new_index));
 
                ++cons_index;
                index = cons_index & size_mask;
                netif_tx_wake_queue(ring->tx_queue);
                priv->port_stats.wake_queue++;
        }
+       return done;
 }
 
 void mlx4_en_tx_irq(struct mlx4_cq *mcq)
        struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq);
        struct mlx4_en_priv *priv = netdev_priv(cq->dev);
 
-       mlx4_en_process_tx_cq(cq->dev, cq);
-       mlx4_en_arm_cq(priv, cq);
+       if (priv->port_up)
+               napi_schedule(&cq->napi);
+       else
+               mlx4_en_arm_cq(priv, cq);
 }
 
+/* TX CQ polling - called by NAPI */
+int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget)
+{
+       struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi);
+       struct net_device *dev = cq->dev;
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int done;
+
+       done = mlx4_en_process_tx_cq(dev, cq, budget);
+
+       /* If we used up all the quota - we're probably not done yet... */
+       if (done < budget) {
+               /* Done for now */
+               napi_complete(napi);
+               mlx4_en_arm_cq(priv, cq);
+               return done;
+       }
+       return budget;
+}
 
 static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv,
                                                      struct mlx4_en_tx_ring *ring,
 
                          struct mlx4_en_cq *cq,
                          int budget);
 int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
+int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget);
 void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
                int is_tx, int rss, int qpn, int cqn, int user_prio,
                struct mlx4_qp_context *context);