Commit 68f236df authored by Arthur Kiyanovski's avatar Arthur Kiyanovski Committed by David S. Miller

net: ena: add support for the rx offset feature

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: default avatarSameeh Jubran <sameehj@amazon.com>
Signed-off-by: default avatarArthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b79f91f1
...@@ -813,7 +813,8 @@ struct ena_admin_host_info { ...@@ -813,7 +813,8 @@ struct ena_admin_host_info {
u16 reserved; u16 reserved;
/* 1 :0 : reserved /* 0 : reserved
* 1 : rx_offset
* 2 : interrupt_moderation * 2 : interrupt_moderation
* 31:3 : reserved * 31:3 : reserved
*/ */
...@@ -1124,6 +1125,8 @@ struct ena_admin_ena_mmio_req_read_less_resp { ...@@ -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_DEVICE_MASK GENMASK(7, 3)
#define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8 #define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8
#define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 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_SHIFT 2
#define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK BIT(2) #define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK BIT(2)
......
...@@ -519,7 +519,7 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq, ...@@ -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; struct ena_eth_io_rx_cdesc_base *cdesc = NULL;
u16 cdesc_idx = 0; u16 cdesc_idx = 0;
u16 nb_hw_desc; u16 nb_hw_desc;
u16 i; u16 i = 0;
WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type"); 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, ...@@ -538,13 +538,19 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
return -ENOSPC; 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); cdesc = ena_com_rx_cdesc_idx_to_ptr(io_cq, cdesc_idx + i);
ena_buf->len = cdesc->length; } while (1);
ena_buf->req_id = cdesc->req_id;
ena_buf++;
}
/* Update SQ head ptr */ /* Update SQ head ptr */
io_sq->next_to_comp += nb_hw_desc; io_sq->next_to_comp += nb_hw_desc;
......
...@@ -73,6 +73,7 @@ struct ena_com_rx_ctx { ...@@ -73,6 +73,7 @@ struct ena_com_rx_ctx {
u32 hash; u32 hash;
u16 descs; u16 descs;
int max_bufs; int max_bufs;
u8 pkt_offset;
}; };
int ena_com_prepare_tx(struct ena_com_io_sq *io_sq, int ena_com_prepare_tx(struct ena_com_io_sq *io_sq,
......
...@@ -264,7 +264,9 @@ struct ena_eth_io_rx_cdesc_base { ...@@ -264,7 +264,9 @@ struct ena_eth_io_rx_cdesc_base {
u16 sub_qid; u16 sub_qid;
u16 reserved; u8 offset;
u8 reserved;
}; };
/* 8-word format */ /* 8-word format */
......
...@@ -1435,6 +1435,8 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, ...@@ -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, skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page,
rx_info->page_offset, len, ENA_PAGE_SIZE); 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, netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev,
"rx skb updated. len %d. data_len %d\n", "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, ...@@ -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; u16 next_to_clean = rx_ring->next_to_clean;
struct ena_com_rx_ctx ena_rx_ctx; struct ena_com_rx_ctx ena_rx_ctx;
struct ena_rx_buffer *rx_info;
struct ena_adapter *adapter; struct ena_adapter *adapter;
u32 res_budget, work_done; u32 res_budget, work_done;
int rx_copybreak_pkt = 0; int rx_copybreak_pkt = 0;
...@@ -1614,6 +1617,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, ...@@ -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.ena_bufs = rx_ring->ena_bufs;
ena_rx_ctx.max_bufs = rx_ring->sgl_size; ena_rx_ctx.max_bufs = rx_ring->sgl_size;
ena_rx_ctx.descs = 0; ena_rx_ctx.descs = 0;
ena_rx_ctx.pkt_offset = 0;
rc = ena_com_rx_pkt(rx_ring->ena_com_io_cq, rc = ena_com_rx_pkt(rx_ring->ena_com_io_cq,
rx_ring->ena_com_io_sq, rx_ring->ena_com_io_sq,
&ena_rx_ctx); &ena_rx_ctx);
...@@ -1623,6 +1627,9 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, ...@@ -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)) if (unlikely(ena_rx_ctx.descs == 0))
break; 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, 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_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, 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, ...@@ -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->num_cpus = num_online_cpus();
host_info->driver_supported_features = host_info->driver_supported_features =
ENA_ADMIN_HOST_INFO_RX_OFFSET_MASK |
ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK; ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK;
rc = ena_com_set_host_attributes(ena_dev); rc = ena_com_set_host_attributes(ena_dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment