sfc: Extend struct efx_tx_buffer to allow pushing option descriptors
authorBen Hutchings <bhutchings@solarflare.com>
Tue, 8 Jan 2013 23:43:19 +0000 (23:43 +0000)
committerBen Hutchings <bhutchings@solarflare.com>
Thu, 29 Aug 2013 17:12:14 +0000 (18:12 +0100)
The TX path firmware for EF10 supports 'option descriptors' to control
offloads and various other features.  Add a flag and field for these
in struct efx_tx_buffer, and don't treat them as DMA descriptors on
completion.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
drivers/net/ethernet/sfc/farch.c
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/tx.c

index 842f92e455174d954c1f88ad651a932b743d31d2..65073aac3c80807ae5b0874a7abd12308ec79159 100644 (file)
@@ -325,6 +325,8 @@ void efx_farch_tx_write(struct efx_tx_queue *tx_queue)
                txd = efx_tx_desc(tx_queue, write_ptr);
                ++tx_queue->write_count;
 
+               EFX_BUG_ON_PARANOID(buffer->flags & EFX_TX_BUF_OPTION);
+
                /* Create TX descriptor ring entry */
                BUILD_BUG_ON(EFX_TX_BUF_CONT != 1);
                EFX_POPULATE_QWORD_4(*txd,
index c9b6f2dcb539cdb2c4a14a0b3f02f35799cfc776..d1aa5dcec963c3f1e7aa3f613268f77f48ff261d 100644 (file)
@@ -135,6 +135,7 @@ struct efx_special_buffer {
  *     freed when descriptor completes
  * @heap_buf: When @flags & %EFX_TX_BUF_HEAP, the associated heap buffer to be
  *     freed when descriptor completes.
+ * @option: When @flags & %EFX_TX_BUF_OPTION, a NIC-specific option descriptor.
  * @dma_addr: DMA address of the fragment.
  * @flags: Flags for allocation and DMA mapping type
  * @len: Length of this fragment.
@@ -146,7 +147,10 @@ struct efx_tx_buffer {
                const struct sk_buff *skb;
                void *heap_buf;
        };
-       dma_addr_t dma_addr;
+       union {
+               efx_qword_t option;
+               dma_addr_t dma_addr;
+       };
        unsigned short flags;
        unsigned short len;
        unsigned short unmap_len;
@@ -155,6 +159,7 @@ struct efx_tx_buffer {
 #define EFX_TX_BUF_SKB         2       /* buffer is last part of skb */
 #define EFX_TX_BUF_HEAP                4       /* buffer was allocated with kmalloc() */
 #define EFX_TX_BUF_MAP_SINGLE  8       /* buffer was mapped with dma_map_single() */
+#define EFX_TX_BUF_OPTION      0x10    /* empty buffer for option descriptor */
 
 /**
  * struct efx_tx_queue - An Efx TX queue
index 85ee647b28ad7b2e9864a25874d909ce39843f1a..82075f9f02e6651cba8027e99a6cb4a6a0fd441f 100644 (file)
@@ -306,7 +306,9 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
 
        while (read_ptr != stop_index) {
                struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr];
-               if (unlikely(buffer->len == 0)) {
+
+               if (!(buffer->flags & EFX_TX_BUF_OPTION) &&
+                   unlikely(buffer->len == 0)) {
                        netif_err(efx, tx_err, efx->net_dev,
                                  "TX queue %d spurious TX completion id %x\n",
                                  tx_queue->queue, read_ptr);