| /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ | 
 | /* Copyright (c) 2021, Microsoft Corporation. */ | 
 |  | 
 | #ifndef _GDMA_H | 
 | #define _GDMA_H | 
 |  | 
 | #include <linux/dma-mapping.h> | 
 | #include <linux/netdevice.h> | 
 |  | 
 | #include "shm_channel.h" | 
 |  | 
 | #define GDMA_STATUS_MORE_ENTRIES	0x00000105 | 
 |  | 
 | /* Structures labeled with "HW DATA" are exchanged with the hardware. All of | 
 |  * them are naturally aligned and hence don't need __packed. | 
 |  */ | 
 |  | 
 | enum gdma_request_type { | 
 | 	GDMA_VERIFY_VF_DRIVER_VERSION	= 1, | 
 | 	GDMA_QUERY_MAX_RESOURCES	= 2, | 
 | 	GDMA_LIST_DEVICES		= 3, | 
 | 	GDMA_REGISTER_DEVICE		= 4, | 
 | 	GDMA_DEREGISTER_DEVICE		= 5, | 
 | 	GDMA_GENERATE_TEST_EQE		= 10, | 
 | 	GDMA_CREATE_QUEUE		= 12, | 
 | 	GDMA_DISABLE_QUEUE		= 13, | 
 | 	GDMA_ALLOCATE_RESOURCE_RANGE	= 22, | 
 | 	GDMA_DESTROY_RESOURCE_RANGE	= 24, | 
 | 	GDMA_CREATE_DMA_REGION		= 25, | 
 | 	GDMA_DMA_REGION_ADD_PAGES	= 26, | 
 | 	GDMA_DESTROY_DMA_REGION		= 27, | 
 | 	GDMA_CREATE_PD			= 29, | 
 | 	GDMA_DESTROY_PD			= 30, | 
 | 	GDMA_CREATE_MR			= 31, | 
 | 	GDMA_DESTROY_MR			= 32, | 
 | 	GDMA_QUERY_HWC_TIMEOUT		= 84, /* 0x54 */ | 
 | }; | 
 |  | 
 | #define GDMA_RESOURCE_DOORBELL_PAGE	27 | 
 |  | 
 | enum gdma_queue_type { | 
 | 	GDMA_INVALID_QUEUE, | 
 | 	GDMA_SQ, | 
 | 	GDMA_RQ, | 
 | 	GDMA_CQ, | 
 | 	GDMA_EQ, | 
 | }; | 
 |  | 
 | enum gdma_work_request_flags { | 
 | 	GDMA_WR_NONE			= 0, | 
 | 	GDMA_WR_OOB_IN_SGL		= BIT(0), | 
 | 	GDMA_WR_PAD_BY_SGE0		= BIT(1), | 
 | }; | 
 |  | 
 | enum gdma_eqe_type { | 
 | 	GDMA_EQE_COMPLETION		= 3, | 
 | 	GDMA_EQE_TEST_EVENT		= 64, | 
 | 	GDMA_EQE_HWC_INIT_EQ_ID_DB	= 129, | 
 | 	GDMA_EQE_HWC_INIT_DATA		= 130, | 
 | 	GDMA_EQE_HWC_INIT_DONE		= 131, | 
 | 	GDMA_EQE_HWC_SOC_RECONFIG	= 132, | 
 | 	GDMA_EQE_HWC_SOC_RECONFIG_DATA	= 133, | 
 | }; | 
 |  | 
 | enum { | 
 | 	GDMA_DEVICE_NONE	= 0, | 
 | 	GDMA_DEVICE_HWC		= 1, | 
 | 	GDMA_DEVICE_MANA	= 2, | 
 | }; | 
 |  | 
 | struct gdma_resource { | 
 | 	/* Protect the bitmap */ | 
 | 	spinlock_t lock; | 
 |  | 
 | 	/* The bitmap size in bits. */ | 
 | 	u32 size; | 
 |  | 
 | 	/* The bitmap tracks the resources. */ | 
 | 	unsigned long *map; | 
 | }; | 
 |  | 
 | union gdma_doorbell_entry { | 
 | 	u64	as_uint64; | 
 |  | 
 | 	struct { | 
 | 		u64 id		: 24; | 
 | 		u64 reserved	: 8; | 
 | 		u64 tail_ptr	: 31; | 
 | 		u64 arm		: 1; | 
 | 	} cq; | 
 |  | 
 | 	struct { | 
 | 		u64 id		: 24; | 
 | 		u64 wqe_cnt	: 8; | 
 | 		u64 tail_ptr	: 32; | 
 | 	} rq; | 
 |  | 
 | 	struct { | 
 | 		u64 id		: 24; | 
 | 		u64 reserved	: 8; | 
 | 		u64 tail_ptr	: 32; | 
 | 	} sq; | 
 |  | 
 | 	struct { | 
 | 		u64 id		: 16; | 
 | 		u64 reserved	: 16; | 
 | 		u64 tail_ptr	: 31; | 
 | 		u64 arm		: 1; | 
 | 	} eq; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_msg_hdr { | 
 | 	u32 hdr_type; | 
 | 	u32 msg_type; | 
 | 	u16 msg_version; | 
 | 	u16 hwc_msg_id; | 
 | 	u32 msg_size; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_dev_id { | 
 | 	union { | 
 | 		struct { | 
 | 			u16 type; | 
 | 			u16 instance; | 
 | 		}; | 
 |  | 
 | 		u32 as_uint32; | 
 | 	}; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_req_hdr { | 
 | 	struct gdma_msg_hdr req; | 
 | 	struct gdma_msg_hdr resp; /* The expected response */ | 
 | 	struct gdma_dev_id dev_id; | 
 | 	u32 activity_id; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_resp_hdr { | 
 | 	struct gdma_msg_hdr response; | 
 | 	struct gdma_dev_id dev_id; | 
 | 	u32 activity_id; | 
 | 	u32 status; | 
 | 	u32 reserved; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_general_req { | 
 | 	struct gdma_req_hdr hdr; | 
 | }; /* HW DATA */ | 
 |  | 
 | #define GDMA_MESSAGE_V1 1 | 
 | #define GDMA_MESSAGE_V2 2 | 
 |  | 
 | struct gdma_general_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | }; /* HW DATA */ | 
 |  | 
 | #define GDMA_STANDARD_HEADER_TYPE 0 | 
 |  | 
 | static inline void mana_gd_init_req_hdr(struct gdma_req_hdr *hdr, u32 code, | 
 | 					u32 req_size, u32 resp_size) | 
 | { | 
 | 	hdr->req.hdr_type = GDMA_STANDARD_HEADER_TYPE; | 
 | 	hdr->req.msg_type = code; | 
 | 	hdr->req.msg_version = GDMA_MESSAGE_V1; | 
 | 	hdr->req.msg_size = req_size; | 
 |  | 
 | 	hdr->resp.hdr_type = GDMA_STANDARD_HEADER_TYPE; | 
 | 	hdr->resp.msg_type = code; | 
 | 	hdr->resp.msg_version = GDMA_MESSAGE_V1; | 
 | 	hdr->resp.msg_size = resp_size; | 
 | } | 
 |  | 
 | /* The 16-byte struct is part of the GDMA work queue entry (WQE). */ | 
 | struct gdma_sge { | 
 | 	u64 address; | 
 | 	u32 mem_key; | 
 | 	u32 size; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_wqe_request { | 
 | 	struct gdma_sge *sgl; | 
 | 	u32 num_sge; | 
 |  | 
 | 	u32 inline_oob_size; | 
 | 	const void *inline_oob_data; | 
 |  | 
 | 	u32 flags; | 
 | 	u32 client_data_unit; | 
 | }; | 
 |  | 
 | enum gdma_page_type { | 
 | 	GDMA_PAGE_TYPE_4K, | 
 | }; | 
 |  | 
 | #define GDMA_INVALID_DMA_REGION 0 | 
 |  | 
 | struct gdma_mem_info { | 
 | 	struct device *dev; | 
 |  | 
 | 	dma_addr_t dma_handle; | 
 | 	void *virt_addr; | 
 | 	u64 length; | 
 |  | 
 | 	/* Allocated by the PF driver */ | 
 | 	u64 dma_region_handle; | 
 | }; | 
 |  | 
 | #define REGISTER_ATB_MST_MKEY_LOWER_SIZE 8 | 
 |  | 
 | struct gdma_dev { | 
 | 	struct gdma_context *gdma_context; | 
 |  | 
 | 	struct gdma_dev_id dev_id; | 
 |  | 
 | 	u32 pdid; | 
 | 	u32 doorbell; | 
 | 	u32 gpa_mkey; | 
 |  | 
 | 	/* GDMA driver specific pointer */ | 
 | 	void *driver_data; | 
 |  | 
 | 	struct auxiliary_device *adev; | 
 | }; | 
 |  | 
 | #define MINIMUM_SUPPORTED_PAGE_SIZE PAGE_SIZE | 
 |  | 
 | #define GDMA_CQE_SIZE 64 | 
 | #define GDMA_EQE_SIZE 16 | 
 | #define GDMA_MAX_SQE_SIZE 512 | 
 | #define GDMA_MAX_RQE_SIZE 256 | 
 |  | 
 | #define GDMA_COMP_DATA_SIZE 0x3C | 
 |  | 
 | #define GDMA_EVENT_DATA_SIZE 0xC | 
 |  | 
 | /* The WQE size must be a multiple of the Basic Unit, which is 32 bytes. */ | 
 | #define GDMA_WQE_BU_SIZE 32 | 
 |  | 
 | #define INVALID_PDID		UINT_MAX | 
 | #define INVALID_DOORBELL	UINT_MAX | 
 | #define INVALID_MEM_KEY		UINT_MAX | 
 | #define INVALID_QUEUE_ID	UINT_MAX | 
 | #define INVALID_PCI_MSIX_INDEX  UINT_MAX | 
 |  | 
 | struct gdma_comp { | 
 | 	u32 cqe_data[GDMA_COMP_DATA_SIZE / 4]; | 
 | 	u32 wq_num; | 
 | 	bool is_sq; | 
 | }; | 
 |  | 
 | struct gdma_event { | 
 | 	u32 details[GDMA_EVENT_DATA_SIZE / 4]; | 
 | 	u8  type; | 
 | }; | 
 |  | 
 | struct gdma_queue; | 
 |  | 
 | struct mana_eq { | 
 | 	struct gdma_queue *eq; | 
 | }; | 
 |  | 
 | typedef void gdma_eq_callback(void *context, struct gdma_queue *q, | 
 | 			      struct gdma_event *e); | 
 |  | 
 | typedef void gdma_cq_callback(void *context, struct gdma_queue *q); | 
 |  | 
 | /* The 'head' is the producer index. For SQ/RQ, when the driver posts a WQE | 
 |  * (Note: the WQE size must be a multiple of the 32-byte Basic Unit), the | 
 |  * driver increases the 'head' in BUs rather than in bytes, and notifies | 
 |  * the HW of the updated head. For EQ/CQ, the driver uses the 'head' to track | 
 |  * the HW head, and increases the 'head' by 1 for every processed EQE/CQE. | 
 |  * | 
 |  * The 'tail' is the consumer index for SQ/RQ. After the CQE of the SQ/RQ is | 
 |  * processed, the driver increases the 'tail' to indicate that WQEs have | 
 |  * been consumed by the HW, so the driver can post new WQEs into the SQ/RQ. | 
 |  * | 
 |  * The driver doesn't use the 'tail' for EQ/CQ, because the driver ensures | 
 |  * that the EQ/CQ is big enough so they can't overflow, and the driver uses | 
 |  * the owner bits mechanism to detect if the queue has become empty. | 
 |  */ | 
 | struct gdma_queue { | 
 | 	struct gdma_dev *gdma_dev; | 
 |  | 
 | 	enum gdma_queue_type type; | 
 | 	u32 id; | 
 |  | 
 | 	struct gdma_mem_info mem_info; | 
 |  | 
 | 	void *queue_mem_ptr; | 
 | 	u32 queue_size; | 
 |  | 
 | 	bool monitor_avl_buf; | 
 |  | 
 | 	u32 head; | 
 | 	u32 tail; | 
 |  | 
 | 	/* Extra fields specific to EQ/CQ. */ | 
 | 	union { | 
 | 		struct { | 
 | 			bool disable_needed; | 
 |  | 
 | 			gdma_eq_callback *callback; | 
 | 			void *context; | 
 |  | 
 | 			unsigned int msix_index; | 
 |  | 
 | 			u32 log2_throttle_limit; | 
 | 		} eq; | 
 |  | 
 | 		struct { | 
 | 			gdma_cq_callback *callback; | 
 | 			void *context; | 
 |  | 
 | 			struct gdma_queue *parent; /* For CQ/EQ relationship */ | 
 | 		} cq; | 
 | 	}; | 
 | }; | 
 |  | 
 | struct gdma_queue_spec { | 
 | 	enum gdma_queue_type type; | 
 | 	bool monitor_avl_buf; | 
 | 	unsigned int queue_size; | 
 |  | 
 | 	/* Extra fields specific to EQ/CQ. */ | 
 | 	union { | 
 | 		struct { | 
 | 			gdma_eq_callback *callback; | 
 | 			void *context; | 
 |  | 
 | 			unsigned long log2_throttle_limit; | 
 | 		} eq; | 
 |  | 
 | 		struct { | 
 | 			gdma_cq_callback *callback; | 
 | 			void *context; | 
 |  | 
 | 			struct gdma_queue *parent_eq; | 
 |  | 
 | 		} cq; | 
 | 	}; | 
 | }; | 
 |  | 
 | #define MANA_IRQ_NAME_SZ 32 | 
 |  | 
 | struct gdma_irq_context { | 
 | 	void (*handler)(void *arg); | 
 | 	void *arg; | 
 | 	char name[MANA_IRQ_NAME_SZ]; | 
 | }; | 
 |  | 
 | struct gdma_context { | 
 | 	struct device		*dev; | 
 |  | 
 | 	/* Per-vPort max number of queues */ | 
 | 	unsigned int		max_num_queues; | 
 | 	unsigned int		max_num_msix; | 
 | 	unsigned int		num_msix_usable; | 
 | 	struct gdma_resource	msix_resource; | 
 | 	struct gdma_irq_context	*irq_contexts; | 
 |  | 
 | 	/* L2 MTU */ | 
 | 	u16 adapter_mtu; | 
 |  | 
 | 	/* This maps a CQ index to the queue structure. */ | 
 | 	unsigned int		max_num_cqs; | 
 | 	struct gdma_queue	**cq_table; | 
 |  | 
 | 	/* Protect eq_test_event and test_event_eq_id  */ | 
 | 	struct mutex		eq_test_event_mutex; | 
 | 	struct completion	eq_test_event; | 
 | 	u32			test_event_eq_id; | 
 |  | 
 | 	bool			is_pf; | 
 | 	phys_addr_t		bar0_pa; | 
 | 	void __iomem		*bar0_va; | 
 | 	void __iomem		*shm_base; | 
 | 	void __iomem		*db_page_base; | 
 | 	phys_addr_t		phys_db_page_base; | 
 | 	u32 db_page_size; | 
 | 	int                     numa_node; | 
 |  | 
 | 	/* Shared memory chanenl (used to bootstrap HWC) */ | 
 | 	struct shm_channel	shm_channel; | 
 |  | 
 | 	/* Hardware communication channel (HWC) */ | 
 | 	struct gdma_dev		hwc; | 
 |  | 
 | 	/* Azure network adapter */ | 
 | 	struct gdma_dev		mana; | 
 | }; | 
 |  | 
 | #define MAX_NUM_GDMA_DEVICES	4 | 
 |  | 
 | static inline bool mana_gd_is_mana(struct gdma_dev *gd) | 
 | { | 
 | 	return gd->dev_id.type == GDMA_DEVICE_MANA; | 
 | } | 
 |  | 
 | static inline bool mana_gd_is_hwc(struct gdma_dev *gd) | 
 | { | 
 | 	return gd->dev_id.type == GDMA_DEVICE_HWC; | 
 | } | 
 |  | 
 | u8 *mana_gd_get_wqe_ptr(const struct gdma_queue *wq, u32 wqe_offset); | 
 | u32 mana_gd_wq_avail_space(struct gdma_queue *wq); | 
 |  | 
 | int mana_gd_test_eq(struct gdma_context *gc, struct gdma_queue *eq); | 
 |  | 
 | int mana_gd_create_hwc_queue(struct gdma_dev *gd, | 
 | 			     const struct gdma_queue_spec *spec, | 
 | 			     struct gdma_queue **queue_ptr); | 
 |  | 
 | int mana_gd_create_mana_eq(struct gdma_dev *gd, | 
 | 			   const struct gdma_queue_spec *spec, | 
 | 			   struct gdma_queue **queue_ptr); | 
 |  | 
 | int mana_gd_create_mana_wq_cq(struct gdma_dev *gd, | 
 | 			      const struct gdma_queue_spec *spec, | 
 | 			      struct gdma_queue **queue_ptr); | 
 |  | 
 | void mana_gd_destroy_queue(struct gdma_context *gc, struct gdma_queue *queue); | 
 |  | 
 | int mana_gd_poll_cq(struct gdma_queue *cq, struct gdma_comp *comp, int num_cqe); | 
 |  | 
 | void mana_gd_ring_cq(struct gdma_queue *cq, u8 arm_bit); | 
 |  | 
 | struct gdma_wqe { | 
 | 	u32 reserved	:24; | 
 | 	u32 last_vbytes	:8; | 
 |  | 
 | 	union { | 
 | 		u32 flags; | 
 |  | 
 | 		struct { | 
 | 			u32 num_sge		:8; | 
 | 			u32 inline_oob_size_div4:3; | 
 | 			u32 client_oob_in_sgl	:1; | 
 | 			u32 reserved1		:4; | 
 | 			u32 client_data_unit	:14; | 
 | 			u32 reserved2		:2; | 
 | 		}; | 
 | 	}; | 
 | }; /* HW DATA */ | 
 |  | 
 | #define INLINE_OOB_SMALL_SIZE 8 | 
 | #define INLINE_OOB_LARGE_SIZE 24 | 
 |  | 
 | #define MAX_TX_WQE_SIZE 512 | 
 | #define MAX_RX_WQE_SIZE 256 | 
 |  | 
 | #define MAX_TX_WQE_SGL_ENTRIES	((GDMA_MAX_SQE_SIZE -			   \ | 
 | 			sizeof(struct gdma_sge) - INLINE_OOB_SMALL_SIZE) / \ | 
 | 			sizeof(struct gdma_sge)) | 
 |  | 
 | #define MAX_RX_WQE_SGL_ENTRIES	((GDMA_MAX_RQE_SIZE -			   \ | 
 | 			sizeof(struct gdma_sge)) / sizeof(struct gdma_sge)) | 
 |  | 
 | struct gdma_cqe { | 
 | 	u32 cqe_data[GDMA_COMP_DATA_SIZE / 4]; | 
 |  | 
 | 	union { | 
 | 		u32 as_uint32; | 
 |  | 
 | 		struct { | 
 | 			u32 wq_num	: 24; | 
 | 			u32 is_sq	: 1; | 
 | 			u32 reserved	: 4; | 
 | 			u32 owner_bits	: 3; | 
 | 		}; | 
 | 	} cqe_info; | 
 | }; /* HW DATA */ | 
 |  | 
 | #define GDMA_CQE_OWNER_BITS 3 | 
 |  | 
 | #define GDMA_CQE_OWNER_MASK ((1 << GDMA_CQE_OWNER_BITS) - 1) | 
 |  | 
 | #define SET_ARM_BIT 1 | 
 |  | 
 | #define GDMA_EQE_OWNER_BITS 3 | 
 |  | 
 | union gdma_eqe_info { | 
 | 	u32 as_uint32; | 
 |  | 
 | 	struct { | 
 | 		u32 type	: 8; | 
 | 		u32 reserved1	: 8; | 
 | 		u32 client_id	: 2; | 
 | 		u32 reserved2	: 11; | 
 | 		u32 owner_bits	: 3; | 
 | 	}; | 
 | }; /* HW DATA */ | 
 |  | 
 | #define GDMA_EQE_OWNER_MASK ((1 << GDMA_EQE_OWNER_BITS) - 1) | 
 | #define INITIALIZED_OWNER_BIT(log2_num_entries) (1UL << (log2_num_entries)) | 
 |  | 
 | struct gdma_eqe { | 
 | 	u32 details[GDMA_EVENT_DATA_SIZE / 4]; | 
 | 	u32 eqe_info; | 
 | }; /* HW DATA */ | 
 |  | 
 | #define GDMA_REG_DB_PAGE_OFFSET	8 | 
 | #define GDMA_REG_DB_PAGE_SIZE	0x10 | 
 | #define GDMA_REG_SHM_OFFSET	0x18 | 
 |  | 
 | #define GDMA_PF_REG_DB_PAGE_SIZE	0xD0 | 
 | #define GDMA_PF_REG_DB_PAGE_OFF		0xC8 | 
 | #define GDMA_PF_REG_SHM_OFF		0x70 | 
 |  | 
 | #define GDMA_SRIOV_REG_CFG_BASE_OFF	0x108 | 
 |  | 
 | #define MANA_PF_DEVICE_ID 0x00B9 | 
 | #define MANA_VF_DEVICE_ID 0x00BA | 
 |  | 
 | struct gdma_posted_wqe_info { | 
 | 	u32 wqe_size_in_bu; | 
 | }; | 
 |  | 
 | /* GDMA_GENERATE_TEST_EQE */ | 
 | struct gdma_generate_test_event_req { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	u32 queue_index; | 
 | }; /* HW DATA */ | 
 |  | 
 | /* GDMA_VERIFY_VF_DRIVER_VERSION */ | 
 | enum { | 
 | 	GDMA_PROTOCOL_V1	= 1, | 
 | 	GDMA_PROTOCOL_FIRST	= GDMA_PROTOCOL_V1, | 
 | 	GDMA_PROTOCOL_LAST	= GDMA_PROTOCOL_V1, | 
 | }; | 
 |  | 
 | #define GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT BIT(0) | 
 |  | 
 | /* Advertise to the NIC firmware: the NAPI work_done variable race is fixed, | 
 |  * so the driver is able to reliably support features like busy_poll. | 
 |  */ | 
 | #define GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX BIT(2) | 
 | #define GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG BIT(3) | 
 |  | 
 | #define GDMA_DRV_CAP_FLAGS1 \ | 
 | 	(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \ | 
 | 	 GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \ | 
 | 	 GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG) | 
 |  | 
 | #define GDMA_DRV_CAP_FLAGS2 0 | 
 |  | 
 | #define GDMA_DRV_CAP_FLAGS3 0 | 
 |  | 
 | #define GDMA_DRV_CAP_FLAGS4 0 | 
 |  | 
 | struct gdma_verify_ver_req { | 
 | 	struct gdma_req_hdr hdr; | 
 |  | 
 | 	/* Mandatory fields required for protocol establishment */ | 
 | 	u64 protocol_ver_min; | 
 | 	u64 protocol_ver_max; | 
 |  | 
 | 	/* Gdma Driver Capability Flags */ | 
 | 	u64 gd_drv_cap_flags1; | 
 | 	u64 gd_drv_cap_flags2; | 
 | 	u64 gd_drv_cap_flags3; | 
 | 	u64 gd_drv_cap_flags4; | 
 |  | 
 | 	/* Advisory fields */ | 
 | 	u64 drv_ver; | 
 | 	u32 os_type; /* Linux = 0x10; Windows = 0x20; Other = 0x30 */ | 
 | 	u32 reserved; | 
 | 	u32 os_ver_major; | 
 | 	u32 os_ver_minor; | 
 | 	u32 os_ver_build; | 
 | 	u32 os_ver_platform; | 
 | 	u64 reserved_2; | 
 | 	u8 os_ver_str1[128]; | 
 | 	u8 os_ver_str2[128]; | 
 | 	u8 os_ver_str3[128]; | 
 | 	u8 os_ver_str4[128]; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_verify_ver_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u64 gdma_protocol_ver; | 
 | 	u64 pf_cap_flags1; | 
 | 	u64 pf_cap_flags2; | 
 | 	u64 pf_cap_flags3; | 
 | 	u64 pf_cap_flags4; | 
 | }; /* HW DATA */ | 
 |  | 
 | /* GDMA_QUERY_MAX_RESOURCES */ | 
 | struct gdma_query_max_resources_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u32 status; | 
 | 	u32 max_sq; | 
 | 	u32 max_rq; | 
 | 	u32 max_cq; | 
 | 	u32 max_eq; | 
 | 	u32 max_db; | 
 | 	u32 max_mst; | 
 | 	u32 max_cq_mod_ctx; | 
 | 	u32 max_mod_cq; | 
 | 	u32 max_msix; | 
 | }; /* HW DATA */ | 
 |  | 
 | /* GDMA_LIST_DEVICES */ | 
 | struct gdma_list_devices_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u32 num_of_devs; | 
 | 	u32 reserved; | 
 | 	struct gdma_dev_id devs[64]; | 
 | }; /* HW DATA */ | 
 |  | 
 | /* GDMA_REGISTER_DEVICE */ | 
 | struct gdma_register_device_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u32 pdid; | 
 | 	u32 gpa_mkey; | 
 | 	u32 db_id; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_allocate_resource_range_req { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	u32 resource_type; | 
 | 	u32 num_resources; | 
 | 	u32 alignment; | 
 | 	u32 allocated_resources; | 
 | }; | 
 |  | 
 | struct gdma_allocate_resource_range_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u32 allocated_resources; | 
 | }; | 
 |  | 
 | struct gdma_destroy_resource_range_req { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	u32 resource_type; | 
 | 	u32 num_resources; | 
 | 	u32 allocated_resources; | 
 | }; | 
 |  | 
 | /* GDMA_CREATE_QUEUE */ | 
 | struct gdma_create_queue_req { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	u32 type; | 
 | 	u32 reserved1; | 
 | 	u32 pdid; | 
 | 	u32 doolbell_id; | 
 | 	u64 gdma_region; | 
 | 	u32 reserved2; | 
 | 	u32 queue_size; | 
 | 	u32 log2_throttle_limit; | 
 | 	u32 eq_pci_msix_index; | 
 | 	u32 cq_mod_ctx_id; | 
 | 	u32 cq_parent_eq_id; | 
 | 	u8  rq_drop_on_overrun; | 
 | 	u8  rq_err_on_wqe_overflow; | 
 | 	u8  rq_chain_rec_wqes; | 
 | 	u8  sq_hw_db; | 
 | 	u32 reserved3; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_create_queue_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u32 queue_index; | 
 | }; /* HW DATA */ | 
 |  | 
 | /* GDMA_DISABLE_QUEUE */ | 
 | struct gdma_disable_queue_req { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	u32 type; | 
 | 	u32 queue_index; | 
 | 	u32 alloc_res_id_on_creation; | 
 | }; /* HW DATA */ | 
 |  | 
 | /* GDMA_QUERY_HWC_TIMEOUT */ | 
 | struct gdma_query_hwc_timeout_req { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	u32 timeout_ms; | 
 | 	u32 reserved; | 
 | }; | 
 |  | 
 | struct gdma_query_hwc_timeout_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u32 timeout_ms; | 
 | 	u32 reserved; | 
 | }; | 
 |  | 
 | enum atb_page_size { | 
 | 	ATB_PAGE_SIZE_4K, | 
 | 	ATB_PAGE_SIZE_8K, | 
 | 	ATB_PAGE_SIZE_16K, | 
 | 	ATB_PAGE_SIZE_32K, | 
 | 	ATB_PAGE_SIZE_64K, | 
 | 	ATB_PAGE_SIZE_128K, | 
 | 	ATB_PAGE_SIZE_256K, | 
 | 	ATB_PAGE_SIZE_512K, | 
 | 	ATB_PAGE_SIZE_1M, | 
 | 	ATB_PAGE_SIZE_2M, | 
 | 	ATB_PAGE_SIZE_MAX, | 
 | }; | 
 |  | 
 | enum gdma_mr_access_flags { | 
 | 	GDMA_ACCESS_FLAG_LOCAL_READ = BIT_ULL(0), | 
 | 	GDMA_ACCESS_FLAG_LOCAL_WRITE = BIT_ULL(1), | 
 | 	GDMA_ACCESS_FLAG_REMOTE_READ = BIT_ULL(2), | 
 | 	GDMA_ACCESS_FLAG_REMOTE_WRITE = BIT_ULL(3), | 
 | 	GDMA_ACCESS_FLAG_REMOTE_ATOMIC = BIT_ULL(4), | 
 | }; | 
 |  | 
 | /* GDMA_CREATE_DMA_REGION */ | 
 | struct gdma_create_dma_region_req { | 
 | 	struct gdma_req_hdr hdr; | 
 |  | 
 | 	/* The total size of the DMA region */ | 
 | 	u64 length; | 
 |  | 
 | 	/* The offset in the first page */ | 
 | 	u32 offset_in_page; | 
 |  | 
 | 	/* enum gdma_page_type */ | 
 | 	u32 gdma_page_type; | 
 |  | 
 | 	/* The total number of pages */ | 
 | 	u32 page_count; | 
 |  | 
 | 	/* If page_addr_list_len is smaller than page_count, | 
 | 	 * the remaining page addresses will be added via the | 
 | 	 * message GDMA_DMA_REGION_ADD_PAGES. | 
 | 	 */ | 
 | 	u32 page_addr_list_len; | 
 | 	u64 page_addr_list[]; | 
 | }; /* HW DATA */ | 
 |  | 
 | struct gdma_create_dma_region_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u64 dma_region_handle; | 
 | }; /* HW DATA */ | 
 |  | 
 | /* GDMA_DMA_REGION_ADD_PAGES */ | 
 | struct gdma_dma_region_add_pages_req { | 
 | 	struct gdma_req_hdr hdr; | 
 |  | 
 | 	u64 dma_region_handle; | 
 |  | 
 | 	u32 page_addr_list_len; | 
 | 	u32 reserved3; | 
 |  | 
 | 	u64 page_addr_list[]; | 
 | }; /* HW DATA */ | 
 |  | 
 | /* GDMA_DESTROY_DMA_REGION */ | 
 | struct gdma_destroy_dma_region_req { | 
 | 	struct gdma_req_hdr hdr; | 
 |  | 
 | 	u64 dma_region_handle; | 
 | }; /* HW DATA */ | 
 |  | 
 | enum gdma_pd_flags { | 
 | 	GDMA_PD_FLAG_INVALID = 0, | 
 | }; | 
 |  | 
 | struct gdma_create_pd_req { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	enum gdma_pd_flags flags; | 
 | 	u32 reserved; | 
 | };/* HW DATA */ | 
 |  | 
 | struct gdma_create_pd_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u64 pd_handle; | 
 | 	u32 pd_id; | 
 | 	u32 reserved; | 
 | };/* HW DATA */ | 
 |  | 
 | struct gdma_destroy_pd_req { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	u64 pd_handle; | 
 | };/* HW DATA */ | 
 |  | 
 | struct gdma_destory_pd_resp { | 
 | 	struct gdma_resp_hdr hdr; | 
 | };/* HW DATA */ | 
 |  | 
 | enum gdma_mr_type { | 
 | 	/* Guest Virtual Address - MRs of this type allow access | 
 | 	 * to memory mapped by PTEs associated with this MR using a virtual | 
 | 	 * address that is set up in the MST | 
 | 	 */ | 
 | 	GDMA_MR_TYPE_GVA = 2, | 
 | }; | 
 |  | 
 | struct gdma_create_mr_params { | 
 | 	u64 pd_handle; | 
 | 	enum gdma_mr_type mr_type; | 
 | 	union { | 
 | 		struct { | 
 | 			u64 dma_region_handle; | 
 | 			u64 virtual_address; | 
 | 			enum gdma_mr_access_flags access_flags; | 
 | 		} gva; | 
 | 	}; | 
 | }; | 
 |  | 
 | struct gdma_create_mr_request { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	u64 pd_handle; | 
 | 	enum gdma_mr_type mr_type; | 
 | 	u32 reserved_1; | 
 |  | 
 | 	union { | 
 | 		struct { | 
 | 			u64 dma_region_handle; | 
 | 			u64 virtual_address; | 
 | 			enum gdma_mr_access_flags access_flags; | 
 | 		} gva; | 
 |  | 
 | 	}; | 
 | 	u32 reserved_2; | 
 | };/* HW DATA */ | 
 |  | 
 | struct gdma_create_mr_response { | 
 | 	struct gdma_resp_hdr hdr; | 
 | 	u64 mr_handle; | 
 | 	u32 lkey; | 
 | 	u32 rkey; | 
 | };/* HW DATA */ | 
 |  | 
 | struct gdma_destroy_mr_request { | 
 | 	struct gdma_req_hdr hdr; | 
 | 	u64 mr_handle; | 
 | };/* HW DATA */ | 
 |  | 
 | struct gdma_destroy_mr_response { | 
 | 	struct gdma_resp_hdr hdr; | 
 | };/* HW DATA */ | 
 |  | 
 | int mana_gd_verify_vf_version(struct pci_dev *pdev); | 
 |  | 
 | int mana_gd_register_device(struct gdma_dev *gd); | 
 | int mana_gd_deregister_device(struct gdma_dev *gd); | 
 |  | 
 | int mana_gd_post_work_request(struct gdma_queue *wq, | 
 | 			      const struct gdma_wqe_request *wqe_req, | 
 | 			      struct gdma_posted_wqe_info *wqe_info); | 
 |  | 
 | int mana_gd_post_and_ring(struct gdma_queue *queue, | 
 | 			  const struct gdma_wqe_request *wqe, | 
 | 			  struct gdma_posted_wqe_info *wqe_info); | 
 |  | 
 | int mana_gd_alloc_res_map(u32 res_avail, struct gdma_resource *r); | 
 | void mana_gd_free_res_map(struct gdma_resource *r); | 
 |  | 
 | void mana_gd_wq_ring_doorbell(struct gdma_context *gc, | 
 | 			      struct gdma_queue *queue); | 
 |  | 
 | int mana_gd_alloc_memory(struct gdma_context *gc, unsigned int length, | 
 | 			 struct gdma_mem_info *gmi); | 
 |  | 
 | void mana_gd_free_memory(struct gdma_mem_info *gmi); | 
 |  | 
 | int mana_gd_send_request(struct gdma_context *gc, u32 req_len, const void *req, | 
 | 			 u32 resp_len, void *resp); | 
 |  | 
 | int mana_gd_destroy_dma_region(struct gdma_context *gc, u64 dma_region_handle); | 
 |  | 
 | #endif /* _GDMA_H */ |