OSDN Git Service

net: ena: add support for the rx offset feature
authorArthur Kiyanovski <akiyano@amazon.com>
Fri, 22 May 2020 09:08:52 +0000 (12:08 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 22 May 2020 21:12:48 +0000 (14:12 -0700)
Newer ENA devices can write data to rx buffers with an offset
from the beginning of the buffer.

This commit adds support for this feature in the driver.

Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/amazon/ena/ena_admin_defs.h
drivers/net/ethernet/amazon/ena/ena_eth_com.c
drivers/net/ethernet/amazon/ena/ena_eth_com.h
drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h
drivers/net/ethernet/amazon/ena/ena_netdev.c

index 7be3dcb..727836f 100644 (file)
@@ -813,7 +813,8 @@ struct ena_admin_host_info {
 
        u16 reserved;
 
-       /* 1 :0 : reserved
+       /* 0 : reserved
+        * 1 : rx_offset
         * 2 : interrupt_moderation
         * 31:3 : reserved
         */
@@ -1124,6 +1125,8 @@ struct ena_admin_ena_mmio_req_read_less_resp {
 #define ENA_ADMIN_HOST_INFO_DEVICE_MASK                     GENMASK(7, 3)
 #define ENA_ADMIN_HOST_INFO_BUS_SHIFT                       8
 #define ENA_ADMIN_HOST_INFO_BUS_MASK                        GENMASK(15, 8)
+#define ENA_ADMIN_HOST_INFO_RX_OFFSET_SHIFT                 1
+#define ENA_ADMIN_HOST_INFO_RX_OFFSET_MASK                  BIT(1)
 #define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_SHIFT      2
 #define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK       BIT(2)
 
index 2845ac2..a014f51 100644 (file)
@@ -519,7 +519,7 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
        struct ena_eth_io_rx_cdesc_base *cdesc = NULL;
        u16 cdesc_idx = 0;
        u16 nb_hw_desc;
-       u16 i;
+       u16 i = 0;
 
        WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type");
 
@@ -538,13 +538,19 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
                return -ENOSPC;
        }
 
-       for (i = 0; i < nb_hw_desc; i++) {
+       cdesc = ena_com_rx_cdesc_idx_to_ptr(io_cq, cdesc_idx);
+       ena_rx_ctx->pkt_offset = cdesc->offset;
+
+       do {
+               ena_buf[i].len = cdesc->length;
+               ena_buf[i].req_id = cdesc->req_id;
+
+               if (++i >= nb_hw_desc)
+                       break;
+
                cdesc = ena_com_rx_cdesc_idx_to_ptr(io_cq, cdesc_idx + i);
 
-               ena_buf->len = cdesc->length;
-               ena_buf->req_id = cdesc->req_id;
-               ena_buf++;
-       }
+       } while (1);
 
        /* Update SQ head ptr */
        io_sq->next_to_comp += nb_hw_desc;
index 77986c0..9834b5c 100644 (file)
@@ -73,6 +73,7 @@ struct ena_com_rx_ctx {
        u32 hash;
        u16 descs;
        int max_bufs;
+       u8 pkt_offset;
 };
 
 int ena_com_prepare_tx(struct ena_com_io_sq *io_sq,
index 00e0f05..ee28fb0 100644 (file)
@@ -264,7 +264,9 @@ struct ena_eth_io_rx_cdesc_base {
 
        u16 sub_qid;
 
-       u16 reserved;
+       u8 offset;
+
+       u8 reserved;
 };
 
 /* 8-word format */
index 85b87ed..3357829 100644 (file)
@@ -1435,6 +1435,8 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
 
                skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page,
                                rx_info->page_offset, len, ENA_PAGE_SIZE);
+               /* The offset is non zero only for the first buffer */
+               rx_info->page_offset = 0;
 
                netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
                          "rx skb updated. len %d. data_len %d\n",
@@ -1590,6 +1592,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
 {
        u16 next_to_clean = rx_ring->next_to_clean;
        struct ena_com_rx_ctx ena_rx_ctx;
+       struct ena_rx_buffer *rx_info;
        struct ena_adapter *adapter;
        u32 res_budget, work_done;
        int rx_copybreak_pkt = 0;
@@ -1614,6 +1617,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
                ena_rx_ctx.ena_bufs = rx_ring->ena_bufs;
                ena_rx_ctx.max_bufs = rx_ring->sgl_size;
                ena_rx_ctx.descs = 0;
+               ena_rx_ctx.pkt_offset = 0;
                rc = ena_com_rx_pkt(rx_ring->ena_com_io_cq,
                                    rx_ring->ena_com_io_sq,
                                    &ena_rx_ctx);
@@ -1623,6 +1627,9 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
                if (unlikely(ena_rx_ctx.descs == 0))
                        break;
 
+               rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id];
+               rx_info->page_offset = ena_rx_ctx.pkt_offset;
+
                netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
                          "rx_poll: q %d got packet from ena. descs #: %d l3 proto %d l4 proto %d hash: %x\n",
                          rx_ring->qid, ena_rx_ctx.descs, ena_rx_ctx.l3_proto,
@@ -3111,6 +3118,7 @@ static void ena_config_host_info(struct ena_com_dev *ena_dev,
        host_info->num_cpus = num_online_cpus();
 
        host_info->driver_supported_features =
+               ENA_ADMIN_HOST_INFO_RX_OFFSET_MASK |
                ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK;
 
        rc = ena_com_set_host_attributes(ena_dev);