static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
 {
-       bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
+       bool csum_offload = tx_queue->label & EFX_TXQ_TYPE_OFFLOAD;
        struct efx_channel *channel = tx_queue->channel;
        struct efx_nic *efx = tx_queue->efx;
        struct efx_ef10_nic_data *nic_data;
 
        for (j = 0; j < EFX_TXQ_TYPES; j++) {
                tx_queue = &channel->tx_queue[j];
                tx_queue->efx = efx;
-               tx_queue->queue = i * EFX_TXQ_TYPES + j;
+               tx_queue->queue = -1;
+               tx_queue->label = j;
                tx_queue->channel = channel;
        }
 
 
 int efx_set_channels(struct efx_nic *efx)
 {
-       struct efx_channel *channel;
        struct efx_tx_queue *tx_queue;
+       struct efx_channel *channel;
+       unsigned int next_queue = 0;
        int xdp_queue_number;
        int rc;
 
                else
                        channel->rx_queue.core_index = -1;
 
-               efx_for_each_channel_tx_queue(tx_queue, channel) {
-                       tx_queue->queue -= (efx->tx_channel_offset *
-                                           EFX_TXQ_TYPES);
-
-                       if (efx_channel_is_xdp_tx(channel) &&
-                           xdp_queue_number < efx->xdp_tx_queue_count) {
-                               efx->xdp_tx_queues[xdp_queue_number] = tx_queue;
-                               xdp_queue_number++;
+               if (channel->channel >= efx->tx_channel_offset) {
+                       if (efx_channel_is_xdp_tx(channel)) {
+                               efx_for_each_channel_tx_queue(tx_queue, channel) {
+                                       tx_queue->queue = next_queue++;
+                                       netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is XDP %u, HW %u\n",
+                                                 channel->channel, tx_queue->label,
+                                                 xdp_queue_number, tx_queue->queue);
+                                       /* We may have a few left-over XDP TX
+                                        * queues owing to xdp_tx_queue_count
+                                        * not dividing evenly by EFX_TXQ_TYPES.
+                                        * We still allocate and probe those
+                                        * TXQs, but never use them.
+                                        */
+                                       if (xdp_queue_number < efx->xdp_tx_queue_count)
+                                               efx->xdp_tx_queues[xdp_queue_number] = tx_queue;
+                                       xdp_queue_number++;
+                               }
+                       } else {
+                               efx_for_each_channel_tx_queue(tx_queue, channel) {
+                                       tx_queue->queue = next_queue++;
+                                       netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is HW %u\n",
+                                                 channel->channel, tx_queue->label,
+                                                 tx_queue->queue);
+                               }
                        }
                }
        }
 
 }
 
 #define EFX_CHANNEL_NAME(_channel) "chan%d", _channel->channel
-#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->queue
-#define EFX_RX_QUEUE_NAME(_rx_queue) "rxq%d", _rx_queue->queue
+#define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->label
 #define EFX_LOOPBACK_NAME(_mode, _counter)                     \
        "loopback.%s." _counter, STRING_TABLE_LOOKUP(_mode, efx_loopback_mode)
 
 
        efx_for_each_channel_tx_queue(tx_queue, channel) {
                efx_fill_test(test_index++, strings, data,
-                             &lb_tests->tx_sent[tx_queue->queue],
+                             &lb_tests->tx_sent[tx_queue->label],
                              EFX_TX_QUEUE_NAME(tx_queue),
                              EFX_LOOPBACK_NAME(mode, "tx_sent"));
                efx_fill_test(test_index++, strings, data,
-                             &lb_tests->tx_done[tx_queue->queue],
+                             &lb_tests->tx_done[tx_queue->label],
                              EFX_TX_QUEUE_NAME(tx_queue),
                              EFX_LOOPBACK_NAME(mode, "tx_done"));
        }
 
 
 void efx_farch_tx_init(struct efx_tx_queue *tx_queue)
 {
-       int csum = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
+       int csum = tx_queue->label & EFX_TXQ_TYPE_OFFLOAD;
        struct efx_nic *efx = tx_queue->efx;
        efx_oword_t reg;
 
                              FRF_AZ_TX_DESCQ_EVQ_ID,
                              tx_queue->channel->channel,
                              FRF_AZ_TX_DESCQ_OWNER_ID, 0,
-                             FRF_AZ_TX_DESCQ_LABEL, tx_queue->queue,
+                             FRF_AZ_TX_DESCQ_LABEL, tx_queue->label,
                              FRF_AZ_TX_DESCQ_SIZE,
                              __ffs(tx_queue->txd.entries),
                              FRF_AZ_TX_DESCQ_TYPE, 0,
 
        EFX_POPULATE_OWORD_1(reg,
                             FRF_BZ_TX_PACE,
-                            (tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ?
+                            (tx_queue->label & EFX_TXQ_TYPE_HIGHPRI) ?
                             FFE_BZ_TX_PACE_OFF :
                             FFE_BZ_TX_PACE_RESERVED);
        efx_writeo_table(efx, ®, FR_BZ_TX_PACE_TBL, tx_queue->queue);
 
 {
        MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_TXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 /
                                                       EFX_BUF_SIZE));
-       bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
+       bool csum_offload = tx_queue->label & EFX_TXQ_TYPE_OFFLOAD;
        size_t entries = tx_queue->txd.buf.len / EFX_BUF_SIZE;
        struct efx_channel *channel = tx_queue->channel;
        struct efx_nic *efx = tx_queue->efx;
 
        MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_SIZE, tx_queue->ptr_mask + 1);
        MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_TARGET_EVQ, channel->channel);
-       MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_LABEL, tx_queue->queue);
+       MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_LABEL, tx_queue->label);
        MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_INSTANCE, tx_queue->queue);
        MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_OWNER_ID, 0);
        MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_PORT_ID, efx->vport_id);
 
  *
  * @efx: The associated Efx NIC
  * @queue: DMA queue number
+ * @label: Label for TX completion events.
+ *     Is our index within @channel->tx_queue array.
  * @tso_version: Version of TSO in use for this queue.
  * @channel: The associated channel
  * @core_txq: The networking core TX queue structure
 struct efx_tx_queue {
        /* Members which don't change on the fast path */
        struct efx_nic *efx ____cacheline_aligned_in_smp;
-       unsigned queue;
+       unsigned int queue;
+       unsigned int label;
        unsigned int tso_version;
        struct efx_channel *channel;
        struct netdev_queue *core_txq;
 
 /* XXX is this a thing on EF100? */
 static inline struct efx_tx_queue *efx_tx_queue_partner(struct efx_tx_queue *tx_queue)
 {
-       if (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD)
+       if (tx_queue->label & EFX_TXQ_TYPE_OFFLOAD)
                return tx_queue - EFX_TXQ_TYPE_OFFLOAD;
        else
                return tx_queue + EFX_TXQ_TYPE_OFFLOAD;
 
                if (rc != NETDEV_TX_OK) {
                        netif_err(efx, drv, efx->net_dev,
                                  "TX queue %d could not transmit packet %d of "
-                                 "%d in %s loopback test\n", tx_queue->queue,
+                                 "%d in %s loopback test\n", tx_queue->label,
                                  i + 1, state->packet_count,
                                  LOOPBACK_MODE(efx));
 
                netif_err(efx, drv, efx->net_dev,
                          "TX queue %d saw only %d out of an expected %d "
                          "TX completion events in %s loopback test\n",
-                         tx_queue->queue, tx_done, state->packet_count,
+                         tx_queue->label, tx_done, state->packet_count,
                          LOOPBACK_MODE(efx));
                rc = -ETIMEDOUT;
                /* Allow to fall through so we see the RX errors as well */
                netif_dbg(efx, drv, efx->net_dev,
                          "TX queue %d saw only %d out of an expected %d "
                          "received packets in %s loopback test\n",
-                         tx_queue->queue, rx_good, state->packet_count,
+                         tx_queue->label, rx_good, state->packet_count,
                          LOOPBACK_MODE(efx));
                rc = -ETIMEDOUT;
                /* Fall through */
        }
 
        /* Update loopback test structure */
-       lb_tests->tx_sent[tx_queue->queue] += state->packet_count;
-       lb_tests->tx_done[tx_queue->queue] += tx_done;
+       lb_tests->tx_sent[tx_queue->label] += state->packet_count;
+       lb_tests->tx_done[tx_queue->label] += tx_done;
        lb_tests->rx_good += rx_good;
        lb_tests->rx_bad += rx_bad;
 
                state->flush = false;
 
                netif_dbg(efx, drv, efx->net_dev,
-                         "TX queue %d testing %s loopback with %d packets\n",
-                         tx_queue->queue, LOOPBACK_MODE(efx),
+                         "TX queue %d (hw %d) testing %s loopback with %d packets\n",
+                         tx_queue->label, tx_queue->queue, LOOPBACK_MODE(efx),
                          state->packet_count);
 
                efx_iterate_state(efx);
 
        netif_dbg(efx, drv, efx->net_dev,
                  "TX queue %d passed %s loopback test with a burst length "
-                 "of %d packets\n", tx_queue->queue, LOOPBACK_MODE(efx),
+                 "of %d packets\n", tx_queue->label, LOOPBACK_MODE(efx),
                  state->packet_count);
 
        return 0;
 
                /* Test all enabled types of TX queue */
                efx_for_each_channel_tx_queue(tx_queue, channel) {
-                       state->offload_csum = (tx_queue->queue &
+                       state->offload_csum = (tx_queue->label &
                                               EFX_TXQ_TYPE_OFFLOAD);
                        rc = efx_test_loopback(tx_queue,
                                               &tests->loopback[mode]);
 
        efx->max_channels = EFX_MAX_CHANNELS;
        efx->max_vis = EFX_MAX_CHANNELS;
        efx->max_tx_channels = EFX_MAX_CHANNELS;
-       efx->tx_queues_per_channel = 2;
+       efx->tx_queues_per_channel = 4;
 
        efx_reado(efx, ®, FR_AZ_CS_DEBUG);
        efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
 
        /* Must be inverse of queue lookup in efx_hard_start_xmit() */
        tx_queue->core_txq =
                netdev_get_tx_queue(efx->net_dev,
-                                   tx_queue->queue / EFX_TXQ_TYPES +
-                                   ((tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ?
+                                   tx_queue->channel->channel +
+                                   ((tx_queue->label & EFX_TXQ_TYPE_HIGHPRI) ?
                                     efx->n_tx_channels : 0));
 }
 
 {
        struct efx_nic *efx = netdev_priv(net_dev);
        struct tc_mqprio_qopt *mqprio = type_data;
-       struct efx_channel *channel;
-       struct efx_tx_queue *tx_queue;
        unsigned tc, num_tc;
-       int rc;
 
        if (type != TC_SETUP_QDISC_MQPRIO)
                return -EOPNOTSUPP;
                net_dev->tc_to_txq[tc].count = efx->n_tx_channels;
        }
 
-       if (num_tc > net_dev->num_tc) {
-               efx->tx_queues_per_channel = 4;
-               /* Initialise high-priority queues as necessary */
-               efx_for_each_channel(channel, efx) {
-                       efx_for_each_channel_tx_queue(tx_queue, channel) {
-                               if (!(tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI))
-                                       continue;
-                               if (!tx_queue->buffer) {
-                                       rc = efx_probe_tx_queue(tx_queue);
-                                       if (rc)
-                                               return rc;
-                               }
-                               if (!tx_queue->initialised)
-                                       efx_init_tx_queue(tx_queue);
-                               efx_init_tx_queue_core_txq(tx_queue);
-                       }
-               }
-       } else {
-               /* Reduce number of classes before number of queues */
-               net_dev->num_tc = num_tc;
-       }
-
-       rc = netif_set_real_num_tx_queues(net_dev,
-                                         max_t(int, num_tc, 1) *
-                                         efx->n_tx_channels);
-       if (rc)
-               return rc;
-
-       /* Do not destroy high-priority queues when they become
-        * unused.  We would have to flush them first, and it is
-        * fairly difficult to flush a subset of TX queues.  Leave
-        * it to efx_fini_channels().
-        */
-
        net_dev->num_tc = num_tc;
-       return 0;
+
+       return netif_set_real_num_tx_queues(net_dev,
+                                           max_t(int, num_tc, 1) *
+                                           efx->n_tx_channels);
 }