struct efx_rx_queue *rx_queue;
        int i;
 
-       /* TX queues.  One per port per channel with TX capability
-        * (more than one per port won't work on Linux, due to out
-        *  of order issues... but will be fine on Solaris)
-        */
-       tx_queue = &efx->tx_queue[0];
-
-       /* Perform this for each channel with TX capabilities.
-        * At the moment, we only support a single TX queue
-        */
-       tx_queue->used = 1;
-       if ((!EFX_INT_MODE_USE_MSI(efx)) && separate_tx_and_rx_channels)
-               tx_queue->channel = &efx->channel[1];
-       else
-               tx_queue->channel = &efx->channel[0];
-       tx_queue->channel->used_flags |= EFX_USED_BY_TX;
-       tx_queue++;
+       efx_for_each_tx_queue(tx_queue, efx) {
+               if (!EFX_INT_MODE_USE_MSI(efx) && separate_tx_and_rx_channels)
+                       tx_queue->channel = &efx->channel[1];
+               else
+                       tx_queue->channel = &efx->channel[0];
+               tx_queue->channel->used_flags |= EFX_USED_BY_TX;
+       }
 
        /* RX queues.  Each has a dedicated channel. */
        for (i = 0; i < EFX_MAX_RX_QUEUES; i++) {
                channel->evqnum = i;
                channel->work_pending = 0;
        }
-       for (i = 0; i < EFX_MAX_TX_QUEUES; i++) {
+       for (i = 0; i < EFX_TX_QUEUE_COUNT; i++) {
                tx_queue = &efx->tx_queue[i];
                tx_queue->efx = efx;
                tx_queue->queue = i;
 
        [LOOPBACK_NETWORK]      = "NETWORK",
 };
 
-static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable);
-
 struct ethtool_string {
        char name[ETH_GSTRING_LEN];
 };
        }
 }
 
-static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
-{
-       int rc;
-
-       /* Our TSO requires TX checksumming, so force TX checksumming
-        * on when TSO is enabled.
-        */
-       if (enable) {
-               rc = efx_ethtool_set_tx_csum(net_dev, 1);
-               if (rc)
-                       return rc;
-       }
-
-       return ethtool_op_set_tso(net_dev, enable);
-}
-
-static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
-{
-       struct efx_nic *efx = netdev_priv(net_dev);
-       int rc;
-
-       rc = ethtool_op_set_tx_csum(net_dev, enable);
-       if (rc)
-               return rc;
-
-       efx_flush_queues(efx);
-
-       /* Our TSO requires TX checksumming, so disable TSO when
-        * checksumming is disabled
-        */
-       if (!enable) {
-               rc = efx_ethtool_set_tso(net_dev, 0);
-               if (rc)
-                       return rc;
-       }
-
-       return 0;
-}
-
 static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
        .get_rx_csum            = efx_ethtool_get_rx_csum,
        .set_rx_csum            = efx_ethtool_set_rx_csum,
        .get_tx_csum            = ethtool_op_get_tx_csum,
-       .set_tx_csum            = efx_ethtool_set_tx_csum,
+       .set_tx_csum            = ethtool_op_set_tx_csum,
        .get_sg                 = ethtool_op_get_sg,
        .set_sg                 = ethtool_op_set_sg,
        .get_tso                = ethtool_op_get_tso,
