Commit e1d0edff authored by Weibo Zhao's avatar Weibo Zhao Committed by JiangShui
Browse files

hns3 udma: feature of memory translate region

driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I85R2F


CVE: NA

------------------------------------------------------

This patch is the code of Memory-Translate-Region(MTR).
MTR is a way that hardware can read/write memory.

Signed-off-by: default avatarWeibo Zhao <zhaoweibo3@huawei.com>
parent b330adf6
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -55,6 +55,9 @@
#define UDMA_TX_CMQ_PI_REG			0x07010
#define UDMA_TX_CMQ_CI_REG			0x07014

#define UDMA_MAX_BT_REGION			3
#define UDMA_MAX_BT_LEVEL			3

enum udma_reset_stage {
	UDMA_STATE_RST_DOWN = 2,
	UDMA_STATE_RST_UNINIT,
@@ -104,11 +107,47 @@ struct udma_ida {
	uint32_t	min; /* Lowest ID to allocate.  */
	uint32_t	max; /* Highest ID to allocate. */
};

struct udma_buf_region {
	uint32_t	offset; /* page offset */
	uint32_t	count; /* page count */
	int		hopnum; /* addressing hop num */
};

struct udma_hem_list {
	struct list_head	root_bt;
	/* link all bt dma mem by hop config */
	struct list_head	mid_bt[UDMA_MAX_BT_REGION][UDMA_MAX_BT_LEVEL];
	struct list_head	btm_bt; /* link all bottom bt in @mid_bt */
	dma_addr_t		root_ba; /* pointer to the root ba table */
};

struct udma_buf_attr {
	struct {
		size_t		size;  /* region size */
		int		hopnum; /* multi-hop addressing hop num */
	} region[UDMA_MAX_BT_REGION];
	uint32_t		region_count; /* valid region count */
	uint32_t		page_shift;  /* buffer page shift */
	/* only alloc buffer-required MTT memory */
	bool			mtt_only;
};

struct udma_buf_list {
	void		*buf;
	dma_addr_t	map;
};

struct udma_hem_cfg {
	dma_addr_t		root_ba; /* root BA table's address */
	bool			is_direct; /* addressing without BA table */
	uint32_t		ba_pg_shift; /* BA table page shift */
	uint32_t		buf_pg_shift; /* buffer page shift */
	uint32_t		buf_pg_count;  /* buffer page count */
	struct udma_buf_region	region[UDMA_MAX_BT_REGION];
	uint32_t		region_count;
};

struct udma_buf {
	struct udma_buf_list		*trunk_list;
	uint32_t			ntrunks;
@@ -121,6 +160,15 @@ struct udma_link_table {
	struct udma_buf_list	table;
	struct udma_buf		*buf;
};

/* memory translate region */
struct udma_mtr {
	struct udma_hem_list	hem_list; /* multi-hop addressing resource */
	struct ubcore_umem	*umem; /* user space buffer */
	struct udma_buf		*kmem; /* kernel space buffer */
	struct udma_hem_cfg	hem_cfg; /* config for hardware addressing */
};

struct udma_dev;
struct udma_cmd_context {
	struct completion	done;
@@ -498,6 +546,10 @@ int udma_cmq_send(struct udma_dev *udma_dev,
		  struct udma_cmq_desc *desc, int num);
int udma_hnae_client_init(struct udma_dev *udma_dev);
void udma_hnae_client_exit(struct udma_dev *udma_dev);
int udma_mtr_create(struct udma_dev *udma_dev, struct udma_mtr *mtr,
		    struct udma_buf_attr *buf_attr, uint32_t ba_page_shift,
		    uint64_t user_addr, bool is_user);
void udma_mtr_destroy(struct udma_dev *udma_dev, struct udma_mtr *mtr);
void udma_cleanup_common_hem(struct udma_dev *udma_dev);
int udma_init_common_hem(struct udma_dev *udma_dev);

+1108 −0

File changed.

Preview size limit exceeded, changes collapsed.

+17 −0
Original line number Diff line number Diff line
@@ -100,6 +100,23 @@ struct udma_hem_mhop {
	uint32_t l2_idx; /* level 2 base address table index */
};

struct udma_hem_item {
	struct list_head	list; /* link all hems in the same bt level */
	struct list_head	sibling; /* link all hems in last hop for mtt */
	void			*addr;
	dma_addr_t		dma_addr;
	size_t			count; /* max ba numbers */
	int			start; /* start buf offset in this hem */
	int			end; /* end buf offset in this hem */
};

/* All HEM itmes are linked in a tree structure */
struct udma_hem_head {
	struct list_head branch[UDMA_MAX_BT_REGION];
	struct list_head root;
	struct list_head leaf;
};

struct udma_buf *udma_buf_alloc(struct udma_dev *udma_dev, uint32_t size,
				uint32_t page_shift, uint32_t flags);
void udma_buf_free(struct udma_dev *udma_dev, struct udma_buf *buf);