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