-       .set_tso                = efx_ethtool_set_tso,
+       .set_tso                = ethtool_op_set_tso,
        .get_flags              = ethtool_op_get_flags,
        .set_flags              = ethtool_op_set_flags,
        .self_test_count        = efx_ethtool_self_test_count,
 
                              TX_NON_IP_DROP_DIS_B0, 1);
 
        if (falcon_rev(efx) >= FALCON_REV_B0) {
-               int csum = !(efx->net_dev->features & NETIF_F_IP_CSUM);
-               EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, csum);
-               EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, csum);
+               int csum = tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM;
+               EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_IP_CHKSM_DIS_B0, !csum);
+               EFX_SET_OWORD_FIELD(tx_desc_ptr, TX_TCP_CHKSM_DIS_B0, !csum);
        }
 
        falcon_write_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
        if (falcon_rev(efx) < FALCON_REV_B0) {
                efx_oword_t reg;
 
-               BUG_ON(tx_queue->queue >= 128); /* HW limit */
+               /* Only 128 bits in this register */
+               BUILD_BUG_ON(EFX_TX_QUEUE_COUNT >= 128);
 
                falcon_read(efx, ®, TX_CHKSM_CFG_REG_KER_A1);
-               if (efx->net_dev->features & NETIF_F_IP_CSUM)
+               if (tx_queue->queue == EFX_TX_QUEUE_OFFLOAD_CSUM)
                        clear_bit_le(tx_queue->queue, (void *)®);
                else
                        set_bit_le(tx_queue->queue, (void *)®);
 
  **************************************************************************/
 
 #define EFX_MAX_CHANNELS 32
-#define EFX_MAX_TX_QUEUES 1
 #define EFX_MAX_RX_QUEUES EFX_MAX_CHANNELS
 
+#define EFX_TX_QUEUE_OFFLOAD_CSUM      0
+#define EFX_TX_QUEUE_NO_CSUM           1
+#define EFX_TX_QUEUE_COUNT             2
+
 /**
  * struct efx_special_buffer - An Efx special buffer
  * @addr: CPU base address of the buffer
  *
  * @efx: The associated Efx NIC
  * @queue: DMA queue number
- * @used: Queue is used by net driver
  * @channel: The associated channel
  * @buffer: The software buffer ring
  * @txd: The hardware descriptor ring
        /* Members which don't change on the fast path */
        struct efx_nic *efx ____cacheline_aligned_in_smp;
        int queue;
-       int used;
        struct efx_channel *channel;
        struct efx_nic *nic;
        struct efx_tx_buffer *buffer;
        enum nic_state state;
        enum reset_type reset_pending;
 
-       struct efx_tx_queue tx_queue[EFX_MAX_TX_QUEUES];
+       struct efx_tx_queue tx_queue[EFX_TX_QUEUE_COUNT];
        struct efx_rx_queue rx_queue[EFX_MAX_RX_QUEUES];
        struct efx_channel channel[EFX_MAX_CHANNELS];
 
 /* Iterate over all used TX queues */
 #define efx_for_each_tx_queue(_tx_queue, _efx)                         \
        for (_tx_queue = &_efx->tx_queue[0];                            \
-            _tx_queue < &_efx->tx_queue[EFX_MAX_TX_QUEUES];            \
-            _tx_queue++)                                               \
-               if (!_tx_queue->used)                                   \
-                       continue;                                       \
-               else
+            _tx_queue < &_efx->tx_queue[EFX_TX_QUEUE_COUNT];           \
+            _tx_queue++)
 
 /* Iterate over all TX queues belonging to a channel */
 #define efx_for_each_channel_tx_queue(_tx_queue, _channel)             \
        for (_tx_queue = &_channel->efx->tx_queue[0];                   \
-            _tx_queue < &_channel->efx->tx_queue[EFX_MAX_TX_QUEUES];   \
+            _tx_queue < &_channel->efx->tx_queue[EFX_TX_QUEUE_COUNT];  \
             _tx_queue++)                                               \
-               if ((!_tx_queue->used) ||                               \
-                   (_tx_queue->channel != _channel))                   \
+               if (_tx_queue->channel != _channel)                     \
                        continue;                                       \
                else
 
 
        int flush;
        int packet_count;
        struct sk_buff **skbs;
+
+       /* Checksums are being offloaded */
+       int offload_csum;
+
        atomic_t rx_good;
        atomic_t rx_bad;
        struct efx_loopback_payload payload;
        
        received = (struct efx_loopback_payload *) buf_ptr;
        received->ip.saddr = payload->ip.saddr;
-       received->ip.check = payload->ip.check;
-       
+       if (state->offload_csum)
+               received->ip.check = payload->ip.check;
+
        /* Check that header exists */
        if (pkt_len < sizeof(received->header)) {
                EFX_ERR(efx, "saw runt RX packet (length %d) in %s loopback "
 
                /* Test every TX queue */
                efx_for_each_tx_queue(tx_queue, efx) {
+                       state->offload_csum = (tx_queue->queue ==
+                                              EFX_TX_QUEUE_OFFLOAD_CSUM);
                        rc |= efx_test_loopback(tx_queue,
                                                &tests->loopback[mode]);
                        if (rc)
 
  */
 
 struct efx_loopback_self_tests {
-       int tx_sent[EFX_MAX_TX_QUEUES];
-       int tx_done[EFX_MAX_TX_QUEUES];
+       int tx_sent[EFX_TX_QUEUE_COUNT];
+       int tx_done[EFX_TX_QUEUE_COUNT];
        int rx_good;
        int rx_bad;
 };
 
 int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
-       return efx_xmit(efx, &efx->tx_queue[0], skb);
+       struct efx_tx_queue *tx_queue;
+
+       if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
+               tx_queue = &efx->tx_queue[EFX_TX_QUEUE_OFFLOAD_CSUM];
+       else
+               tx_queue = &efx->tx_queue[EFX_TX_QUEUE_NO_CSUM];
+
+       return efx_xmit(efx, tx_queue, skb);
 }
 
 void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
        /* Allocate software ring */
        txq_size = (efx->type->txd_ring_mask + 1) * sizeof(*tx_queue->buffer);
        tx_queue->buffer = kzalloc(txq_size, GFP_KERNEL);
-       if (!tx_queue->buffer) {
-               rc = -ENOMEM;
-               goto fail1;
-       }
+       if (!tx_queue->buffer)
+               return -ENOMEM;
        for (i = 0; i <= efx->type->txd_ring_mask; ++i)
                tx_queue->buffer[i].continuation = 1;
 
        /* Allocate hardware ring */
        rc = falcon_probe_tx(tx_queue);
        if (rc)
-               goto fail2;
+               goto fail;
 
        return 0;
 
- fail2:
+ fail:
        kfree(tx_queue->buffer);
        tx_queue->buffer = NULL;
- fail1:
-       tx_queue->used = 0;
-
        return rc;
 }
 
 
        kfree(tx_queue->buffer);
        tx_queue->buffer = NULL;
-       tx_queue->used = 0;
 }