0
  "   ˆl–Ým_J*j"Tâ�Á=q—TÅ£Âƒh¹ÀÅ      402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe
     ˆ¿Âƒh¹ÀÅ      Y
     ˆÃÂ„DóÿÁÀÅ ?÷     /* 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
#define GDMA_STATUS_CMD_UNSUPPORTED	0xffffffff

/* 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_FPGA_RECONFIG	= 132,
	GDMA_EQE_HWC_SOC_RECONFIG_DATA	= 133,
	GDMA_EQE_HWC_SOC_SERVICE	= 134,
	GDMA_EQE_HWC_RESET_REQUEST	= 135,
	GDMA_EQE_RNIC_QP_FATAL		= 176,
};

enum {
	GDMA_DEVICE_NONE	= 0,
	GDMA_DEVICE_HWC		= 1,
	GDMA_DEVICE_MANA	= 2,
	GDMA_DEVICE_MANA_IB	= 3,
};

enum gdma_service_type {
	GDMA_SERVICE_TYPE_NONE		= 0,
	GDMA_SERVICE_TYPE_RDMA_SUSPEND	= 1,
	GDMA_SERVICE_TYPE_RDMA_RESUME	= 2,
};

struct mana_service_work {
	struct work_struct work;
	struct gdma_dev *gdma_dev;
	enum gdma_service_type event;
};

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
#define GDMA_MESSAGE_V3 3
#define GDMA_MESSAGE_V4 4

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;
	u