xref: /linux/drivers/dma/idxd/idxd.h (revision 1f2bb40337f0df1d9af80793e9fdacff7706e654)
1bfe1d560SDave Jiang /* SPDX-License-Identifier: GPL-2.0 */
2bfe1d560SDave Jiang /* Copyright(c) 2019 Intel Corporation. All rights rsvd. */
3bfe1d560SDave Jiang #ifndef _IDXD_H_
4bfe1d560SDave Jiang #define _IDXD_H_
5bfe1d560SDave Jiang 
6bfe1d560SDave Jiang #include <linux/sbitmap.h>
78f47d1a5SDave Jiang #include <linux/dmaengine.h>
8bfe1d560SDave Jiang #include <linux/percpu-rwsem.h>
9bfe1d560SDave Jiang #include <linux/wait.h>
1042d279f9SDave Jiang #include <linux/cdev.h>
1147c16ac2SDave Jiang #include <linux/idr.h>
1281dd4d4dSTom Zanussi #include <linux/pci.h>
1381dd4d4dSTom Zanussi #include <linux/perf_event.h>
14bfe1d560SDave Jiang #include "registers.h"
15bfe1d560SDave Jiang 
16bfe1d560SDave Jiang #define IDXD_DRIVER_VERSION	"1.00"
17bfe1d560SDave Jiang 
18bfe1d560SDave Jiang extern struct kmem_cache *idxd_desc_pool;
19bfe1d560SDave Jiang 
2039786285SDave Jiang struct idxd_wq;
21700af3a0SDave Jiang struct idxd_dev;
22700af3a0SDave Jiang 
23700af3a0SDave Jiang enum idxd_dev_type {
24700af3a0SDave Jiang 	IDXD_DEV_NONE = -1,
25700af3a0SDave Jiang 	IDXD_DEV_DSA = 0,
26700af3a0SDave Jiang 	IDXD_DEV_IAX,
27700af3a0SDave Jiang 	IDXD_DEV_WQ,
28700af3a0SDave Jiang 	IDXD_DEV_GROUP,
29700af3a0SDave Jiang 	IDXD_DEV_ENGINE,
30700af3a0SDave Jiang 	IDXD_DEV_CDEV,
31700af3a0SDave Jiang 	IDXD_DEV_MAX_TYPE,
32700af3a0SDave Jiang };
33700af3a0SDave Jiang 
34700af3a0SDave Jiang struct idxd_dev {
35700af3a0SDave Jiang 	struct device conf_dev;
36700af3a0SDave Jiang 	enum idxd_dev_type type;
37700af3a0SDave Jiang };
3839786285SDave Jiang 
39bfe1d560SDave Jiang #define IDXD_REG_TIMEOUT	50
40bfe1d560SDave Jiang #define IDXD_DRAIN_TIMEOUT	5000
41bfe1d560SDave Jiang 
42bfe1d560SDave Jiang enum idxd_type {
43bfe1d560SDave Jiang 	IDXD_TYPE_UNKNOWN = -1,
44bfe1d560SDave Jiang 	IDXD_TYPE_DSA = 0,
45f25b4638SDave Jiang 	IDXD_TYPE_IAX,
46f25b4638SDave Jiang 	IDXD_TYPE_MAX,
47bfe1d560SDave Jiang };
48bfe1d560SDave Jiang 
49bfe1d560SDave Jiang #define IDXD_NAME_SIZE		128
5081dd4d4dSTom Zanussi #define IDXD_PMU_EVENT_MAX	64
51bfe1d560SDave Jiang 
52bfe1d560SDave Jiang struct idxd_device_driver {
53da5a11d7SDave Jiang 	const char *name;
54bfe1d560SDave Jiang 	struct device_driver drv;
55bfe1d560SDave Jiang };
56bfe1d560SDave Jiang 
57bfe1d560SDave Jiang struct idxd_irq_entry {
58bfe1d560SDave Jiang 	struct idxd_device *idxd;
59bfe1d560SDave Jiang 	int id;
605fc8e85fSDave Jiang 	int vector;
61bfe1d560SDave Jiang 	struct llist_head pending_llist;
62bfe1d560SDave Jiang 	struct list_head work_list;
63e4f4d8cdSDave Jiang 	/*
64e4f4d8cdSDave Jiang 	 * Lock to protect access between irq thread process descriptor
65e4f4d8cdSDave Jiang 	 * and irq thread processing error descriptor.
66e4f4d8cdSDave Jiang 	 */
67e4f4d8cdSDave Jiang 	spinlock_t list_lock;
68bfe1d560SDave Jiang };
69bfe1d560SDave Jiang 
70bfe1d560SDave Jiang struct idxd_group {
71700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
72bfe1d560SDave Jiang 	struct idxd_device *idxd;
73bfe1d560SDave Jiang 	struct grpcfg grpcfg;
74bfe1d560SDave Jiang 	int id;
75bfe1d560SDave Jiang 	int num_engines;
76bfe1d560SDave Jiang 	int num_wqs;
77bfe1d560SDave Jiang 	bool use_token_limit;
78bfe1d560SDave Jiang 	u8 tokens_allowed;
79bfe1d560SDave Jiang 	u8 tokens_reserved;
80bfe1d560SDave Jiang 	int tc_a;
81bfe1d560SDave Jiang 	int tc_b;
82bfe1d560SDave Jiang };
83bfe1d560SDave Jiang 
8481dd4d4dSTom Zanussi struct idxd_pmu {
8581dd4d4dSTom Zanussi 	struct idxd_device *idxd;
8681dd4d4dSTom Zanussi 
8781dd4d4dSTom Zanussi 	struct perf_event *event_list[IDXD_PMU_EVENT_MAX];
8881dd4d4dSTom Zanussi 	int n_events;
8981dd4d4dSTom Zanussi 
9081dd4d4dSTom Zanussi 	DECLARE_BITMAP(used_mask, IDXD_PMU_EVENT_MAX);
9181dd4d4dSTom Zanussi 
9281dd4d4dSTom Zanussi 	struct pmu pmu;
9381dd4d4dSTom Zanussi 	char name[IDXD_NAME_SIZE];
9481dd4d4dSTom Zanussi 	int cpu;
9581dd4d4dSTom Zanussi 
9681dd4d4dSTom Zanussi 	int n_counters;
9781dd4d4dSTom Zanussi 	int counter_width;
9881dd4d4dSTom Zanussi 	int n_event_categories;
9981dd4d4dSTom Zanussi 
10081dd4d4dSTom Zanussi 	bool per_counter_caps_supported;
10181dd4d4dSTom Zanussi 	unsigned long supported_event_categories;
10281dd4d4dSTom Zanussi 
10381dd4d4dSTom Zanussi 	unsigned long supported_filters;
10481dd4d4dSTom Zanussi 	int n_filters;
10581dd4d4dSTom Zanussi 
10681dd4d4dSTom Zanussi 	struct hlist_node cpuhp_node;
10781dd4d4dSTom Zanussi };
10881dd4d4dSTom Zanussi 
109bfe1d560SDave Jiang #define IDXD_MAX_PRIORITY	0xf
110bfe1d560SDave Jiang 
111bfe1d560SDave Jiang enum idxd_wq_state {
112bfe1d560SDave Jiang 	IDXD_WQ_DISABLED = 0,
113bfe1d560SDave Jiang 	IDXD_WQ_ENABLED,
114bfe1d560SDave Jiang };
115bfe1d560SDave Jiang 
116bfe1d560SDave Jiang enum idxd_wq_flag {
117bfe1d560SDave Jiang 	WQ_FLAG_DEDICATED = 0,
1188e50d392SDave Jiang 	WQ_FLAG_BLOCK_ON_FAULT,
119bfe1d560SDave Jiang };
120bfe1d560SDave Jiang 
121bfe1d560SDave Jiang enum idxd_wq_type {
122bfe1d560SDave Jiang 	IDXD_WQT_NONE = 0,
123bfe1d560SDave Jiang 	IDXD_WQT_KERNEL,
12442d279f9SDave Jiang 	IDXD_WQT_USER,
12542d279f9SDave Jiang };
12642d279f9SDave Jiang 
12742d279f9SDave Jiang struct idxd_cdev {
12804922b74SDave Jiang 	struct idxd_wq *wq;
12942d279f9SDave Jiang 	struct cdev cdev;
130700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
13142d279f9SDave Jiang 	int minor;
132bfe1d560SDave Jiang };
133bfe1d560SDave Jiang 
134bfe1d560SDave Jiang #define IDXD_ALLOCATED_BATCH_SIZE	128U
135bfe1d560SDave Jiang #define WQ_NAME_SIZE   1024
136bfe1d560SDave Jiang #define WQ_TYPE_SIZE   10
137bfe1d560SDave Jiang 
138d1dfe5b8SDave Jiang enum idxd_op_type {
139d1dfe5b8SDave Jiang 	IDXD_OP_BLOCK = 0,
140d1dfe5b8SDave Jiang 	IDXD_OP_NONBLOCK = 1,
141d1dfe5b8SDave Jiang };
142d1dfe5b8SDave Jiang 
1438f47d1a5SDave Jiang enum idxd_complete_type {
1448f47d1a5SDave Jiang 	IDXD_COMPLETE_NORMAL = 0,
1458f47d1a5SDave Jiang 	IDXD_COMPLETE_ABORT,
1468e50d392SDave Jiang 	IDXD_COMPLETE_DEV_FAIL,
1478f47d1a5SDave Jiang };
1488f47d1a5SDave Jiang 
14939786285SDave Jiang struct idxd_dma_chan {
15039786285SDave Jiang 	struct dma_chan chan;
15139786285SDave Jiang 	struct idxd_wq *wq;
15239786285SDave Jiang };
15339786285SDave Jiang 
154bfe1d560SDave Jiang struct idxd_wq {
1558e50d392SDave Jiang 	void __iomem *portal;
15693a40a6dSDave Jiang 	struct percpu_ref wq_active;
15793a40a6dSDave Jiang 	struct completion wq_dead;
158700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
15904922b74SDave Jiang 	struct idxd_cdev *idxd_cdev;
16004922b74SDave Jiang 	struct wait_queue_head err_queue;
161bfe1d560SDave Jiang 	struct idxd_device *idxd;
162bfe1d560SDave Jiang 	int id;
163bfe1d560SDave Jiang 	enum idxd_wq_type type;
164bfe1d560SDave Jiang 	struct idxd_group *group;
165bfe1d560SDave Jiang 	int client_count;
166bfe1d560SDave Jiang 	struct mutex wq_lock;	/* mutex for workqueue */
167bfe1d560SDave Jiang 	u32 size;
168bfe1d560SDave Jiang 	u32 threshold;
169bfe1d560SDave Jiang 	u32 priority;
170bfe1d560SDave Jiang 	enum idxd_wq_state state;
171bfe1d560SDave Jiang 	unsigned long flags;
172d98793b5SDave Jiang 	union wqcfg *wqcfg;
173bfe1d560SDave Jiang 	struct dsa_hw_desc **hw_descs;
174bfe1d560SDave Jiang 	int num_descs;
175f25b4638SDave Jiang 	union {
176bfe1d560SDave Jiang 		struct dsa_completion_record *compls;
177f25b4638SDave Jiang 		struct iax_completion_record *iax_compls;
178f25b4638SDave Jiang 	};
179f25b4638SDave Jiang 	void *compls_raw;
180bfe1d560SDave Jiang 	dma_addr_t compls_addr;
181f25b4638SDave Jiang 	dma_addr_t compls_addr_raw;
182bfe1d560SDave Jiang 	int compls_size;
183bfe1d560SDave Jiang 	struct idxd_desc **descs;
1840705107fSDave Jiang 	struct sbitmap_queue sbq;
18539786285SDave Jiang 	struct idxd_dma_chan *idxd_chan;
186bfe1d560SDave Jiang 	char name[WQ_NAME_SIZE + 1];
187d7aad555SDave Jiang 	u64 max_xfer_bytes;
188e7184b15SDave Jiang 	u32 max_batch_size;
18992de5fa2SDave Jiang 	bool ats_dis;
190bfe1d560SDave Jiang };
191bfe1d560SDave Jiang 
192bfe1d560SDave Jiang struct idxd_engine {
193700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
194bfe1d560SDave Jiang 	int id;
195bfe1d560SDave Jiang 	struct idxd_group *group;
196bfe1d560SDave Jiang 	struct idxd_device *idxd;
197bfe1d560SDave Jiang };
198bfe1d560SDave Jiang 
199bfe1d560SDave Jiang /* shadow registers */
200bfe1d560SDave Jiang struct idxd_hw {
201bfe1d560SDave Jiang 	u32 version;
202bfe1d560SDave Jiang 	union gen_cap_reg gen_cap;
203bfe1d560SDave Jiang 	union wq_cap_reg wq_cap;
204bfe1d560SDave Jiang 	union group_cap_reg group_cap;
205bfe1d560SDave Jiang 	union engine_cap_reg engine_cap;
206bfe1d560SDave Jiang 	struct opcap opcap;
207eb15e715SDave Jiang 	u32 cmd_cap;
208bfe1d560SDave Jiang };
209bfe1d560SDave Jiang 
210bfe1d560SDave Jiang enum idxd_device_state {
211bfe1d560SDave Jiang 	IDXD_DEV_HALTED = -1,
212bfe1d560SDave Jiang 	IDXD_DEV_DISABLED = 0,
213bfe1d560SDave Jiang 	IDXD_DEV_ENABLED,
214bfe1d560SDave Jiang };
215bfe1d560SDave Jiang 
216bfe1d560SDave Jiang enum idxd_device_flag {
217bfe1d560SDave Jiang 	IDXD_FLAG_CONFIGURABLE = 0,
2180d5c10b4SDave Jiang 	IDXD_FLAG_CMD_RUNNING,
2198e50d392SDave Jiang 	IDXD_FLAG_PASID_ENABLED,
220bfe1d560SDave Jiang };
221bfe1d560SDave Jiang 
22239786285SDave Jiang struct idxd_dma_dev {
22339786285SDave Jiang 	struct idxd_device *idxd;
22439786285SDave Jiang 	struct dma_device dma;
22539786285SDave Jiang };
22639786285SDave Jiang 
227435b512dSDave Jiang struct idxd_driver_data {
228435b512dSDave Jiang 	const char *name_prefix;
229bfe1d560SDave Jiang 	enum idxd_type type;
230435b512dSDave Jiang 	struct device_type *dev_type;
231435b512dSDave Jiang 	int compl_size;
232435b512dSDave Jiang 	int align;
233435b512dSDave Jiang };
234435b512dSDave Jiang 
235435b512dSDave Jiang struct idxd_device {
236700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
237435b512dSDave Jiang 	struct idxd_driver_data *data;
238bfe1d560SDave Jiang 	struct list_head list;
239bfe1d560SDave Jiang 	struct idxd_hw hw;
240bfe1d560SDave Jiang 	enum idxd_device_state state;
241bfe1d560SDave Jiang 	unsigned long flags;
242bfe1d560SDave Jiang 	int id;
24342d279f9SDave Jiang 	int major;
244ff18de55SDave Jiang 	u8 cmd_status;
245bfe1d560SDave Jiang 
246bfe1d560SDave Jiang 	struct pci_dev *pdev;
247bfe1d560SDave Jiang 	void __iomem *reg_base;
248bfe1d560SDave Jiang 
249bfe1d560SDave Jiang 	spinlock_t dev_lock;	/* spinlock for device */
25053b2ee7fSDave Jiang 	spinlock_t cmd_lock;	/* spinlock for device commands */
2510d5c10b4SDave Jiang 	struct completion *cmd_done;
252defe49f9SDave Jiang 	struct idxd_group **groups;
2537c5dd23eSDave Jiang 	struct idxd_wq **wqs;
25475b91130SDave Jiang 	struct idxd_engine **engines;
255bfe1d560SDave Jiang 
2568e50d392SDave Jiang 	struct iommu_sva *sva;
2578e50d392SDave Jiang 	unsigned int pasid;
2588e50d392SDave Jiang 
259bfe1d560SDave Jiang 	int num_groups;
260bfe1d560SDave Jiang 
261bfe1d560SDave Jiang 	u32 msix_perm_offset;
262bfe1d560SDave Jiang 	u32 wqcfg_offset;
263bfe1d560SDave Jiang 	u32 grpcfg_offset;
264bfe1d560SDave Jiang 	u32 perfmon_offset;
265bfe1d560SDave Jiang 
266bfe1d560SDave Jiang 	u64 max_xfer_bytes;
267bfe1d560SDave Jiang 	u32 max_batch_size;
268bfe1d560SDave Jiang 	int max_groups;
269bfe1d560SDave Jiang 	int max_engines;
270bfe1d560SDave Jiang 	int max_tokens;
271bfe1d560SDave Jiang 	int max_wqs;
272bfe1d560SDave Jiang 	int max_wq_size;
273bfe1d560SDave Jiang 	int token_limit;
274c52ca478SDave Jiang 	int nr_tokens;		/* non-reserved tokens */
275d98793b5SDave Jiang 	unsigned int wqcfg_size;
276bfe1d560SDave Jiang 
277bfe1d560SDave Jiang 	union sw_err_reg sw_err;
2780d5c10b4SDave Jiang 	wait_queue_head_t cmd_waitq;
279bfe1d560SDave Jiang 	int num_wq_irqs;
280bfe1d560SDave Jiang 	struct idxd_irq_entry *irq_entries;
2818f47d1a5SDave Jiang 
28239786285SDave Jiang 	struct idxd_dma_dev *idxd_dma;
2830d5c10b4SDave Jiang 	struct workqueue_struct *wq;
2840d5c10b4SDave Jiang 	struct work_struct work;
285eb15e715SDave Jiang 
286eb15e715SDave Jiang 	int *int_handles;
28781dd4d4dSTom Zanussi 
28881dd4d4dSTom Zanussi 	struct idxd_pmu *idxd_pmu;
289bfe1d560SDave Jiang };
290bfe1d560SDave Jiang 
291bfe1d560SDave Jiang /* IDXD software descriptor */
292bfe1d560SDave Jiang struct idxd_desc {
293f25b4638SDave Jiang 	union {
294bfe1d560SDave Jiang 		struct dsa_hw_desc *hw;
295f25b4638SDave Jiang 		struct iax_hw_desc *iax_hw;
296f25b4638SDave Jiang 	};
297bfe1d560SDave Jiang 	dma_addr_t desc_dma;
298f25b4638SDave Jiang 	union {
299bfe1d560SDave Jiang 		struct dsa_completion_record *completion;
300f25b4638SDave Jiang 		struct iax_completion_record *iax_completion;
301f25b4638SDave Jiang 	};
302bfe1d560SDave Jiang 	dma_addr_t compl_dma;
3038f47d1a5SDave Jiang 	struct dma_async_tx_descriptor txd;
304bfe1d560SDave Jiang 	struct llist_node llnode;
305bfe1d560SDave Jiang 	struct list_head list;
306bfe1d560SDave Jiang 	int id;
3070705107fSDave Jiang 	int cpu;
308bfe1d560SDave Jiang 	struct idxd_wq *wq;
309bfe1d560SDave Jiang };
310bfe1d560SDave Jiang 
3116b4b87f2SDave Jiang /*
3126b4b87f2SDave Jiang  * This is software defined error for the completion status. We overload the error code
3136b4b87f2SDave Jiang  * that will never appear in completion status and only SWERR register.
3146b4b87f2SDave Jiang  */
3156b4b87f2SDave Jiang enum idxd_completion_status {
3166b4b87f2SDave Jiang 	IDXD_COMP_DESC_ABORT = 0xff,
3176b4b87f2SDave Jiang };
3186b4b87f2SDave Jiang 
319700af3a0SDave Jiang #define idxd_confdev(idxd) &idxd->idxd_dev.conf_dev
320700af3a0SDave Jiang #define wq_confdev(wq) &wq->idxd_dev.conf_dev
321700af3a0SDave Jiang #define engine_confdev(engine) &engine->idxd_dev.conf_dev
322700af3a0SDave Jiang #define group_confdev(group) &group->idxd_dev.conf_dev
323700af3a0SDave Jiang #define cdev_dev(cdev) &cdev->idxd_dev.conf_dev
324700af3a0SDave Jiang 
325700af3a0SDave Jiang #define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev)
326700af3a0SDave Jiang 
327700af3a0SDave Jiang static inline struct idxd_device *confdev_to_idxd(struct device *dev)
328700af3a0SDave Jiang {
329700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
330700af3a0SDave Jiang 
331700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_device, idxd_dev);
332700af3a0SDave Jiang }
333700af3a0SDave Jiang 
334700af3a0SDave Jiang static inline struct idxd_wq *confdev_to_wq(struct device *dev)
335700af3a0SDave Jiang {
336700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
337700af3a0SDave Jiang 
338700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_wq, idxd_dev);
339700af3a0SDave Jiang }
340700af3a0SDave Jiang 
341700af3a0SDave Jiang static inline struct idxd_engine *confdev_to_engine(struct device *dev)
342700af3a0SDave Jiang {
343700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
344700af3a0SDave Jiang 
345700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_engine, idxd_dev);
346700af3a0SDave Jiang }
347700af3a0SDave Jiang 
348700af3a0SDave Jiang static inline struct idxd_group *confdev_to_group(struct device *dev)
349700af3a0SDave Jiang {
350700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
351700af3a0SDave Jiang 
352700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_group, idxd_dev);
353700af3a0SDave Jiang }
354700af3a0SDave Jiang 
355700af3a0SDave Jiang static inline struct idxd_cdev *dev_to_cdev(struct device *dev)
356700af3a0SDave Jiang {
357700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
358700af3a0SDave Jiang 
359700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_cdev, idxd_dev);
360700af3a0SDave Jiang }
361700af3a0SDave Jiang 
362700af3a0SDave Jiang static inline void idxd_dev_set_type(struct idxd_dev *idev, int type)
363700af3a0SDave Jiang {
364700af3a0SDave Jiang 	if (type >= IDXD_DEV_MAX_TYPE) {
365700af3a0SDave Jiang 		idev->type = IDXD_DEV_NONE;
366700af3a0SDave Jiang 		return;
367700af3a0SDave Jiang 	}
368700af3a0SDave Jiang 
369700af3a0SDave Jiang 	idev->type = type;
370700af3a0SDave Jiang }
371bfe1d560SDave Jiang 
37242d279f9SDave Jiang extern struct bus_type dsa_bus_type;
373f25b4638SDave Jiang extern struct bus_type iax_bus_type;
37442d279f9SDave Jiang 
3758e50d392SDave Jiang extern bool support_enqcmd;
3764b73e4ebSDave Jiang extern struct ida idxd_ida;
37747c16ac2SDave Jiang extern struct device_type dsa_device_type;
37847c16ac2SDave Jiang extern struct device_type iax_device_type;
3797c5dd23eSDave Jiang extern struct device_type idxd_wq_device_type;
38075b91130SDave Jiang extern struct device_type idxd_engine_device_type;
381defe49f9SDave Jiang extern struct device_type idxd_group_device_type;
38247c16ac2SDave Jiang 
38347c16ac2SDave Jiang static inline bool is_dsa_dev(struct device *dev)
38447c16ac2SDave Jiang {
38547c16ac2SDave Jiang 	return dev->type == &dsa_device_type;
38647c16ac2SDave Jiang }
38747c16ac2SDave Jiang 
38847c16ac2SDave Jiang static inline bool is_iax_dev(struct device *dev)
38947c16ac2SDave Jiang {
39047c16ac2SDave Jiang 	return dev->type == &iax_device_type;
39147c16ac2SDave Jiang }
39247c16ac2SDave Jiang 
39347c16ac2SDave Jiang static inline bool is_idxd_dev(struct device *dev)
39447c16ac2SDave Jiang {
39547c16ac2SDave Jiang 	return is_dsa_dev(dev) || is_iax_dev(dev);
39647c16ac2SDave Jiang }
3978e50d392SDave Jiang 
3987c5dd23eSDave Jiang static inline bool is_idxd_wq_dev(struct device *dev)
3997c5dd23eSDave Jiang {
4007c5dd23eSDave Jiang 	return dev->type == &idxd_wq_device_type;
4017c5dd23eSDave Jiang }
4027c5dd23eSDave Jiang 
4037c5dd23eSDave Jiang static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq)
4047c5dd23eSDave Jiang {
4057c5dd23eSDave Jiang 	if (wq->type == IDXD_WQT_KERNEL && strcmp(wq->name, "dmaengine") == 0)
4067c5dd23eSDave Jiang 		return true;
4077c5dd23eSDave Jiang 	return false;
4087c5dd23eSDave Jiang }
4097c5dd23eSDave Jiang 
4107c5dd23eSDave Jiang static inline bool is_idxd_wq_cdev(struct idxd_wq *wq)
4117c5dd23eSDave Jiang {
4127c5dd23eSDave Jiang 	return wq->type == IDXD_WQT_USER;
4137c5dd23eSDave Jiang }
4147c5dd23eSDave Jiang 
415bfe1d560SDave Jiang static inline bool wq_dedicated(struct idxd_wq *wq)
416bfe1d560SDave Jiang {
417bfe1d560SDave Jiang 	return test_bit(WQ_FLAG_DEDICATED, &wq->flags);
418bfe1d560SDave Jiang }
419bfe1d560SDave Jiang 
4208e50d392SDave Jiang static inline bool wq_shared(struct idxd_wq *wq)
4218e50d392SDave Jiang {
4228e50d392SDave Jiang 	return !test_bit(WQ_FLAG_DEDICATED, &wq->flags);
4238e50d392SDave Jiang }
4248e50d392SDave Jiang 
4258e50d392SDave Jiang static inline bool device_pasid_enabled(struct idxd_device *idxd)
4268e50d392SDave Jiang {
4278e50d392SDave Jiang 	return test_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags);
4288e50d392SDave Jiang }
4298e50d392SDave Jiang 
4308e50d392SDave Jiang static inline bool device_swq_supported(struct idxd_device *idxd)
4318e50d392SDave Jiang {
4328e50d392SDave Jiang 	return (support_enqcmd && device_pasid_enabled(idxd));
4338e50d392SDave Jiang }
4348e50d392SDave Jiang 
43542d279f9SDave Jiang enum idxd_portal_prot {
43642d279f9SDave Jiang 	IDXD_PORTAL_UNLIMITED = 0,
43742d279f9SDave Jiang 	IDXD_PORTAL_LIMITED,
43842d279f9SDave Jiang };
43942d279f9SDave Jiang 
440eb15e715SDave Jiang enum idxd_interrupt_type {
441eb15e715SDave Jiang 	IDXD_IRQ_MSIX = 0,
442eb15e715SDave Jiang 	IDXD_IRQ_IMS,
443eb15e715SDave Jiang };
444eb15e715SDave Jiang 
44542d279f9SDave Jiang static inline int idxd_get_wq_portal_offset(enum idxd_portal_prot prot)
44642d279f9SDave Jiang {
44742d279f9SDave Jiang 	return prot * 0x1000;
44842d279f9SDave Jiang }
44942d279f9SDave Jiang 
45042d279f9SDave Jiang static inline int idxd_get_wq_portal_full_offset(int wq_id,
45142d279f9SDave Jiang 						 enum idxd_portal_prot prot)
45242d279f9SDave Jiang {
45342d279f9SDave Jiang 	return ((wq_id * 4) << PAGE_SHIFT) + idxd_get_wq_portal_offset(prot);
45442d279f9SDave Jiang }
45542d279f9SDave Jiang 
456c52ca478SDave Jiang static inline void idxd_wq_get(struct idxd_wq *wq)
457c52ca478SDave Jiang {
458c52ca478SDave Jiang 	wq->client_count++;
459c52ca478SDave Jiang }
460c52ca478SDave Jiang 
461c52ca478SDave Jiang static inline void idxd_wq_put(struct idxd_wq *wq)
462c52ca478SDave Jiang {
463c52ca478SDave Jiang 	wq->client_count--;
464c52ca478SDave Jiang }
465c52ca478SDave Jiang 
466c52ca478SDave Jiang static inline int idxd_wq_refcount(struct idxd_wq *wq)
467c52ca478SDave Jiang {
468c52ca478SDave Jiang 	return wq->client_count;
469c52ca478SDave Jiang };
470c52ca478SDave Jiang 
4713ecfc913SDave Jiang int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv,
4723ecfc913SDave Jiang 					struct module *module, const char *mod_name);
4733ecfc913SDave Jiang #define idxd_driver_register(driver) \
4743ecfc913SDave Jiang 	__idxd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
4753ecfc913SDave Jiang 
4763ecfc913SDave Jiang void idxd_driver_unregister(struct idxd_device_driver *idxd_drv);
4773ecfc913SDave Jiang 
478c52ca478SDave Jiang int idxd_register_bus_type(void);
479c52ca478SDave Jiang void idxd_unregister_bus_type(void);
48047c16ac2SDave Jiang int idxd_register_devices(struct idxd_device *idxd);
48147c16ac2SDave Jiang void idxd_unregister_devices(struct idxd_device *idxd);
482c52ca478SDave Jiang int idxd_register_driver(void);
483c52ca478SDave Jiang void idxd_unregister_driver(void);
4845b0c68c4SDave Jiang void idxd_wqs_quiesce(struct idxd_device *idxd);
485bfe1d560SDave Jiang 
486bfe1d560SDave Jiang /* device interrupt control */
4876df0e6c5SDave Jiang void idxd_msix_perm_setup(struct idxd_device *idxd);
4886df0e6c5SDave Jiang void idxd_msix_perm_clear(struct idxd_device *idxd);
489bfe1d560SDave Jiang irqreturn_t idxd_misc_thread(int vec, void *data);
490bfe1d560SDave Jiang irqreturn_t idxd_wq_thread(int irq, void *data);
491bfe1d560SDave Jiang void idxd_mask_error_interrupts(struct idxd_device *idxd);
492bfe1d560SDave Jiang void idxd_unmask_error_interrupts(struct idxd_device *idxd);
493bfe1d560SDave Jiang void idxd_mask_msix_vectors(struct idxd_device *idxd);
4944548a6adSDave Jiang void idxd_mask_msix_vector(struct idxd_device *idxd, int vec_id);
4954548a6adSDave Jiang void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id);
496bfe1d560SDave Jiang 
497bfe1d560SDave Jiang /* device control */
498*1f2bb403SDave Jiang int drv_enable_wq(struct idxd_wq *wq);
49989e3becdSDave Jiang int idxd_device_init_reset(struct idxd_device *idxd);
500bfe1d560SDave Jiang int idxd_device_enable(struct idxd_device *idxd);
501bfe1d560SDave Jiang int idxd_device_disable(struct idxd_device *idxd);
5020d5c10b4SDave Jiang void idxd_device_reset(struct idxd_device *idxd);
5030dcfe41eSDave Jiang void idxd_device_clear_state(struct idxd_device *idxd);
504bfe1d560SDave Jiang int idxd_device_config(struct idxd_device *idxd);
5058e50d392SDave Jiang void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid);
5068c66bbdcSDave Jiang int idxd_device_load_config(struct idxd_device *idxd);
507eb15e715SDave Jiang int idxd_device_request_int_handle(struct idxd_device *idxd, int idx, int *handle,
508eb15e715SDave Jiang 				   enum idxd_interrupt_type irq_type);
509eb15e715SDave Jiang int idxd_device_release_int_handle(struct idxd_device *idxd, int handle,
510eb15e715SDave Jiang 				   enum idxd_interrupt_type irq_type);
511bfe1d560SDave Jiang 
512bfe1d560SDave Jiang /* work queue control */
5135b0c68c4SDave Jiang void idxd_wqs_unmap_portal(struct idxd_device *idxd);
514bfe1d560SDave Jiang int idxd_wq_alloc_resources(struct idxd_wq *wq);
515bfe1d560SDave Jiang void idxd_wq_free_resources(struct idxd_wq *wq);
516bfe1d560SDave Jiang int idxd_wq_enable(struct idxd_wq *wq);
5170dcfe41eSDave Jiang int idxd_wq_disable(struct idxd_wq *wq, bool reset_config);
5180d5c10b4SDave Jiang void idxd_wq_drain(struct idxd_wq *wq);
519ea9aadc0SDave Jiang void idxd_wq_reset(struct idxd_wq *wq);
520c52ca478SDave Jiang int idxd_wq_map_portal(struct idxd_wq *wq);
521c52ca478SDave Jiang void idxd_wq_unmap_portal(struct idxd_wq *wq);
5228e50d392SDave Jiang int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid);
5238e50d392SDave Jiang int idxd_wq_disable_pasid(struct idxd_wq *wq);
52493a40a6dSDave Jiang void idxd_wq_quiesce(struct idxd_wq *wq);
52593a40a6dSDave Jiang int idxd_wq_init_percpu_ref(struct idxd_wq *wq);
526bfe1d560SDave Jiang 
527d1dfe5b8SDave Jiang /* submission */
528d1dfe5b8SDave Jiang int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);
529d1dfe5b8SDave Jiang struct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype);
530d1dfe5b8SDave Jiang void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc);
531d1dfe5b8SDave Jiang 
5328f47d1a5SDave Jiang /* dmaengine */
5338f47d1a5SDave Jiang int idxd_register_dma_device(struct idxd_device *idxd);
5348f47d1a5SDave Jiang void idxd_unregister_dma_device(struct idxd_device *idxd);
5358f47d1a5SDave Jiang int idxd_register_dma_channel(struct idxd_wq *wq);
5368f47d1a5SDave Jiang void idxd_unregister_dma_channel(struct idxd_wq *wq);
5378f47d1a5SDave Jiang void idxd_parse_completion_status(u8 status, enum dmaengine_tx_result *res);
5388f47d1a5SDave Jiang void idxd_dma_complete_txd(struct idxd_desc *desc,
5398f47d1a5SDave Jiang 			   enum idxd_complete_type comp_type);
5408f47d1a5SDave Jiang 
54142d279f9SDave Jiang /* cdev */
54242d279f9SDave Jiang int idxd_cdev_register(void);
54342d279f9SDave Jiang void idxd_cdev_remove(void);
54442d279f9SDave Jiang int idxd_cdev_get_major(struct idxd_device *idxd);
54542d279f9SDave Jiang int idxd_wq_add_cdev(struct idxd_wq *wq);
54642d279f9SDave Jiang void idxd_wq_del_cdev(struct idxd_wq *wq);
54742d279f9SDave Jiang 
54881dd4d4dSTom Zanussi /* perfmon */
54981dd4d4dSTom Zanussi #if IS_ENABLED(CONFIG_INTEL_IDXD_PERFMON)
55081dd4d4dSTom Zanussi int perfmon_pmu_init(struct idxd_device *idxd);
55181dd4d4dSTom Zanussi void perfmon_pmu_remove(struct idxd_device *idxd);
55281dd4d4dSTom Zanussi void perfmon_counter_overflow(struct idxd_device *idxd);
55381dd4d4dSTom Zanussi void perfmon_init(void);
55481dd4d4dSTom Zanussi void perfmon_exit(void);
55581dd4d4dSTom Zanussi #else
55681dd4d4dSTom Zanussi static inline int perfmon_pmu_init(struct idxd_device *idxd) { return 0; }
55781dd4d4dSTom Zanussi static inline void perfmon_pmu_remove(struct idxd_device *idxd) {}
55881dd4d4dSTom Zanussi static inline void perfmon_counter_overflow(struct idxd_device *idxd) {}
55981dd4d4dSTom Zanussi static inline void perfmon_init(void) {}
56081dd4d4dSTom Zanussi static inline void perfmon_exit(void) {}
56181dd4d4dSTom Zanussi #endif
56281dd4d4dSTom Zanussi 
5636b4b87f2SDave Jiang static inline void complete_desc(struct idxd_desc *desc, enum idxd_complete_type reason)
5646b4b87f2SDave Jiang {
5656b4b87f2SDave Jiang 	idxd_dma_complete_txd(desc, reason);
5666b4b87f2SDave Jiang 	idxd_free_desc(desc->wq, desc);
5676b4b87f2SDave Jiang }
5686b4b87f2SDave Jiang 
569bfe1d560SDave Jiang #endif
570