162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
262306a36Sopenharmony_ci * Google virtual Ethernet (gve) driver
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) 2015-2021 Google, Inc.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef _GVE_H_
862306a36Sopenharmony_ci#define _GVE_H_
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/dma-mapping.h>
1162306a36Sopenharmony_ci#include <linux/netdevice.h>
1262306a36Sopenharmony_ci#include <linux/pci.h>
1362306a36Sopenharmony_ci#include <linux/u64_stats_sync.h>
1462306a36Sopenharmony_ci#include <net/xdp.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include "gve_desc.h"
1762306a36Sopenharmony_ci#include "gve_desc_dqo.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#ifndef PCI_VENDOR_ID_GOOGLE
2062306a36Sopenharmony_ci#define PCI_VENDOR_ID_GOOGLE	0x1ae0
2162306a36Sopenharmony_ci#endif
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define PCI_DEV_ID_GVNIC	0x0042
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define GVE_REGISTER_BAR	0
2662306a36Sopenharmony_ci#define GVE_DOORBELL_BAR	2
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* Driver can alloc up to 2 segments for the header and 2 for the payload. */
2962306a36Sopenharmony_ci#define GVE_TX_MAX_IOVEC	4
3062306a36Sopenharmony_ci/* 1 for management, 1 for rx, 1 for tx */
3162306a36Sopenharmony_ci#define GVE_MIN_MSIX 3
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci/* Numbers of gve tx/rx stats in stats report. */
3462306a36Sopenharmony_ci#define GVE_TX_STATS_REPORT_NUM	6
3562306a36Sopenharmony_ci#define GVE_RX_STATS_REPORT_NUM	2
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/* Interval to schedule a stats report update, 20000ms. */
3862306a36Sopenharmony_ci#define GVE_STATS_REPORT_TIMER_PERIOD	20000
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/* Numbers of NIC tx/rx stats in stats report. */
4162306a36Sopenharmony_ci#define NIC_TX_STATS_REPORT_NUM	0
4262306a36Sopenharmony_ci#define NIC_RX_STATS_REPORT_NUM	4
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#define GVE_DATA_SLOT_ADDR_PAGE_MASK (~(PAGE_SIZE - 1))
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* PTYPEs are always 10 bits. */
4762306a36Sopenharmony_ci#define GVE_NUM_PTYPES	1024
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#define GVE_RX_BUFFER_SIZE_DQO 2048
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#define GVE_XDP_ACTIONS 5
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#define GVE_GQ_TX_MIN_PKT_DESC_BYTES 182
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci#define DQO_QPL_DEFAULT_TX_PAGES 512
5662306a36Sopenharmony_ci#define DQO_QPL_DEFAULT_RX_PAGES 2048
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/* Maximum TSO size supported on DQO */
5962306a36Sopenharmony_ci#define GVE_DQO_TX_MAX	0x3FFFF
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci#define GVE_TX_BUF_SHIFT_DQO 11
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/* 2K buffers for DQO-QPL */
6462306a36Sopenharmony_ci#define GVE_TX_BUF_SIZE_DQO BIT(GVE_TX_BUF_SHIFT_DQO)
6562306a36Sopenharmony_ci#define GVE_TX_BUFS_PER_PAGE_DQO (PAGE_SIZE >> GVE_TX_BUF_SHIFT_DQO)
6662306a36Sopenharmony_ci#define GVE_MAX_TX_BUFS_PER_PKT (DIV_ROUND_UP(GVE_DQO_TX_MAX, GVE_TX_BUF_SIZE_DQO))
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/* If number of free/recyclable buffers are less than this threshold; driver
6962306a36Sopenharmony_ci * allocs and uses a non-qpl page on the receive path of DQO QPL to free
7062306a36Sopenharmony_ci * up buffers.
7162306a36Sopenharmony_ci * Value is set big enough to post at least 3 64K LRO packet via 2K buffer to NIC.
7262306a36Sopenharmony_ci */
7362306a36Sopenharmony_ci#define GVE_DQO_QPL_ONDEMAND_ALLOC_THRESHOLD 96
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci/* Each slot in the desc ring has a 1:1 mapping to a slot in the data ring */
7662306a36Sopenharmony_cistruct gve_rx_desc_queue {
7762306a36Sopenharmony_ci	struct gve_rx_desc *desc_ring; /* the descriptor ring */
7862306a36Sopenharmony_ci	dma_addr_t bus; /* the bus for the desc_ring */
7962306a36Sopenharmony_ci	u8 seqno; /* the next expected seqno for this desc*/
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci/* The page info for a single slot in the RX data queue */
8362306a36Sopenharmony_cistruct gve_rx_slot_page_info {
8462306a36Sopenharmony_ci	struct page *page;
8562306a36Sopenharmony_ci	void *page_address;
8662306a36Sopenharmony_ci	u32 page_offset; /* offset to write to in page */
8762306a36Sopenharmony_ci	int pagecnt_bias; /* expected pagecnt if only the driver has a ref */
8862306a36Sopenharmony_ci	u16 pad; /* adjustment for rx padding */
8962306a36Sopenharmony_ci	u8 can_flip; /* tracks if the networking stack is using the page */
9062306a36Sopenharmony_ci};
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/* A list of pages registered with the device during setup and used by a queue
9362306a36Sopenharmony_ci * as buffers
9462306a36Sopenharmony_ci */
9562306a36Sopenharmony_cistruct gve_queue_page_list {
9662306a36Sopenharmony_ci	u32 id; /* unique id */
9762306a36Sopenharmony_ci	u32 num_entries;
9862306a36Sopenharmony_ci	struct page **pages; /* list of num_entries pages */
9962306a36Sopenharmony_ci	dma_addr_t *page_buses; /* the dma addrs of the pages */
10062306a36Sopenharmony_ci};
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Each slot in the data ring has a 1:1 mapping to a slot in the desc ring */
10362306a36Sopenharmony_cistruct gve_rx_data_queue {
10462306a36Sopenharmony_ci	union gve_rx_data_slot *data_ring; /* read by NIC */
10562306a36Sopenharmony_ci	dma_addr_t data_bus; /* dma mapping of the slots */
10662306a36Sopenharmony_ci	struct gve_rx_slot_page_info *page_info; /* page info of the buffers */
10762306a36Sopenharmony_ci	struct gve_queue_page_list *qpl; /* qpl assigned to this queue */
10862306a36Sopenharmony_ci	u8 raw_addressing; /* use raw_addressing? */
10962306a36Sopenharmony_ci};
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistruct gve_priv;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci/* RX buffer queue for posting buffers to HW.
11462306a36Sopenharmony_ci * Each RX (completion) queue has a corresponding buffer queue.
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_cistruct gve_rx_buf_queue_dqo {
11762306a36Sopenharmony_ci	struct gve_rx_desc_dqo *desc_ring;
11862306a36Sopenharmony_ci	dma_addr_t bus;
11962306a36Sopenharmony_ci	u32 head; /* Pointer to start cleaning buffers at. */
12062306a36Sopenharmony_ci	u32 tail; /* Last posted buffer index + 1 */
12162306a36Sopenharmony_ci	u32 mask; /* Mask for indices to the size of the ring */
12262306a36Sopenharmony_ci};
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/* RX completion queue to receive packets from HW. */
12562306a36Sopenharmony_cistruct gve_rx_compl_queue_dqo {
12662306a36Sopenharmony_ci	struct gve_rx_compl_desc_dqo *desc_ring;
12762306a36Sopenharmony_ci	dma_addr_t bus;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	/* Number of slots which did not have a buffer posted yet. We should not
13062306a36Sopenharmony_ci	 * post more buffers than the queue size to avoid HW overrunning the
13162306a36Sopenharmony_ci	 * queue.
13262306a36Sopenharmony_ci	 */
13362306a36Sopenharmony_ci	int num_free_slots;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	/* HW uses a "generation bit" to notify SW of new descriptors. When a
13662306a36Sopenharmony_ci	 * descriptor's generation bit is different from the current generation,
13762306a36Sopenharmony_ci	 * that descriptor is ready to be consumed by SW.
13862306a36Sopenharmony_ci	 */
13962306a36Sopenharmony_ci	u8 cur_gen_bit;
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	/* Pointer into desc_ring where the next completion descriptor will be
14262306a36Sopenharmony_ci	 * received.
14362306a36Sopenharmony_ci	 */
14462306a36Sopenharmony_ci	u32 head;
14562306a36Sopenharmony_ci	u32 mask; /* Mask for indices to the size of the ring */
14662306a36Sopenharmony_ci};
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/* Stores state for tracking buffers posted to HW */
14962306a36Sopenharmony_cistruct gve_rx_buf_state_dqo {
15062306a36Sopenharmony_ci	/* The page posted to HW. */
15162306a36Sopenharmony_ci	struct gve_rx_slot_page_info page_info;
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	/* The DMA address corresponding to `page_info`. */
15462306a36Sopenharmony_ci	dma_addr_t addr;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	/* Last offset into the page when it only had a single reference, at
15762306a36Sopenharmony_ci	 * which point every other offset is free to be reused.
15862306a36Sopenharmony_ci	 */
15962306a36Sopenharmony_ci	u32 last_single_ref_offset;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	/* Linked list index to next element in the list, or -1 if none */
16262306a36Sopenharmony_ci	s16 next;
16362306a36Sopenharmony_ci};
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci/* `head` and `tail` are indices into an array, or -1 if empty. */
16662306a36Sopenharmony_cistruct gve_index_list {
16762306a36Sopenharmony_ci	s16 head;
16862306a36Sopenharmony_ci	s16 tail;
16962306a36Sopenharmony_ci};
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci/* A single received packet split across multiple buffers may be
17262306a36Sopenharmony_ci * reconstructed using the information in this structure.
17362306a36Sopenharmony_ci */
17462306a36Sopenharmony_cistruct gve_rx_ctx {
17562306a36Sopenharmony_ci	/* head and tail of skb chain for the current packet or NULL if none */
17662306a36Sopenharmony_ci	struct sk_buff *skb_head;
17762306a36Sopenharmony_ci	struct sk_buff *skb_tail;
17862306a36Sopenharmony_ci	u32 total_size;
17962306a36Sopenharmony_ci	u8 frag_cnt;
18062306a36Sopenharmony_ci	bool drop_pkt;
18162306a36Sopenharmony_ci};
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistruct gve_rx_cnts {
18462306a36Sopenharmony_ci	u32 ok_pkt_bytes;
18562306a36Sopenharmony_ci	u16 ok_pkt_cnt;
18662306a36Sopenharmony_ci	u16 total_pkt_cnt;
18762306a36Sopenharmony_ci	u16 cont_pkt_cnt;
18862306a36Sopenharmony_ci	u16 desc_err_pkt_cnt;
18962306a36Sopenharmony_ci};
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci/* Contains datapath state used to represent an RX queue. */
19262306a36Sopenharmony_cistruct gve_rx_ring {
19362306a36Sopenharmony_ci	struct gve_priv *gve;
19462306a36Sopenharmony_ci	union {
19562306a36Sopenharmony_ci		/* GQI fields */
19662306a36Sopenharmony_ci		struct {
19762306a36Sopenharmony_ci			struct gve_rx_desc_queue desc;
19862306a36Sopenharmony_ci			struct gve_rx_data_queue data;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci			/* threshold for posting new buffs and descs */
20162306a36Sopenharmony_ci			u32 db_threshold;
20262306a36Sopenharmony_ci			u16 packet_buffer_size;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci			u32 qpl_copy_pool_mask;
20562306a36Sopenharmony_ci			u32 qpl_copy_pool_head;
20662306a36Sopenharmony_ci			struct gve_rx_slot_page_info *qpl_copy_pool;
20762306a36Sopenharmony_ci		};
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci		/* DQO fields. */
21062306a36Sopenharmony_ci		struct {
21162306a36Sopenharmony_ci			struct gve_rx_buf_queue_dqo bufq;
21262306a36Sopenharmony_ci			struct gve_rx_compl_queue_dqo complq;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci			struct gve_rx_buf_state_dqo *buf_states;
21562306a36Sopenharmony_ci			u16 num_buf_states;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci			/* Linked list of gve_rx_buf_state_dqo. Index into
21862306a36Sopenharmony_ci			 * buf_states, or -1 if empty.
21962306a36Sopenharmony_ci			 */
22062306a36Sopenharmony_ci			s16 free_buf_states;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci			/* Linked list of gve_rx_buf_state_dqo. Indexes into
22362306a36Sopenharmony_ci			 * buf_states, or -1 if empty.
22462306a36Sopenharmony_ci			 *
22562306a36Sopenharmony_ci			 * This list contains buf_states which are pointing to
22662306a36Sopenharmony_ci			 * valid buffers.
22762306a36Sopenharmony_ci			 *
22862306a36Sopenharmony_ci			 * We use a FIFO here in order to increase the
22962306a36Sopenharmony_ci			 * probability that buffers can be reused by increasing
23062306a36Sopenharmony_ci			 * the time between usages.
23162306a36Sopenharmony_ci			 */
23262306a36Sopenharmony_ci			struct gve_index_list recycled_buf_states;
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci			/* Linked list of gve_rx_buf_state_dqo. Indexes into
23562306a36Sopenharmony_ci			 * buf_states, or -1 if empty.
23662306a36Sopenharmony_ci			 *
23762306a36Sopenharmony_ci			 * This list contains buf_states which have buffers
23862306a36Sopenharmony_ci			 * which cannot be reused yet.
23962306a36Sopenharmony_ci			 */
24062306a36Sopenharmony_ci			struct gve_index_list used_buf_states;
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci			/* qpl assigned to this queue */
24362306a36Sopenharmony_ci			struct gve_queue_page_list *qpl;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci			/* index into queue page list */
24662306a36Sopenharmony_ci			u32 next_qpl_page_idx;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci			/* track number of used buffers */
24962306a36Sopenharmony_ci			u16 used_buf_states_cnt;
25062306a36Sopenharmony_ci		} dqo;
25162306a36Sopenharmony_ci	};
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	u64 rbytes; /* free-running bytes received */
25462306a36Sopenharmony_ci	u64 rpackets; /* free-running packets received */
25562306a36Sopenharmony_ci	u32 cnt; /* free-running total number of completed packets */
25662306a36Sopenharmony_ci	u32 fill_cnt; /* free-running total number of descs and buffs posted */
25762306a36Sopenharmony_ci	u32 mask; /* masks the cnt and fill_cnt to the size of the ring */
25862306a36Sopenharmony_ci	u64 rx_copybreak_pkt; /* free-running count of copybreak packets */
25962306a36Sopenharmony_ci	u64 rx_copied_pkt; /* free-running total number of copied packets */
26062306a36Sopenharmony_ci	u64 rx_skb_alloc_fail; /* free-running count of skb alloc fails */
26162306a36Sopenharmony_ci	u64 rx_buf_alloc_fail; /* free-running count of buffer alloc fails */
26262306a36Sopenharmony_ci	u64 rx_desc_err_dropped_pkt; /* free-running count of packets dropped by descriptor error */
26362306a36Sopenharmony_ci	u64 rx_cont_packet_cnt; /* free-running multi-fragment packets received */
26462306a36Sopenharmony_ci	u64 rx_frag_flip_cnt; /* free-running count of rx segments where page_flip was used */
26562306a36Sopenharmony_ci	u64 rx_frag_copy_cnt; /* free-running count of rx segments copied */
26662306a36Sopenharmony_ci	u64 rx_frag_alloc_cnt; /* free-running count of rx page allocations */
26762306a36Sopenharmony_ci	u64 xdp_tx_errors;
26862306a36Sopenharmony_ci	u64 xdp_redirect_errors;
26962306a36Sopenharmony_ci	u64 xdp_alloc_fails;
27062306a36Sopenharmony_ci	u64 xdp_actions[GVE_XDP_ACTIONS];
27162306a36Sopenharmony_ci	u32 q_num; /* queue index */
27262306a36Sopenharmony_ci	u32 ntfy_id; /* notification block index */
27362306a36Sopenharmony_ci	struct gve_queue_resources *q_resources; /* head and tail pointer idx */
27462306a36Sopenharmony_ci	dma_addr_t q_resources_bus; /* dma address for the queue resources */
27562306a36Sopenharmony_ci	struct u64_stats_sync statss; /* sync stats for 32bit archs */
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	struct gve_rx_ctx ctx; /* Info for packet currently being processed in this ring. */
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	/* XDP stuff */
28062306a36Sopenharmony_ci	struct xdp_rxq_info xdp_rxq;
28162306a36Sopenharmony_ci	struct xdp_rxq_info xsk_rxq;
28262306a36Sopenharmony_ci	struct xsk_buff_pool *xsk_pool;
28362306a36Sopenharmony_ci	struct page_frag_cache page_cache; /* Page cache to allocate XDP frames */
28462306a36Sopenharmony_ci};
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci/* A TX desc ring entry */
28762306a36Sopenharmony_ciunion gve_tx_desc {
28862306a36Sopenharmony_ci	struct gve_tx_pkt_desc pkt; /* first desc for a packet */
28962306a36Sopenharmony_ci	struct gve_tx_mtd_desc mtd; /* optional metadata descriptor */
29062306a36Sopenharmony_ci	struct gve_tx_seg_desc seg; /* subsequent descs for a packet */
29162306a36Sopenharmony_ci};
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci/* Tracks the memory in the fifo occupied by a segment of a packet */
29462306a36Sopenharmony_cistruct gve_tx_iovec {
29562306a36Sopenharmony_ci	u32 iov_offset; /* offset into this segment */
29662306a36Sopenharmony_ci	u32 iov_len; /* length */
29762306a36Sopenharmony_ci	u32 iov_padding; /* padding associated with this segment */
29862306a36Sopenharmony_ci};
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci/* Tracks the memory in the fifo occupied by the skb. Mapped 1:1 to a desc
30162306a36Sopenharmony_ci * ring entry but only used for a pkt_desc not a seg_desc
30262306a36Sopenharmony_ci */
30362306a36Sopenharmony_cistruct gve_tx_buffer_state {
30462306a36Sopenharmony_ci	union {
30562306a36Sopenharmony_ci		struct sk_buff *skb; /* skb for this pkt */
30662306a36Sopenharmony_ci		struct xdp_frame *xdp_frame; /* xdp_frame */
30762306a36Sopenharmony_ci	};
30862306a36Sopenharmony_ci	struct {
30962306a36Sopenharmony_ci		u16 size; /* size of xmitted xdp pkt */
31062306a36Sopenharmony_ci		u8 is_xsk; /* xsk buff */
31162306a36Sopenharmony_ci	} xdp;
31262306a36Sopenharmony_ci	union {
31362306a36Sopenharmony_ci		struct gve_tx_iovec iov[GVE_TX_MAX_IOVEC]; /* segments of this pkt */
31462306a36Sopenharmony_ci		struct {
31562306a36Sopenharmony_ci			DEFINE_DMA_UNMAP_ADDR(dma);
31662306a36Sopenharmony_ci			DEFINE_DMA_UNMAP_LEN(len);
31762306a36Sopenharmony_ci		};
31862306a36Sopenharmony_ci	};
31962306a36Sopenharmony_ci};
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci/* A TX buffer - each queue has one */
32262306a36Sopenharmony_cistruct gve_tx_fifo {
32362306a36Sopenharmony_ci	void *base; /* address of base of FIFO */
32462306a36Sopenharmony_ci	u32 size; /* total size */
32562306a36Sopenharmony_ci	atomic_t available; /* how much space is still available */
32662306a36Sopenharmony_ci	u32 head; /* offset to write at */
32762306a36Sopenharmony_ci	struct gve_queue_page_list *qpl; /* QPL mapped into this FIFO */
32862306a36Sopenharmony_ci};
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci/* TX descriptor for DQO format */
33162306a36Sopenharmony_ciunion gve_tx_desc_dqo {
33262306a36Sopenharmony_ci	struct gve_tx_pkt_desc_dqo pkt;
33362306a36Sopenharmony_ci	struct gve_tx_tso_context_desc_dqo tso_ctx;
33462306a36Sopenharmony_ci	struct gve_tx_general_context_desc_dqo general_ctx;
33562306a36Sopenharmony_ci};
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_cienum gve_packet_state {
33862306a36Sopenharmony_ci	/* Packet is in free list, available to be allocated.
33962306a36Sopenharmony_ci	 * This should always be zero since state is not explicitly initialized.
34062306a36Sopenharmony_ci	 */
34162306a36Sopenharmony_ci	GVE_PACKET_STATE_UNALLOCATED,
34262306a36Sopenharmony_ci	/* Packet is expecting a regular data completion or miss completion */
34362306a36Sopenharmony_ci	GVE_PACKET_STATE_PENDING_DATA_COMPL,
34462306a36Sopenharmony_ci	/* Packet has received a miss completion and is expecting a
34562306a36Sopenharmony_ci	 * re-injection completion.
34662306a36Sopenharmony_ci	 */
34762306a36Sopenharmony_ci	GVE_PACKET_STATE_PENDING_REINJECT_COMPL,
34862306a36Sopenharmony_ci	/* No valid completion received within the specified timeout. */
34962306a36Sopenharmony_ci	GVE_PACKET_STATE_TIMED_OUT_COMPL,
35062306a36Sopenharmony_ci};
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_cistruct gve_tx_pending_packet_dqo {
35362306a36Sopenharmony_ci	struct sk_buff *skb; /* skb for this packet */
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	/* 0th element corresponds to the linear portion of `skb`, should be
35662306a36Sopenharmony_ci	 * unmapped with `dma_unmap_single`.
35762306a36Sopenharmony_ci	 *
35862306a36Sopenharmony_ci	 * All others correspond to `skb`'s frags and should be unmapped with
35962306a36Sopenharmony_ci	 * `dma_unmap_page`.
36062306a36Sopenharmony_ci	 */
36162306a36Sopenharmony_ci	union {
36262306a36Sopenharmony_ci		struct {
36362306a36Sopenharmony_ci			DEFINE_DMA_UNMAP_ADDR(dma[MAX_SKB_FRAGS + 1]);
36462306a36Sopenharmony_ci			DEFINE_DMA_UNMAP_LEN(len[MAX_SKB_FRAGS + 1]);
36562306a36Sopenharmony_ci		};
36662306a36Sopenharmony_ci		s16 tx_qpl_buf_ids[GVE_MAX_TX_BUFS_PER_PKT];
36762306a36Sopenharmony_ci	};
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	u16 num_bufs;
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	/* Linked list index to next element in the list, or -1 if none */
37262306a36Sopenharmony_ci	s16 next;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	/* Linked list index to prev element in the list, or -1 if none.
37562306a36Sopenharmony_ci	 * Used for tracking either outstanding miss completions or prematurely
37662306a36Sopenharmony_ci	 * freed packets.
37762306a36Sopenharmony_ci	 */
37862306a36Sopenharmony_ci	s16 prev;
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	/* Identifies the current state of the packet as defined in
38162306a36Sopenharmony_ci	 * `enum gve_packet_state`.
38262306a36Sopenharmony_ci	 */
38362306a36Sopenharmony_ci	u8 state;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	/* If packet is an outstanding miss completion, then the packet is
38662306a36Sopenharmony_ci	 * freed if the corresponding re-injection completion is not received
38762306a36Sopenharmony_ci	 * before kernel jiffies exceeds timeout_jiffies.
38862306a36Sopenharmony_ci	 */
38962306a36Sopenharmony_ci	unsigned long timeout_jiffies;
39062306a36Sopenharmony_ci};
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci/* Contains datapath state used to represent a TX queue. */
39362306a36Sopenharmony_cistruct gve_tx_ring {
39462306a36Sopenharmony_ci	/* Cacheline 0 -- Accessed & dirtied during transmit */
39562306a36Sopenharmony_ci	union {
39662306a36Sopenharmony_ci		/* GQI fields */
39762306a36Sopenharmony_ci		struct {
39862306a36Sopenharmony_ci			struct gve_tx_fifo tx_fifo;
39962306a36Sopenharmony_ci			u32 req; /* driver tracked head pointer */
40062306a36Sopenharmony_ci			u32 done; /* driver tracked tail pointer */
40162306a36Sopenharmony_ci		};
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci		/* DQO fields. */
40462306a36Sopenharmony_ci		struct {
40562306a36Sopenharmony_ci			/* Linked list of gve_tx_pending_packet_dqo. Index into
40662306a36Sopenharmony_ci			 * pending_packets, or -1 if empty.
40762306a36Sopenharmony_ci			 *
40862306a36Sopenharmony_ci			 * This is a consumer list owned by the TX path. When it
40962306a36Sopenharmony_ci			 * runs out, the producer list is stolen from the
41062306a36Sopenharmony_ci			 * completion handling path
41162306a36Sopenharmony_ci			 * (dqo_compl.free_pending_packets).
41262306a36Sopenharmony_ci			 */
41362306a36Sopenharmony_ci			s16 free_pending_packets;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci			/* Cached value of `dqo_compl.hw_tx_head` */
41662306a36Sopenharmony_ci			u32 head;
41762306a36Sopenharmony_ci			u32 tail; /* Last posted buffer index + 1 */
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci			/* Index of the last descriptor with "report event" bit
42062306a36Sopenharmony_ci			 * set.
42162306a36Sopenharmony_ci			 */
42262306a36Sopenharmony_ci			u32 last_re_idx;
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci			/* free running number of packet buf descriptors posted */
42562306a36Sopenharmony_ci			u16 posted_packet_desc_cnt;
42662306a36Sopenharmony_ci			/* free running number of packet buf descriptors completed */
42762306a36Sopenharmony_ci			u16 completed_packet_desc_cnt;
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci			/* QPL fields */
43062306a36Sopenharmony_ci			struct {
43162306a36Sopenharmony_ci			       /* Linked list of gve_tx_buf_dqo. Index into
43262306a36Sopenharmony_ci				* tx_qpl_buf_next, or -1 if empty.
43362306a36Sopenharmony_ci				*
43462306a36Sopenharmony_ci				* This is a consumer list owned by the TX path. When it
43562306a36Sopenharmony_ci				* runs out, the producer list is stolen from the
43662306a36Sopenharmony_ci				* completion handling path
43762306a36Sopenharmony_ci				* (dqo_compl.free_tx_qpl_buf_head).
43862306a36Sopenharmony_ci				*/
43962306a36Sopenharmony_ci				s16 free_tx_qpl_buf_head;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci			       /* Free running count of the number of QPL tx buffers
44262306a36Sopenharmony_ci				* allocated
44362306a36Sopenharmony_ci				*/
44462306a36Sopenharmony_ci				u32 alloc_tx_qpl_buf_cnt;
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci				/* Cached value of `dqo_compl.free_tx_qpl_buf_cnt` */
44762306a36Sopenharmony_ci				u32 free_tx_qpl_buf_cnt;
44862306a36Sopenharmony_ci			};
44962306a36Sopenharmony_ci		} dqo_tx;
45062306a36Sopenharmony_ci	};
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci	/* Cacheline 1 -- Accessed & dirtied during gve_clean_tx_done */
45362306a36Sopenharmony_ci	union {
45462306a36Sopenharmony_ci		/* GQI fields */
45562306a36Sopenharmony_ci		struct {
45662306a36Sopenharmony_ci			/* Spinlock for when cleanup in progress */
45762306a36Sopenharmony_ci			spinlock_t clean_lock;
45862306a36Sopenharmony_ci			/* Spinlock for XDP tx traffic */
45962306a36Sopenharmony_ci			spinlock_t xdp_lock;
46062306a36Sopenharmony_ci		};
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci		/* DQO fields. */
46362306a36Sopenharmony_ci		struct {
46462306a36Sopenharmony_ci			u32 head; /* Last read on compl_desc */
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci			/* Tracks the current gen bit of compl_q */
46762306a36Sopenharmony_ci			u8 cur_gen_bit;
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci			/* Linked list of gve_tx_pending_packet_dqo. Index into
47062306a36Sopenharmony_ci			 * pending_packets, or -1 if empty.
47162306a36Sopenharmony_ci			 *
47262306a36Sopenharmony_ci			 * This is the producer list, owned by the completion
47362306a36Sopenharmony_ci			 * handling path. When the consumer list
47462306a36Sopenharmony_ci			 * (dqo_tx.free_pending_packets) is runs out, this list
47562306a36Sopenharmony_ci			 * will be stolen.
47662306a36Sopenharmony_ci			 */
47762306a36Sopenharmony_ci			atomic_t free_pending_packets;
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci			/* Last TX ring index fetched by HW */
48062306a36Sopenharmony_ci			atomic_t hw_tx_head;
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci			/* List to track pending packets which received a miss
48362306a36Sopenharmony_ci			 * completion but not a corresponding reinjection.
48462306a36Sopenharmony_ci			 */
48562306a36Sopenharmony_ci			struct gve_index_list miss_completions;
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci			/* List to track pending packets that were completed
48862306a36Sopenharmony_ci			 * before receiving a valid completion because they
48962306a36Sopenharmony_ci			 * reached a specified timeout.
49062306a36Sopenharmony_ci			 */
49162306a36Sopenharmony_ci			struct gve_index_list timed_out_completions;
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci			/* QPL fields */
49462306a36Sopenharmony_ci			struct {
49562306a36Sopenharmony_ci				/* Linked list of gve_tx_buf_dqo. Index into
49662306a36Sopenharmony_ci				 * tx_qpl_buf_next, or -1 if empty.
49762306a36Sopenharmony_ci				 *
49862306a36Sopenharmony_ci				 * This is the producer list, owned by the completion
49962306a36Sopenharmony_ci				 * handling path. When the consumer list
50062306a36Sopenharmony_ci				 * (dqo_tx.free_tx_qpl_buf_head) is runs out, this list
50162306a36Sopenharmony_ci				 * will be stolen.
50262306a36Sopenharmony_ci				 */
50362306a36Sopenharmony_ci				atomic_t free_tx_qpl_buf_head;
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci				/* Free running count of the number of tx buffers
50662306a36Sopenharmony_ci				 * freed
50762306a36Sopenharmony_ci				 */
50862306a36Sopenharmony_ci				atomic_t free_tx_qpl_buf_cnt;
50962306a36Sopenharmony_ci			};
51062306a36Sopenharmony_ci		} dqo_compl;
51162306a36Sopenharmony_ci	} ____cacheline_aligned;
51262306a36Sopenharmony_ci	u64 pkt_done; /* free-running - total packets completed */
51362306a36Sopenharmony_ci	u64 bytes_done; /* free-running - total bytes completed */
51462306a36Sopenharmony_ci	u64 dropped_pkt; /* free-running - total packets dropped */
51562306a36Sopenharmony_ci	u64 dma_mapping_error; /* count of dma mapping errors */
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	/* Cacheline 2 -- Read-mostly fields */
51862306a36Sopenharmony_ci	union {
51962306a36Sopenharmony_ci		/* GQI fields */
52062306a36Sopenharmony_ci		struct {
52162306a36Sopenharmony_ci			union gve_tx_desc *desc;
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci			/* Maps 1:1 to a desc */
52462306a36Sopenharmony_ci			struct gve_tx_buffer_state *info;
52562306a36Sopenharmony_ci		};
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci		/* DQO fields. */
52862306a36Sopenharmony_ci		struct {
52962306a36Sopenharmony_ci			union gve_tx_desc_dqo *tx_ring;
53062306a36Sopenharmony_ci			struct gve_tx_compl_desc *compl_ring;
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci			struct gve_tx_pending_packet_dqo *pending_packets;
53362306a36Sopenharmony_ci			s16 num_pending_packets;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci			u32 complq_mask; /* complq size is complq_mask + 1 */
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci			/* QPL fields */
53862306a36Sopenharmony_ci			struct {
53962306a36Sopenharmony_ci				/* qpl assigned to this queue */
54062306a36Sopenharmony_ci				struct gve_queue_page_list *qpl;
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci				/* Each QPL page is divided into TX bounce buffers
54362306a36Sopenharmony_ci				 * of size GVE_TX_BUF_SIZE_DQO. tx_qpl_buf_next is
54462306a36Sopenharmony_ci				 * an array to manage linked lists of TX buffers.
54562306a36Sopenharmony_ci				 * An entry j at index i implies that j'th buffer
54662306a36Sopenharmony_ci				 * is next on the list after i
54762306a36Sopenharmony_ci				 */
54862306a36Sopenharmony_ci				s16 *tx_qpl_buf_next;
54962306a36Sopenharmony_ci				u32 num_tx_qpl_bufs;
55062306a36Sopenharmony_ci			};
55162306a36Sopenharmony_ci		} dqo;
55262306a36Sopenharmony_ci	} ____cacheline_aligned;
55362306a36Sopenharmony_ci	struct netdev_queue *netdev_txq;
55462306a36Sopenharmony_ci	struct gve_queue_resources *q_resources; /* head and tail pointer idx */
55562306a36Sopenharmony_ci	struct device *dev;
55662306a36Sopenharmony_ci	u32 mask; /* masks req and done down to queue size */
55762306a36Sopenharmony_ci	u8 raw_addressing; /* use raw_addressing? */
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci	/* Slow-path fields */
56062306a36Sopenharmony_ci	u32 q_num ____cacheline_aligned; /* queue idx */
56162306a36Sopenharmony_ci	u32 stop_queue; /* count of queue stops */
56262306a36Sopenharmony_ci	u32 wake_queue; /* count of queue wakes */
56362306a36Sopenharmony_ci	u32 queue_timeout; /* count of queue timeouts */
56462306a36Sopenharmony_ci	u32 ntfy_id; /* notification block index */
56562306a36Sopenharmony_ci	u32 last_kick_msec; /* Last time the queue was kicked */
56662306a36Sopenharmony_ci	dma_addr_t bus; /* dma address of the descr ring */
56762306a36Sopenharmony_ci	dma_addr_t q_resources_bus; /* dma address of the queue resources */
56862306a36Sopenharmony_ci	dma_addr_t complq_bus_dqo; /* dma address of the dqo.compl_ring */
56962306a36Sopenharmony_ci	struct u64_stats_sync statss; /* sync stats for 32bit archs */
57062306a36Sopenharmony_ci	struct xsk_buff_pool *xsk_pool;
57162306a36Sopenharmony_ci	u32 xdp_xsk_wakeup;
57262306a36Sopenharmony_ci	u32 xdp_xsk_done;
57362306a36Sopenharmony_ci	u64 xdp_xsk_sent;
57462306a36Sopenharmony_ci	u64 xdp_xmit;
57562306a36Sopenharmony_ci	u64 xdp_xmit_errors;
57662306a36Sopenharmony_ci} ____cacheline_aligned;
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci/* Wraps the info for one irq including the napi struct and the queues
57962306a36Sopenharmony_ci * associated with that irq.
58062306a36Sopenharmony_ci */
58162306a36Sopenharmony_cistruct gve_notify_block {
58262306a36Sopenharmony_ci	__be32 *irq_db_index; /* pointer to idx into Bar2 */
58362306a36Sopenharmony_ci	char name[IFNAMSIZ + 16]; /* name registered with the kernel */
58462306a36Sopenharmony_ci	struct napi_struct napi; /* kernel napi struct for this block */
58562306a36Sopenharmony_ci	struct gve_priv *priv;
58662306a36Sopenharmony_ci	struct gve_tx_ring *tx; /* tx rings on this block */
58762306a36Sopenharmony_ci	struct gve_rx_ring *rx; /* rx rings on this block */
58862306a36Sopenharmony_ci};
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ci/* Tracks allowed and current queue settings */
59162306a36Sopenharmony_cistruct gve_queue_config {
59262306a36Sopenharmony_ci	u16 max_queues;
59362306a36Sopenharmony_ci	u16 num_queues; /* current */
59462306a36Sopenharmony_ci};
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci/* Tracks the available and used qpl IDs */
59762306a36Sopenharmony_cistruct gve_qpl_config {
59862306a36Sopenharmony_ci	u32 qpl_map_size; /* map memory size */
59962306a36Sopenharmony_ci	unsigned long *qpl_id_map; /* bitmap of used qpl ids */
60062306a36Sopenharmony_ci};
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_cistruct gve_options_dqo_rda {
60362306a36Sopenharmony_ci	u16 tx_comp_ring_entries; /* number of tx_comp descriptors */
60462306a36Sopenharmony_ci	u16 rx_buff_ring_entries; /* number of rx_buff descriptors */
60562306a36Sopenharmony_ci};
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_cistruct gve_irq_db {
60862306a36Sopenharmony_ci	__be32 index;
60962306a36Sopenharmony_ci} ____cacheline_aligned;
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_cistruct gve_ptype {
61262306a36Sopenharmony_ci	u8 l3_type;  /* `gve_l3_type` in gve_adminq.h */
61362306a36Sopenharmony_ci	u8 l4_type;  /* `gve_l4_type` in gve_adminq.h */
61462306a36Sopenharmony_ci};
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_cistruct gve_ptype_lut {
61762306a36Sopenharmony_ci	struct gve_ptype ptypes[GVE_NUM_PTYPES];
61862306a36Sopenharmony_ci};
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci/* GVE_QUEUE_FORMAT_UNSPECIFIED must be zero since 0 is the default value
62162306a36Sopenharmony_ci * when the entire configure_device_resources command is zeroed out and the
62262306a36Sopenharmony_ci * queue_format is not specified.
62362306a36Sopenharmony_ci */
62462306a36Sopenharmony_cienum gve_queue_format {
62562306a36Sopenharmony_ci	GVE_QUEUE_FORMAT_UNSPECIFIED	= 0x0,
62662306a36Sopenharmony_ci	GVE_GQI_RDA_FORMAT		= 0x1,
62762306a36Sopenharmony_ci	GVE_GQI_QPL_FORMAT		= 0x2,
62862306a36Sopenharmony_ci	GVE_DQO_RDA_FORMAT		= 0x3,
62962306a36Sopenharmony_ci	GVE_DQO_QPL_FORMAT		= 0x4,
63062306a36Sopenharmony_ci};
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_cistruct gve_priv {
63362306a36Sopenharmony_ci	struct net_device *dev;
63462306a36Sopenharmony_ci	struct gve_tx_ring *tx; /* array of tx_cfg.num_queues */
63562306a36Sopenharmony_ci	struct gve_rx_ring *rx; /* array of rx_cfg.num_queues */
63662306a36Sopenharmony_ci	struct gve_queue_page_list *qpls; /* array of num qpls */
63762306a36Sopenharmony_ci	struct gve_notify_block *ntfy_blocks; /* array of num_ntfy_blks */
63862306a36Sopenharmony_ci	struct gve_irq_db *irq_db_indices; /* array of num_ntfy_blks */
63962306a36Sopenharmony_ci	dma_addr_t irq_db_indices_bus;
64062306a36Sopenharmony_ci	struct msix_entry *msix_vectors; /* array of num_ntfy_blks + 1 */
64162306a36Sopenharmony_ci	char mgmt_msix_name[IFNAMSIZ + 16];
64262306a36Sopenharmony_ci	u32 mgmt_msix_idx;
64362306a36Sopenharmony_ci	__be32 *counter_array; /* array of num_event_counters */
64462306a36Sopenharmony_ci	dma_addr_t counter_array_bus;
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci	u16 num_event_counters;
64762306a36Sopenharmony_ci	u16 tx_desc_cnt; /* num desc per ring */
64862306a36Sopenharmony_ci	u16 rx_desc_cnt; /* num desc per ring */
64962306a36Sopenharmony_ci	u16 tx_pages_per_qpl; /* Suggested number of pages per qpl for TX queues by NIC */
65062306a36Sopenharmony_ci	u16 rx_pages_per_qpl; /* Suggested number of pages per qpl for RX queues by NIC */
65162306a36Sopenharmony_ci	u16 rx_data_slot_cnt; /* rx buffer length */
65262306a36Sopenharmony_ci	u64 max_registered_pages;
65362306a36Sopenharmony_ci	u64 num_registered_pages; /* num pages registered with NIC */
65462306a36Sopenharmony_ci	struct bpf_prog *xdp_prog; /* XDP BPF program */
65562306a36Sopenharmony_ci	u32 rx_copybreak; /* copy packets smaller than this */
65662306a36Sopenharmony_ci	u16 default_num_queues; /* default num queues to set up */
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci	u16 num_xdp_queues;
65962306a36Sopenharmony_ci	struct gve_queue_config tx_cfg;
66062306a36Sopenharmony_ci	struct gve_queue_config rx_cfg;
66162306a36Sopenharmony_ci	struct gve_qpl_config qpl_cfg; /* map used QPL ids */
66262306a36Sopenharmony_ci	u32 num_ntfy_blks; /* spilt between TX and RX so must be even */
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	struct gve_registers __iomem *reg_bar0; /* see gve_register.h */
66562306a36Sopenharmony_ci	__be32 __iomem *db_bar2; /* "array" of doorbells */
66662306a36Sopenharmony_ci	u32 msg_enable;	/* level for netif* netdev print macros	*/
66762306a36Sopenharmony_ci	struct pci_dev *pdev;
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	/* metrics */
67062306a36Sopenharmony_ci	u32 tx_timeo_cnt;
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	/* Admin queue - see gve_adminq.h*/
67362306a36Sopenharmony_ci	union gve_adminq_command *adminq;
67462306a36Sopenharmony_ci	dma_addr_t adminq_bus_addr;
67562306a36Sopenharmony_ci	u32 adminq_mask; /* masks prod_cnt to adminq size */
67662306a36Sopenharmony_ci	u32 adminq_prod_cnt; /* free-running count of AQ cmds executed */
67762306a36Sopenharmony_ci	u32 adminq_cmd_fail; /* free-running count of AQ cmds failed */
67862306a36Sopenharmony_ci	u32 adminq_timeouts; /* free-running count of AQ cmds timeouts */
67962306a36Sopenharmony_ci	/* free-running count of per AQ cmd executed */
68062306a36Sopenharmony_ci	u32 adminq_describe_device_cnt;
68162306a36Sopenharmony_ci	u32 adminq_cfg_device_resources_cnt;
68262306a36Sopenharmony_ci	u32 adminq_register_page_list_cnt;
68362306a36Sopenharmony_ci	u32 adminq_unregister_page_list_cnt;
68462306a36Sopenharmony_ci	u32 adminq_create_tx_queue_cnt;
68562306a36Sopenharmony_ci	u32 adminq_create_rx_queue_cnt;
68662306a36Sopenharmony_ci	u32 adminq_destroy_tx_queue_cnt;
68762306a36Sopenharmony_ci	u32 adminq_destroy_rx_queue_cnt;
68862306a36Sopenharmony_ci	u32 adminq_dcfg_device_resources_cnt;
68962306a36Sopenharmony_ci	u32 adminq_set_driver_parameter_cnt;
69062306a36Sopenharmony_ci	u32 adminq_report_stats_cnt;
69162306a36Sopenharmony_ci	u32 adminq_report_link_speed_cnt;
69262306a36Sopenharmony_ci	u32 adminq_get_ptype_map_cnt;
69362306a36Sopenharmony_ci	u32 adminq_verify_driver_compatibility_cnt;
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci	/* Global stats */
69662306a36Sopenharmony_ci	u32 interface_up_cnt; /* count of times interface turned up since last reset */
69762306a36Sopenharmony_ci	u32 interface_down_cnt; /* count of times interface turned down since last reset */
69862306a36Sopenharmony_ci	u32 reset_cnt; /* count of reset */
69962306a36Sopenharmony_ci	u32 page_alloc_fail; /* count of page alloc fails */
70062306a36Sopenharmony_ci	u32 dma_mapping_error; /* count of dma mapping errors */
70162306a36Sopenharmony_ci	u32 stats_report_trigger_cnt; /* count of device-requested stats-reports since last reset */
70262306a36Sopenharmony_ci	u32 suspend_cnt; /* count of times suspended */
70362306a36Sopenharmony_ci	u32 resume_cnt; /* count of times resumed */
70462306a36Sopenharmony_ci	struct workqueue_struct *gve_wq;
70562306a36Sopenharmony_ci	struct work_struct service_task;
70662306a36Sopenharmony_ci	struct work_struct stats_report_task;
70762306a36Sopenharmony_ci	unsigned long service_task_flags;
70862306a36Sopenharmony_ci	unsigned long state_flags;
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	struct gve_stats_report *stats_report;
71162306a36Sopenharmony_ci	u64 stats_report_len;
71262306a36Sopenharmony_ci	dma_addr_t stats_report_bus; /* dma address for the stats report */
71362306a36Sopenharmony_ci	unsigned long ethtool_flags;
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci	unsigned long stats_report_timer_period;
71662306a36Sopenharmony_ci	struct timer_list stats_report_timer;
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci	/* Gvnic device link speed from hypervisor. */
71962306a36Sopenharmony_ci	u64 link_speed;
72062306a36Sopenharmony_ci	bool up_before_suspend; /* True if dev was up before suspend */
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci	struct gve_options_dqo_rda options_dqo_rda;
72362306a36Sopenharmony_ci	struct gve_ptype_lut *ptype_lut_dqo;
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci	/* Must be a power of two. */
72662306a36Sopenharmony_ci	int data_buffer_size_dqo;
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	enum gve_queue_format queue_format;
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	/* Interrupt coalescing settings */
73162306a36Sopenharmony_ci	u32 tx_coalesce_usecs;
73262306a36Sopenharmony_ci	u32 rx_coalesce_usecs;
73362306a36Sopenharmony_ci};
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_cienum gve_service_task_flags_bit {
73662306a36Sopenharmony_ci	GVE_PRIV_FLAGS_DO_RESET			= 1,
73762306a36Sopenharmony_ci	GVE_PRIV_FLAGS_RESET_IN_PROGRESS	= 2,
73862306a36Sopenharmony_ci	GVE_PRIV_FLAGS_PROBE_IN_PROGRESS	= 3,
73962306a36Sopenharmony_ci	GVE_PRIV_FLAGS_DO_REPORT_STATS = 4,
74062306a36Sopenharmony_ci};
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_cienum gve_state_flags_bit {
74362306a36Sopenharmony_ci	GVE_PRIV_FLAGS_ADMIN_QUEUE_OK		= 1,
74462306a36Sopenharmony_ci	GVE_PRIV_FLAGS_DEVICE_RESOURCES_OK	= 2,
74562306a36Sopenharmony_ci	GVE_PRIV_FLAGS_DEVICE_RINGS_OK		= 3,
74662306a36Sopenharmony_ci	GVE_PRIV_FLAGS_NAPI_ENABLED		= 4,
74762306a36Sopenharmony_ci};
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_cienum gve_ethtool_flags_bit {
75062306a36Sopenharmony_ci	GVE_PRIV_FLAGS_REPORT_STATS		= 0,
75162306a36Sopenharmony_ci};
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_cistatic inline bool gve_get_do_reset(struct gve_priv *priv)
75462306a36Sopenharmony_ci{
75562306a36Sopenharmony_ci	return test_bit(GVE_PRIV_FLAGS_DO_RESET, &priv->service_task_flags);
75662306a36Sopenharmony_ci}
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_cistatic inline void gve_set_do_reset(struct gve_priv *priv)
75962306a36Sopenharmony_ci{
76062306a36Sopenharmony_ci	set_bit(GVE_PRIV_FLAGS_DO_RESET, &priv->service_task_flags);
76162306a36Sopenharmony_ci}
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_cistatic inline void gve_clear_do_reset(struct gve_priv *priv)
76462306a36Sopenharmony_ci{
76562306a36Sopenharmony_ci	clear_bit(GVE_PRIV_FLAGS_DO_RESET, &priv->service_task_flags);
76662306a36Sopenharmony_ci}
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_cistatic inline bool gve_get_reset_in_progress(struct gve_priv *priv)
76962306a36Sopenharmony_ci{
77062306a36Sopenharmony_ci	return test_bit(GVE_PRIV_FLAGS_RESET_IN_PROGRESS,
77162306a36Sopenharmony_ci			&priv->service_task_flags);
77262306a36Sopenharmony_ci}
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_cistatic inline void gve_set_reset_in_progress(struct gve_priv *priv)
77562306a36Sopenharmony_ci{
77662306a36Sopenharmony_ci	set_bit(GVE_PRIV_FLAGS_RESET_IN_PROGRESS, &priv->service_task_flags);
77762306a36Sopenharmony_ci}
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_cistatic inline void gve_clear_reset_in_progress(struct gve_priv *priv)
78062306a36Sopenharmony_ci{
78162306a36Sopenharmony_ci	clear_bit(GVE_PRIV_FLAGS_RESET_IN_PROGRESS, &priv->service_task_flags);
78262306a36Sopenharmony_ci}
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_cistatic inline bool gve_get_probe_in_progress(struct gve_priv *priv)
78562306a36Sopenharmony_ci{
78662306a36Sopenharmony_ci	return test_bit(GVE_PRIV_FLAGS_PROBE_IN_PROGRESS,
78762306a36Sopenharmony_ci			&priv->service_task_flags);
78862306a36Sopenharmony_ci}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_cistatic inline void gve_set_probe_in_progress(struct gve_priv *priv)
79162306a36Sopenharmony_ci{
79262306a36Sopenharmony_ci	set_bit(GVE_PRIV_FLAGS_PROBE_IN_PROGRESS, &priv->service_task_flags);
79362306a36Sopenharmony_ci}
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_cistatic inline void gve_clear_probe_in_progress(struct gve_priv *priv)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	clear_bit(GVE_PRIV_FLAGS_PROBE_IN_PROGRESS, &priv->service_task_flags);
79862306a36Sopenharmony_ci}
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_cistatic inline bool gve_get_do_report_stats(struct gve_priv *priv)
80162306a36Sopenharmony_ci{
80262306a36Sopenharmony_ci	return test_bit(GVE_PRIV_FLAGS_DO_REPORT_STATS,
80362306a36Sopenharmony_ci			&priv->service_task_flags);
80462306a36Sopenharmony_ci}
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_cistatic inline void gve_set_do_report_stats(struct gve_priv *priv)
80762306a36Sopenharmony_ci{
80862306a36Sopenharmony_ci	set_bit(GVE_PRIV_FLAGS_DO_REPORT_STATS, &priv->service_task_flags);
80962306a36Sopenharmony_ci}
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_cistatic inline void gve_clear_do_report_stats(struct gve_priv *priv)
81262306a36Sopenharmony_ci{
81362306a36Sopenharmony_ci	clear_bit(GVE_PRIV_FLAGS_DO_REPORT_STATS, &priv->service_task_flags);
81462306a36Sopenharmony_ci}
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_cistatic inline bool gve_get_admin_queue_ok(struct gve_priv *priv)
81762306a36Sopenharmony_ci{
81862306a36Sopenharmony_ci	return test_bit(GVE_PRIV_FLAGS_ADMIN_QUEUE_OK, &priv->state_flags);
81962306a36Sopenharmony_ci}
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_cistatic inline void gve_set_admin_queue_ok(struct gve_priv *priv)
82262306a36Sopenharmony_ci{
82362306a36Sopenharmony_ci	set_bit(GVE_PRIV_FLAGS_ADMIN_QUEUE_OK, &priv->state_flags);
82462306a36Sopenharmony_ci}
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_cistatic inline void gve_clear_admin_queue_ok(struct gve_priv *priv)
82762306a36Sopenharmony_ci{
82862306a36Sopenharmony_ci	clear_bit(GVE_PRIV_FLAGS_ADMIN_QUEUE_OK, &priv->state_flags);
82962306a36Sopenharmony_ci}
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_cistatic inline bool gve_get_device_resources_ok(struct gve_priv *priv)
83262306a36Sopenharmony_ci{
83362306a36Sopenharmony_ci	return test_bit(GVE_PRIV_FLAGS_DEVICE_RESOURCES_OK, &priv->state_flags);
83462306a36Sopenharmony_ci}
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_cistatic inline void gve_set_device_resources_ok(struct gve_priv *priv)
83762306a36Sopenharmony_ci{
83862306a36Sopenharmony_ci	set_bit(GVE_PRIV_FLAGS_DEVICE_RESOURCES_OK, &priv->state_flags);
83962306a36Sopenharmony_ci}
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_cistatic inline void gve_clear_device_resources_ok(struct gve_priv *priv)
84262306a36Sopenharmony_ci{
84362306a36Sopenharmony_ci	clear_bit(GVE_PRIV_FLAGS_DEVICE_RESOURCES_OK, &priv->state_flags);
84462306a36Sopenharmony_ci}
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_cistatic inline bool gve_get_device_rings_ok(struct gve_priv *priv)
84762306a36Sopenharmony_ci{
84862306a36Sopenharmony_ci	return test_bit(GVE_PRIV_FLAGS_DEVICE_RINGS_OK, &priv->state_flags);
84962306a36Sopenharmony_ci}
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_cistatic inline void gve_set_device_rings_ok(struct gve_priv *priv)
85262306a36Sopenharmony_ci{
85362306a36Sopenharmony_ci	set_bit(GVE_PRIV_FLAGS_DEVICE_RINGS_OK, &priv->state_flags);
85462306a36Sopenharmony_ci}
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_cistatic inline void gve_clear_device_rings_ok(struct gve_priv *priv)
85762306a36Sopenharmony_ci{
85862306a36Sopenharmony_ci	clear_bit(GVE_PRIV_FLAGS_DEVICE_RINGS_OK, &priv->state_flags);
85962306a36Sopenharmony_ci}
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_cistatic inline bool gve_get_napi_enabled(struct gve_priv *priv)
86262306a36Sopenharmony_ci{
86362306a36Sopenharmony_ci	return test_bit(GVE_PRIV_FLAGS_NAPI_ENABLED, &priv->state_flags);
86462306a36Sopenharmony_ci}
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_cistatic inline void gve_set_napi_enabled(struct gve_priv *priv)
86762306a36Sopenharmony_ci{
86862306a36Sopenharmony_ci	set_bit(GVE_PRIV_FLAGS_NAPI_ENABLED, &priv->state_flags);
86962306a36Sopenharmony_ci}
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_cistatic inline void gve_clear_napi_enabled(struct gve_priv *priv)
87262306a36Sopenharmony_ci{
87362306a36Sopenharmony_ci	clear_bit(GVE_PRIV_FLAGS_NAPI_ENABLED, &priv->state_flags);
87462306a36Sopenharmony_ci}
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_cistatic inline bool gve_get_report_stats(struct gve_priv *priv)
87762306a36Sopenharmony_ci{
87862306a36Sopenharmony_ci	return test_bit(GVE_PRIV_FLAGS_REPORT_STATS, &priv->ethtool_flags);
87962306a36Sopenharmony_ci}
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_cistatic inline void gve_clear_report_stats(struct gve_priv *priv)
88262306a36Sopenharmony_ci{
88362306a36Sopenharmony_ci	clear_bit(GVE_PRIV_FLAGS_REPORT_STATS, &priv->ethtool_flags);
88462306a36Sopenharmony_ci}
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_ci/* Returns the address of the ntfy_blocks irq doorbell
88762306a36Sopenharmony_ci */
88862306a36Sopenharmony_cistatic inline __be32 __iomem *gve_irq_doorbell(struct gve_priv *priv,
88962306a36Sopenharmony_ci					       struct gve_notify_block *block)
89062306a36Sopenharmony_ci{
89162306a36Sopenharmony_ci	return &priv->db_bar2[be32_to_cpu(*block->irq_db_index)];
89262306a36Sopenharmony_ci}
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci/* Returns the index into ntfy_blocks of the given tx ring's block
89562306a36Sopenharmony_ci */
89662306a36Sopenharmony_cistatic inline u32 gve_tx_idx_to_ntfy(struct gve_priv *priv, u32 queue_idx)
89762306a36Sopenharmony_ci{
89862306a36Sopenharmony_ci	return queue_idx;
89962306a36Sopenharmony_ci}
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci/* Returns the index into ntfy_blocks of the given rx ring's block
90262306a36Sopenharmony_ci */
90362306a36Sopenharmony_cistatic inline u32 gve_rx_idx_to_ntfy(struct gve_priv *priv, u32 queue_idx)
90462306a36Sopenharmony_ci{
90562306a36Sopenharmony_ci	return (priv->num_ntfy_blks / 2) + queue_idx;
90662306a36Sopenharmony_ci}
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_cistatic inline bool gve_is_qpl(struct gve_priv *priv)
90962306a36Sopenharmony_ci{
91062306a36Sopenharmony_ci	return priv->queue_format == GVE_GQI_QPL_FORMAT ||
91162306a36Sopenharmony_ci		priv->queue_format == GVE_DQO_QPL_FORMAT;
91262306a36Sopenharmony_ci}
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci/* Returns the number of tx queue page lists
91562306a36Sopenharmony_ci */
91662306a36Sopenharmony_cistatic inline u32 gve_num_tx_qpls(struct gve_priv *priv)
91762306a36Sopenharmony_ci{
91862306a36Sopenharmony_ci	if (!gve_is_qpl(priv))
91962306a36Sopenharmony_ci		return 0;
92062306a36Sopenharmony_ci
92162306a36Sopenharmony_ci	return priv->tx_cfg.num_queues + priv->num_xdp_queues;
92262306a36Sopenharmony_ci}
92362306a36Sopenharmony_ci
92462306a36Sopenharmony_ci/* Returns the number of XDP tx queue page lists
92562306a36Sopenharmony_ci */
92662306a36Sopenharmony_cistatic inline u32 gve_num_xdp_qpls(struct gve_priv *priv)
92762306a36Sopenharmony_ci{
92862306a36Sopenharmony_ci	if (priv->queue_format != GVE_GQI_QPL_FORMAT)
92962306a36Sopenharmony_ci		return 0;
93062306a36Sopenharmony_ci
93162306a36Sopenharmony_ci	return priv->num_xdp_queues;
93262306a36Sopenharmony_ci}
93362306a36Sopenharmony_ci
93462306a36Sopenharmony_ci/* Returns the number of rx queue page lists
93562306a36Sopenharmony_ci */
93662306a36Sopenharmony_cistatic inline u32 gve_num_rx_qpls(struct gve_priv *priv)
93762306a36Sopenharmony_ci{
93862306a36Sopenharmony_ci	if (!gve_is_qpl(priv))
93962306a36Sopenharmony_ci		return 0;
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci	return priv->rx_cfg.num_queues;
94262306a36Sopenharmony_ci}
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_cistatic inline u32 gve_tx_qpl_id(struct gve_priv *priv, int tx_qid)
94562306a36Sopenharmony_ci{
94662306a36Sopenharmony_ci	return tx_qid;
94762306a36Sopenharmony_ci}
94862306a36Sopenharmony_ci
94962306a36Sopenharmony_cistatic inline u32 gve_rx_qpl_id(struct gve_priv *priv, int rx_qid)
95062306a36Sopenharmony_ci{
95162306a36Sopenharmony_ci	return priv->tx_cfg.max_queues + rx_qid;
95262306a36Sopenharmony_ci}
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_cistatic inline u32 gve_tx_start_qpl_id(struct gve_priv *priv)
95562306a36Sopenharmony_ci{
95662306a36Sopenharmony_ci	return gve_tx_qpl_id(priv, 0);
95762306a36Sopenharmony_ci}
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_cistatic inline u32 gve_rx_start_qpl_id(struct gve_priv *priv)
96062306a36Sopenharmony_ci{
96162306a36Sopenharmony_ci	return gve_rx_qpl_id(priv, 0);
96262306a36Sopenharmony_ci}
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci/* Returns a pointer to the next available tx qpl in the list of qpls
96562306a36Sopenharmony_ci */
96662306a36Sopenharmony_cistatic inline
96762306a36Sopenharmony_cistruct gve_queue_page_list *gve_assign_tx_qpl(struct gve_priv *priv, int tx_qid)
96862306a36Sopenharmony_ci{
96962306a36Sopenharmony_ci	int id = gve_tx_qpl_id(priv, tx_qid);
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci	/* QPL already in use */
97262306a36Sopenharmony_ci	if (test_bit(id, priv->qpl_cfg.qpl_id_map))
97362306a36Sopenharmony_ci		return NULL;
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci	set_bit(id, priv->qpl_cfg.qpl_id_map);
97662306a36Sopenharmony_ci	return &priv->qpls[id];
97762306a36Sopenharmony_ci}
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci/* Returns a pointer to the next available rx qpl in the list of qpls
98062306a36Sopenharmony_ci */
98162306a36Sopenharmony_cistatic inline
98262306a36Sopenharmony_cistruct gve_queue_page_list *gve_assign_rx_qpl(struct gve_priv *priv, int rx_qid)
98362306a36Sopenharmony_ci{
98462306a36Sopenharmony_ci	int id = gve_rx_qpl_id(priv, rx_qid);
98562306a36Sopenharmony_ci
98662306a36Sopenharmony_ci	/* QPL already in use */
98762306a36Sopenharmony_ci	if (test_bit(id, priv->qpl_cfg.qpl_id_map))
98862306a36Sopenharmony_ci		return NULL;
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci	set_bit(id, priv->qpl_cfg.qpl_id_map);
99162306a36Sopenharmony_ci	return &priv->qpls[id];
99262306a36Sopenharmony_ci}
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci/* Unassigns the qpl with the given id
99562306a36Sopenharmony_ci */
99662306a36Sopenharmony_cistatic inline void gve_unassign_qpl(struct gve_priv *priv, int id)
99762306a36Sopenharmony_ci{
99862306a36Sopenharmony_ci	clear_bit(id, priv->qpl_cfg.qpl_id_map);
99962306a36Sopenharmony_ci}
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci/* Returns the correct dma direction for tx and rx qpls
100262306a36Sopenharmony_ci */
100362306a36Sopenharmony_cistatic inline enum dma_data_direction gve_qpl_dma_dir(struct gve_priv *priv,
100462306a36Sopenharmony_ci						      int id)
100562306a36Sopenharmony_ci{
100662306a36Sopenharmony_ci	if (id < gve_rx_start_qpl_id(priv))
100762306a36Sopenharmony_ci		return DMA_TO_DEVICE;
100862306a36Sopenharmony_ci	else
100962306a36Sopenharmony_ci		return DMA_FROM_DEVICE;
101062306a36Sopenharmony_ci}
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_cistatic inline bool gve_is_gqi(struct gve_priv *priv)
101362306a36Sopenharmony_ci{
101462306a36Sopenharmony_ci	return priv->queue_format == GVE_GQI_RDA_FORMAT ||
101562306a36Sopenharmony_ci		priv->queue_format == GVE_GQI_QPL_FORMAT;
101662306a36Sopenharmony_ci}
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_cistatic inline u32 gve_num_tx_queues(struct gve_priv *priv)
101962306a36Sopenharmony_ci{
102062306a36Sopenharmony_ci	return priv->tx_cfg.num_queues + priv->num_xdp_queues;
102162306a36Sopenharmony_ci}
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_cistatic inline u32 gve_xdp_tx_queue_id(struct gve_priv *priv, u32 queue_id)
102462306a36Sopenharmony_ci{
102562306a36Sopenharmony_ci	return priv->tx_cfg.num_queues + queue_id;
102662306a36Sopenharmony_ci}
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_cistatic inline u32 gve_xdp_tx_start_queue_id(struct gve_priv *priv)
102962306a36Sopenharmony_ci{
103062306a36Sopenharmony_ci	return gve_xdp_tx_queue_id(priv, 0);
103162306a36Sopenharmony_ci}
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci/* buffers */
103462306a36Sopenharmony_ciint gve_alloc_page(struct gve_priv *priv, struct device *dev,
103562306a36Sopenharmony_ci		   struct page **page, dma_addr_t *dma,
103662306a36Sopenharmony_ci		   enum dma_data_direction, gfp_t gfp_flags);
103762306a36Sopenharmony_civoid gve_free_page(struct device *dev, struct page *page, dma_addr_t dma,
103862306a36Sopenharmony_ci		   enum dma_data_direction);
103962306a36Sopenharmony_ci/* tx handling */
104062306a36Sopenharmony_cinetdev_tx_t gve_tx(struct sk_buff *skb, struct net_device *dev);
104162306a36Sopenharmony_ciint gve_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
104262306a36Sopenharmony_ci		 u32 flags);
104362306a36Sopenharmony_ciint gve_xdp_xmit_one(struct gve_priv *priv, struct gve_tx_ring *tx,
104462306a36Sopenharmony_ci		     void *data, int len, void *frame_p);
104562306a36Sopenharmony_civoid gve_xdp_tx_flush(struct gve_priv *priv, u32 xdp_qid);
104662306a36Sopenharmony_cibool gve_tx_poll(struct gve_notify_block *block, int budget);
104762306a36Sopenharmony_cibool gve_xdp_poll(struct gve_notify_block *block, int budget);
104862306a36Sopenharmony_ciint gve_tx_alloc_rings(struct gve_priv *priv, int start_id, int num_rings);
104962306a36Sopenharmony_civoid gve_tx_free_rings_gqi(struct gve_priv *priv, int start_id, int num_rings);
105062306a36Sopenharmony_ciu32 gve_tx_load_event_counter(struct gve_priv *priv,
105162306a36Sopenharmony_ci			      struct gve_tx_ring *tx);
105262306a36Sopenharmony_cibool gve_tx_clean_pending(struct gve_priv *priv, struct gve_tx_ring *tx);
105362306a36Sopenharmony_ci/* rx handling */
105462306a36Sopenharmony_civoid gve_rx_write_doorbell(struct gve_priv *priv, struct gve_rx_ring *rx);
105562306a36Sopenharmony_ciint gve_rx_poll(struct gve_notify_block *block, int budget);
105662306a36Sopenharmony_cibool gve_rx_work_pending(struct gve_rx_ring *rx);
105762306a36Sopenharmony_ciint gve_rx_alloc_rings(struct gve_priv *priv);
105862306a36Sopenharmony_civoid gve_rx_free_rings_gqi(struct gve_priv *priv);
105962306a36Sopenharmony_ci/* Reset */
106062306a36Sopenharmony_civoid gve_schedule_reset(struct gve_priv *priv);
106162306a36Sopenharmony_ciint gve_reset(struct gve_priv *priv, bool attempt_teardown);
106262306a36Sopenharmony_ciint gve_adjust_queues(struct gve_priv *priv,
106362306a36Sopenharmony_ci		      struct gve_queue_config new_rx_config,
106462306a36Sopenharmony_ci		      struct gve_queue_config new_tx_config);
106562306a36Sopenharmony_ci/* report stats handling */
106662306a36Sopenharmony_civoid gve_handle_report_stats(struct gve_priv *priv);
106762306a36Sopenharmony_ci/* exported by ethtool.c */
106862306a36Sopenharmony_ciextern const struct ethtool_ops gve_ethtool_ops;
106962306a36Sopenharmony_ci/* needed by ethtool */
107062306a36Sopenharmony_ciextern char gve_driver_name[];
107162306a36Sopenharmony_ciextern const char gve_version_str[];
107262306a36Sopenharmony_ci#endif /* _GVE_H_ */
1073