sfc: make TSO version a per-queue parameter
authorBert Kenward <bkenward@solarflare.com>
Mon, 30 Nov 2015 09:05:35 +0000 (09:05 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 1 Dec 2015 20:46:39 +0000 (15:46 -0500)
The Solarflare 8000 series NIC will use a new TSO scheme. The current
driver refuses to load if the current TSO scheme is not found. Remove
that check and instead make the TSO version a per-queue parameter.

Signed-off-by: Bert Kenward <bkenward@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/tx.c

index bc6d21b471be4f4ae2f0c4c1cb26430e92c24803..425df3dbc77d7199a03676296d17cf7d5fc47260 100644 (file)
@@ -180,13 +180,6 @@ static int efx_ef10_init_datapath_caps(struct efx_nic *efx)
        nic_data->tx_dpcpu_fw_id =
                MCDI_WORD(outbuf, GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID);
 
-       if (!(nic_data->datapath_caps &
-             (1 << MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN))) {
-               netif_err(efx, drv, efx->net_dev,
-                         "current firmware does not support TSO\n");
-               return -ENODEV;
-       }
-
        if (!(nic_data->datapath_caps &
              (1 << MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_LBN))) {
                netif_err(efx, probe, efx->net_dev,
@@ -1797,6 +1790,12 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
                             ESF_DZ_TX_OPTION_UDP_TCP_CSUM, csum_offload,
                             ESF_DZ_TX_OPTION_IP_CSUM, csum_offload);
        tx_queue->write_count = 1;
+
+       if (nic_data->datapath_caps &
+           (1 << MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN)) {
+               tx_queue->tso_version = 1;
+       }
+
        wmb();
        efx_ef10_push_tx_desc(tx_queue, txd);
 
index a8ddd122f68586f7b566033c03272cb0b548dec6..5c0d0baa185c7e054bf59a80c1c2b419ffb864d0 100644 (file)
@@ -182,6 +182,7 @@ struct efx_tx_buffer {
  *
  * @efx: The associated Efx NIC
  * @queue: DMA queue number
+ * @tso_version: Version of TSO in use for this queue.
  * @channel: The associated channel
  * @core_txq: The networking core TX queue structure
  * @buffer: The software buffer ring
@@ -228,6 +229,7 @@ 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 tso_version;
        struct efx_channel *channel;
        struct netdev_queue *core_txq;
        struct efx_tx_buffer *buffer;
index 67f6afaa022f4e55e6d2632f90586c0d48a8e429..f7a0ec1bca97d96a4debc2324ad944380726cca6 100644 (file)
@@ -1010,13 +1010,17 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue,
 
 /* Parse the SKB header and initialise state. */
 static int tso_start(struct tso_state *st, struct efx_nic *efx,
+                    struct efx_tx_queue *tx_queue,
                     const struct sk_buff *skb)
 {
-       bool use_opt_desc = efx_nic_rev(efx) >= EFX_REV_HUNT_A0;
        struct device *dma_dev = &efx->pci_dev->dev;
        unsigned int header_len, in_len;
+       bool use_opt_desc = false;
        dma_addr_t dma_addr;
 
+       if (tx_queue->tso_version == 1)
+               use_opt_desc = true;
+
        st->ip_off = skb_network_header(skb) - skb->data;
        st->tcp_off = skb_transport_header(skb) - skb->data;
        header_len = st->tcp_off + (tcp_hdr(skb)->doff << 2u);
@@ -1271,7 +1275,7 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
        /* Find the packet protocol and sanity-check it */
        state.protocol = efx_tso_check_protocol(skb);
 
-       rc = tso_start(&state, efx, skb);
+       rc = tso_start(&state, efx, tx_queue, skb);
        if (rc)
                goto mem_err;