xref: /openbmc/linux/drivers/dma/idxd/idxd.h (revision 8cacaaa4)
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>
13de5819b9SJerry Snitselaar #include <linux/bitmap.h>
1481dd4d4dSTom Zanussi #include <linux/perf_event.h>
15fffaed1eSJacob Pan #include <linux/iommu.h>
16a9c17152SDave Jiang #include <uapi/linux/idxd.h>
17bfe1d560SDave Jiang #include "registers.h"
18bfe1d560SDave Jiang 
19bfe1d560SDave Jiang #define IDXD_DRIVER_VERSION	"1.00"
20bfe1d560SDave Jiang 
21bfe1d560SDave Jiang extern struct kmem_cache *idxd_desc_pool;
22ade8a86bSDave Jiang extern bool tc_override;
23bfe1d560SDave Jiang 
2439786285SDave Jiang struct idxd_wq;
25700af3a0SDave Jiang struct idxd_dev;
26700af3a0SDave Jiang 
27700af3a0SDave Jiang enum idxd_dev_type {
28700af3a0SDave Jiang 	IDXD_DEV_NONE = -1,
29700af3a0SDave Jiang 	IDXD_DEV_DSA = 0,
30700af3a0SDave Jiang 	IDXD_DEV_IAX,
31700af3a0SDave Jiang 	IDXD_DEV_WQ,
32700af3a0SDave Jiang 	IDXD_DEV_GROUP,
33700af3a0SDave Jiang 	IDXD_DEV_ENGINE,
34700af3a0SDave Jiang 	IDXD_DEV_CDEV,
35e6fd6d7eSDave Jiang 	IDXD_DEV_CDEV_FILE,
36700af3a0SDave Jiang 	IDXD_DEV_MAX_TYPE,
37700af3a0SDave Jiang };
38700af3a0SDave Jiang 
39700af3a0SDave Jiang struct idxd_dev {
40700af3a0SDave Jiang 	struct device conf_dev;
41700af3a0SDave Jiang 	enum idxd_dev_type type;
42700af3a0SDave Jiang };
4339786285SDave Jiang 
44bfe1d560SDave Jiang #define IDXD_REG_TIMEOUT	50
45bfe1d560SDave Jiang #define IDXD_DRAIN_TIMEOUT	5000
46bfe1d560SDave Jiang 
47bfe1d560SDave Jiang enum idxd_type {
48bfe1d560SDave Jiang 	IDXD_TYPE_UNKNOWN = -1,
49bfe1d560SDave Jiang 	IDXD_TYPE_DSA = 0,
50f25b4638SDave Jiang 	IDXD_TYPE_IAX,
51f25b4638SDave Jiang 	IDXD_TYPE_MAX,
52bfe1d560SDave Jiang };
53bfe1d560SDave Jiang 
54bfe1d560SDave Jiang #define IDXD_NAME_SIZE		128
5581dd4d4dSTom Zanussi #define IDXD_PMU_EVENT_MAX	64
56bfe1d560SDave Jiang 
577930d855SDave Jiang #define IDXD_ENQCMDS_RETRIES		32
587930d855SDave Jiang #define IDXD_ENQCMDS_MAX_RETRIES	64
597930d855SDave Jiang 
60bfe1d560SDave Jiang struct idxd_device_driver {
61da5a11d7SDave Jiang 	const char *name;
625fee6567SDave Jiang 	enum idxd_dev_type *type;
63fcc2281bSDave Jiang 	int (*probe)(struct idxd_dev *idxd_dev);
64fcc2281bSDave Jiang 	void (*remove)(struct idxd_dev *idxd_dev);
65bfe1d560SDave Jiang 	struct device_driver drv;
66bfe1d560SDave Jiang };
67bfe1d560SDave Jiang 
68c05257b5SDave Jiang extern struct idxd_device_driver dsa_drv;
69034b3290SDave Jiang extern struct idxd_device_driver idxd_drv;
700cda4f69SDave Jiang extern struct idxd_device_driver idxd_dmaengine_drv;
71448c3de8SDave Jiang extern struct idxd_device_driver idxd_user_drv;
72c05257b5SDave Jiang 
738b67426eSDave Jiang #define INVALID_INT_HANDLE	-1
74bfe1d560SDave Jiang struct idxd_irq_entry {
75bfe1d560SDave Jiang 	int id;
765fc8e85fSDave Jiang 	int vector;
77bfe1d560SDave Jiang 	struct llist_head pending_llist;
78bfe1d560SDave Jiang 	struct list_head work_list;
79e4f4d8cdSDave Jiang 	/*
80e4f4d8cdSDave Jiang 	 * Lock to protect access between irq thread process descriptor
81e4f4d8cdSDave Jiang 	 * and irq thread processing error descriptor.
82e4f4d8cdSDave Jiang 	 */
83e4f4d8cdSDave Jiang 	spinlock_t list_lock;
848b67426eSDave Jiang 	int int_handle;
858b67426eSDave Jiang 	ioasid_t pasid;
86bfe1d560SDave Jiang };
87bfe1d560SDave Jiang 
88bfe1d560SDave Jiang struct idxd_group {
89700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
90bfe1d560SDave Jiang 	struct idxd_device *idxd;
91bfe1d560SDave Jiang 	struct grpcfg grpcfg;
92bfe1d560SDave Jiang 	int id;
93bfe1d560SDave Jiang 	int num_engines;
94bfe1d560SDave Jiang 	int num_wqs;
957ed6f1b8SDave Jiang 	bool use_rdbuf_limit;
967ed6f1b8SDave Jiang 	u8 rdbufs_allowed;
977ed6f1b8SDave Jiang 	u8 rdbufs_reserved;
98bfe1d560SDave Jiang 	int tc_a;
99bfe1d560SDave Jiang 	int tc_b;
1001f273752SDave Jiang 	int desc_progress_limit;
1017ca68fa3SDave Jiang 	int batch_progress_limit;
102bfe1d560SDave Jiang };
103bfe1d560SDave Jiang 
10481dd4d4dSTom Zanussi struct idxd_pmu {
10581dd4d4dSTom Zanussi 	struct idxd_device *idxd;
10681dd4d4dSTom Zanussi 
10781dd4d4dSTom Zanussi 	struct perf_event *event_list[IDXD_PMU_EVENT_MAX];
10881dd4d4dSTom Zanussi 	int n_events;
10981dd4d4dSTom Zanussi 
11081dd4d4dSTom Zanussi 	DECLARE_BITMAP(used_mask, IDXD_PMU_EVENT_MAX);
11181dd4d4dSTom Zanussi 
11281dd4d4dSTom Zanussi 	struct pmu pmu;
11381dd4d4dSTom Zanussi 	char name[IDXD_NAME_SIZE];
11481dd4d4dSTom Zanussi 	int cpu;
11581dd4d4dSTom Zanussi 
11681dd4d4dSTom Zanussi 	int n_counters;
11781dd4d4dSTom Zanussi 	int counter_width;
11881dd4d4dSTom Zanussi 	int n_event_categories;
11981dd4d4dSTom Zanussi 
12081dd4d4dSTom Zanussi 	bool per_counter_caps_supported;
12181dd4d4dSTom Zanussi 	unsigned long supported_event_categories;
12281dd4d4dSTom Zanussi 
12381dd4d4dSTom Zanussi 	unsigned long supported_filters;
12481dd4d4dSTom Zanussi 	int n_filters;
12581dd4d4dSTom Zanussi 
12681dd4d4dSTom Zanussi 	struct hlist_node cpuhp_node;
12781dd4d4dSTom Zanussi };
12881dd4d4dSTom Zanussi 
129bfe1d560SDave Jiang #define IDXD_MAX_PRIORITY	0xf
130bfe1d560SDave Jiang 
131fecae134SDave Jiang enum {
132fecae134SDave Jiang 	COUNTER_FAULTS = 0,
133fecae134SDave Jiang 	COUNTER_FAULT_FAILS,
134fecae134SDave Jiang 	COUNTER_MAX
135fecae134SDave Jiang };
136fecae134SDave Jiang 
137bfe1d560SDave Jiang enum idxd_wq_state {
138bfe1d560SDave Jiang 	IDXD_WQ_DISABLED = 0,
139bfe1d560SDave Jiang 	IDXD_WQ_ENABLED,
140bfe1d560SDave Jiang };
141bfe1d560SDave Jiang 
142bfe1d560SDave Jiang enum idxd_wq_flag {
143bfe1d560SDave Jiang 	WQ_FLAG_DEDICATED = 0,
1448e50d392SDave Jiang 	WQ_FLAG_BLOCK_ON_FAULT,
14522bd0df8SDave Jiang 	WQ_FLAG_ATS_DISABLE,
146f2dc3271SDave Jiang 	WQ_FLAG_PRS_DISABLE,
147bfe1d560SDave Jiang };
148bfe1d560SDave Jiang 
149bfe1d560SDave Jiang enum idxd_wq_type {
150bfe1d560SDave Jiang 	IDXD_WQT_NONE = 0,
151bfe1d560SDave Jiang 	IDXD_WQT_KERNEL,
15242d279f9SDave Jiang 	IDXD_WQT_USER,
15342d279f9SDave Jiang };
15442d279f9SDave Jiang 
15542d279f9SDave Jiang struct idxd_cdev {
15604922b74SDave Jiang 	struct idxd_wq *wq;
15742d279f9SDave Jiang 	struct cdev cdev;
158700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
15942d279f9SDave Jiang 	int minor;
160bfe1d560SDave Jiang };
161bfe1d560SDave Jiang 
162bfe1d560SDave Jiang #define IDXD_ALLOCATED_BATCH_SIZE	128U
163bfe1d560SDave Jiang #define WQ_NAME_SIZE   1024
164bfe1d560SDave Jiang #define WQ_TYPE_SIZE   10
165bfe1d560SDave Jiang 
16692452a72SDave Jiang #define WQ_DEFAULT_QUEUE_DEPTH		16
16792452a72SDave Jiang #define WQ_DEFAULT_MAX_XFER		SZ_2M
16892452a72SDave Jiang #define WQ_DEFAULT_MAX_BATCH		32
16992452a72SDave Jiang 
170d1dfe5b8SDave Jiang enum idxd_op_type {
171d1dfe5b8SDave Jiang 	IDXD_OP_BLOCK = 0,
172d1dfe5b8SDave Jiang 	IDXD_OP_NONBLOCK = 1,
173d1dfe5b8SDave Jiang };
174d1dfe5b8SDave Jiang 
1758f47d1a5SDave Jiang enum idxd_complete_type {
1768f47d1a5SDave Jiang 	IDXD_COMPLETE_NORMAL = 0,
1778f47d1a5SDave Jiang 	IDXD_COMPLETE_ABORT,
1788e50d392SDave Jiang 	IDXD_COMPLETE_DEV_FAIL,
1798f47d1a5SDave Jiang };
1808f47d1a5SDave Jiang 
18139786285SDave Jiang struct idxd_dma_chan {
18239786285SDave Jiang 	struct dma_chan chan;
18339786285SDave Jiang 	struct idxd_wq *wq;
18439786285SDave Jiang };
18539786285SDave Jiang 
186bfe1d560SDave Jiang struct idxd_wq {
1878e50d392SDave Jiang 	void __iomem *portal;
188a9c17152SDave Jiang 	u32 portal_offset;
1897930d855SDave Jiang 	unsigned int enqcmds_retries;
19093a40a6dSDave Jiang 	struct percpu_ref wq_active;
19193a40a6dSDave Jiang 	struct completion wq_dead;
19256fc39f5SDave Jiang 	struct completion wq_resurrect;
193700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
19404922b74SDave Jiang 	struct idxd_cdev *idxd_cdev;
19504922b74SDave Jiang 	struct wait_queue_head err_queue;
1962f30decdSDave Jiang 	struct workqueue_struct *wq;
197bfe1d560SDave Jiang 	struct idxd_device *idxd;
198bfe1d560SDave Jiang 	int id;
199ec0d6423SDave Jiang 	struct idxd_irq_entry ie;
200bfe1d560SDave Jiang 	enum idxd_wq_type type;
201bfe1d560SDave Jiang 	struct idxd_group *group;
202bfe1d560SDave Jiang 	int client_count;
203bfe1d560SDave Jiang 	struct mutex wq_lock;	/* mutex for workqueue */
204bfe1d560SDave Jiang 	u32 size;
205bfe1d560SDave Jiang 	u32 threshold;
206bfe1d560SDave Jiang 	u32 priority;
207bfe1d560SDave Jiang 	enum idxd_wq_state state;
208bfe1d560SDave Jiang 	unsigned long flags;
209d98793b5SDave Jiang 	union wqcfg *wqcfg;
210b0325aefSDave Jiang 	unsigned long *opcap_bmap;
211b0325aefSDave Jiang 
212bfe1d560SDave Jiang 	struct dsa_hw_desc **hw_descs;
213bfe1d560SDave Jiang 	int num_descs;
214f25b4638SDave Jiang 	union {
215bfe1d560SDave Jiang 		struct dsa_completion_record *compls;
216f25b4638SDave Jiang 		struct iax_completion_record *iax_compls;
217f25b4638SDave Jiang 	};
218bfe1d560SDave Jiang 	dma_addr_t compls_addr;
219bfe1d560SDave Jiang 	int compls_size;
220bfe1d560SDave Jiang 	struct idxd_desc **descs;
2210705107fSDave Jiang 	struct sbitmap_queue sbq;
22239786285SDave Jiang 	struct idxd_dma_chan *idxd_chan;
223bfe1d560SDave Jiang 	char name[WQ_NAME_SIZE + 1];
224d7aad555SDave Jiang 	u64 max_xfer_bytes;
225e7184b15SDave Jiang 	u32 max_batch_size;
226b022f597SFenghua Yu 
227b022f597SFenghua Yu 	/* Lock to protect upasid_xa access. */
228b022f597SFenghua Yu 	struct mutex uc_lock;
229b022f597SFenghua Yu 	struct xarray upasid_xa;
230bfe1d560SDave Jiang };
231bfe1d560SDave Jiang 
232bfe1d560SDave Jiang struct idxd_engine {
233700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
234bfe1d560SDave Jiang 	int id;
235bfe1d560SDave Jiang 	struct idxd_group *group;
236bfe1d560SDave Jiang 	struct idxd_device *idxd;
237bfe1d560SDave Jiang };
238bfe1d560SDave Jiang 
239bfe1d560SDave Jiang /* shadow registers */
240bfe1d560SDave Jiang struct idxd_hw {
241bfe1d560SDave Jiang 	u32 version;
242bfe1d560SDave Jiang 	union gen_cap_reg gen_cap;
243bfe1d560SDave Jiang 	union wq_cap_reg wq_cap;
244bfe1d560SDave Jiang 	union group_cap_reg group_cap;
245bfe1d560SDave Jiang 	union engine_cap_reg engine_cap;
246bfe1d560SDave Jiang 	struct opcap opcap;
247eb15e715SDave Jiang 	u32 cmd_cap;
2489f0d99b3SDave Jiang 	union iaa_cap_reg iaa_cap;
249bfe1d560SDave Jiang };
250bfe1d560SDave Jiang 
251bfe1d560SDave Jiang enum idxd_device_state {
252bfe1d560SDave Jiang 	IDXD_DEV_HALTED = -1,
253bfe1d560SDave Jiang 	IDXD_DEV_DISABLED = 0,
254bfe1d560SDave Jiang 	IDXD_DEV_ENABLED,
255bfe1d560SDave Jiang };
256bfe1d560SDave Jiang 
257bfe1d560SDave Jiang enum idxd_device_flag {
258bfe1d560SDave Jiang 	IDXD_FLAG_CONFIGURABLE = 0,
2590d5c10b4SDave Jiang 	IDXD_FLAG_CMD_RUNNING,
2608e50d392SDave Jiang 	IDXD_FLAG_PASID_ENABLED,
26142a1b738SDave Jiang 	IDXD_FLAG_USER_PASID_ENABLED,
262bfe1d560SDave Jiang };
263bfe1d560SDave Jiang 
26439786285SDave Jiang struct idxd_dma_dev {
26539786285SDave Jiang 	struct idxd_device *idxd;
26639786285SDave Jiang 	struct dma_device dma;
26739786285SDave Jiang };
26839786285SDave Jiang 
269435b512dSDave Jiang struct idxd_driver_data {
270435b512dSDave Jiang 	const char *name_prefix;
271bfe1d560SDave Jiang 	enum idxd_type type;
272435b512dSDave Jiang 	struct device_type *dev_type;
273435b512dSDave Jiang 	int compl_size;
274435b512dSDave Jiang 	int align;
275c40bd7d9SDave Jiang 	int evl_cr_off;
2762442b747SDave Jiang 	int cr_status_off;
2772442b747SDave Jiang 	int cr_result_off;
2788cacaaa4SArjan van de Ven 	bool user_submission_safe;
279435b512dSDave Jiang };
280435b512dSDave Jiang 
2811649091fSDave Jiang struct idxd_evl {
282244da66cSDave Jiang 	/* Lock to protect event log access. */
283758071a3SRex Zhang 	struct mutex lock;
284244da66cSDave Jiang 	void *log;
285244da66cSDave Jiang 	dma_addr_t dma;
286244da66cSDave Jiang 	/* Total size of event log = number of entries * entry size. */
287244da66cSDave Jiang 	unsigned int log_size;
288244da66cSDave Jiang 	/* The number of entries in the event log. */
2891649091fSDave Jiang 	u16 size;
290c40bd7d9SDave Jiang 	unsigned long *bmap;
2912442b747SDave Jiang 	bool batch_fail[IDXD_MAX_BATCH_IDENT];
2921649091fSDave Jiang };
2931649091fSDave Jiang 
294c2f156bfSDave Jiang struct idxd_evl_fault {
295c2f156bfSDave Jiang 	struct work_struct work;
296c2f156bfSDave Jiang 	struct idxd_wq *wq;
297c2f156bfSDave Jiang 	u8 status;
298c2f156bfSDave Jiang 
299c2f156bfSDave Jiang 	/* make this last member always */
300c2f156bfSDave Jiang 	struct __evl_entry entry[];
301435b512dSDave Jiang };
302435b512dSDave Jiang 
303435b512dSDave Jiang struct idxd_device {
304700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
305435b512dSDave Jiang 	struct idxd_driver_data *data;
306bfe1d560SDave Jiang 	struct list_head list;
307bfe1d560SDave Jiang 	struct idxd_hw hw;
308bfe1d560SDave Jiang 	enum idxd_device_state state;
309bfe1d560SDave Jiang 	unsigned long flags;
310bfe1d560SDave Jiang 	int id;
31142d279f9SDave Jiang 	int major;
312125d1037SDave Jiang 	u32 cmd_status;
313ec0d6423SDave Jiang 	struct idxd_irq_entry ie;	/* misc irq, msix 0 */
314bfe1d560SDave Jiang 
315bfe1d560SDave Jiang 	struct pci_dev *pdev;
316bfe1d560SDave Jiang 	void __iomem *reg_base;
317bfe1d560SDave Jiang 
318bfe1d560SDave Jiang 	spinlock_t dev_lock;	/* spinlock for device */
31953b2ee7fSDave Jiang 	spinlock_t cmd_lock;	/* spinlock for device commands */
3200d5c10b4SDave Jiang 	struct completion *cmd_done;
321defe49f9SDave Jiang 	struct idxd_group **groups;
3227c5dd23eSDave Jiang 	struct idxd_wq **wqs;
32375b91130SDave Jiang 	struct idxd_engine **engines;
324bfe1d560SDave Jiang 
3258e50d392SDave Jiang 	struct iommu_sva *sva;
3268e50d392SDave Jiang 	unsigned int pasid;
3278e50d392SDave Jiang 
328bfe1d560SDave Jiang 	int num_groups;
3298b67426eSDave Jiang 	int irq_cnt;
3308b67426eSDave Jiang 	bool request_int_handles;
331bfe1d560SDave Jiang 
332bfe1d560SDave Jiang 	u32 msix_perm_offset;
333bfe1d560SDave Jiang 	u32 wqcfg_offset;
334bfe1d560SDave Jiang 	u32 grpcfg_offset;
335bfe1d560SDave Jiang 	u32 perfmon_offset;
336bfe1d560SDave Jiang 
337bfe1d560SDave Jiang 	u64 max_xfer_bytes;
338bfe1d560SDave Jiang 	u32 max_batch_size;
339bfe1d560SDave Jiang 	int max_groups;
340bfe1d560SDave Jiang 	int max_engines;
3417ed6f1b8SDave Jiang 	int max_rdbufs;
342bfe1d560SDave Jiang 	int max_wqs;
343bfe1d560SDave Jiang 	int max_wq_size;
3447ed6f1b8SDave Jiang 	int rdbuf_limit;
3457ed6f1b8SDave Jiang 	int nr_rdbufs;		/* non-reserved read buffers */
346d98793b5SDave Jiang 	unsigned int wqcfg_size;
347de5819b9SJerry Snitselaar 	unsigned long *wq_enable_map;
348bfe1d560SDave Jiang 
349bfe1d560SDave Jiang 	union sw_err_reg sw_err;
3500d5c10b4SDave Jiang 	wait_queue_head_t cmd_waitq;
3518f47d1a5SDave Jiang 
35239786285SDave Jiang 	struct idxd_dma_dev *idxd_dma;
3530d5c10b4SDave Jiang 	struct workqueue_struct *wq;
3540d5c10b4SDave Jiang 	struct work_struct work;
355eb15e715SDave Jiang 
35681dd4d4dSTom Zanussi 	struct idxd_pmu *idxd_pmu;
357a8563a33SDave Jiang 
358a8563a33SDave Jiang 	unsigned long *opcap_bmap;
3591649091fSDave Jiang 	struct idxd_evl *evl;
360c2f156bfSDave Jiang 	struct kmem_cache *evl_cache;
3615fbe6503SDave Jiang 
3625fbe6503SDave Jiang 	struct dentry *dbgfs_dir;
3635fbe6503SDave Jiang 	struct dentry *dbgfs_evl_file;
3648cacaaa4SArjan van de Ven 
3658cacaaa4SArjan van de Ven 	bool user_submission_safe;
366bfe1d560SDave Jiang };
367bfe1d560SDave Jiang 
evl_ent_size(struct idxd_device * idxd)368244da66cSDave Jiang static inline unsigned int evl_ent_size(struct idxd_device *idxd)
369244da66cSDave Jiang {
370244da66cSDave Jiang 	return idxd->hw.gen_cap.evl_support ?
371244da66cSDave Jiang 	       (32 * (1 << idxd->hw.gen_cap.evl_support)) : 0;
372244da66cSDave Jiang }
373244da66cSDave Jiang 
evl_size(struct idxd_device * idxd)374244da66cSDave Jiang static inline unsigned int evl_size(struct idxd_device *idxd)
375244da66cSDave Jiang {
376244da66cSDave Jiang 	return idxd->evl->size * evl_ent_size(idxd);
377244da66cSDave Jiang }
378244da66cSDave Jiang 
379bfe1d560SDave Jiang /* IDXD software descriptor */
380bfe1d560SDave Jiang struct idxd_desc {
381f25b4638SDave Jiang 	union {
382bfe1d560SDave Jiang 		struct dsa_hw_desc *hw;
383f25b4638SDave Jiang 		struct iax_hw_desc *iax_hw;
384f25b4638SDave Jiang 	};
385bfe1d560SDave Jiang 	dma_addr_t desc_dma;
386f25b4638SDave Jiang 	union {
387bfe1d560SDave Jiang 		struct dsa_completion_record *completion;
388f25b4638SDave Jiang 		struct iax_completion_record *iax_completion;
389f25b4638SDave Jiang 	};
390bfe1d560SDave Jiang 	dma_addr_t compl_dma;
3918f47d1a5SDave Jiang 	struct dma_async_tx_descriptor txd;
392bfe1d560SDave Jiang 	struct llist_node llnode;
393bfe1d560SDave Jiang 	struct list_head list;
394bfe1d560SDave Jiang 	int id;
3950705107fSDave Jiang 	int cpu;
396bfe1d560SDave Jiang 	struct idxd_wq *wq;
397bfe1d560SDave Jiang };
398bfe1d560SDave Jiang 
3996b4b87f2SDave Jiang /*
4006b4b87f2SDave Jiang  * This is software defined error for the completion status. We overload the error code
4016b4b87f2SDave Jiang  * that will never appear in completion status and only SWERR register.
4026b4b87f2SDave Jiang  */
4036b4b87f2SDave Jiang enum idxd_completion_status {
4046b4b87f2SDave Jiang 	IDXD_COMP_DESC_ABORT = 0xff,
4056b4b87f2SDave Jiang };
4066b4b87f2SDave Jiang 
407700af3a0SDave Jiang #define idxd_confdev(idxd) &idxd->idxd_dev.conf_dev
408700af3a0SDave Jiang #define wq_confdev(wq) &wq->idxd_dev.conf_dev
409700af3a0SDave Jiang #define engine_confdev(engine) &engine->idxd_dev.conf_dev
410700af3a0SDave Jiang #define group_confdev(group) &group->idxd_dev.conf_dev
411700af3a0SDave Jiang #define cdev_dev(cdev) &cdev->idxd_dev.conf_dev
412e6fd6d7eSDave Jiang #define user_ctx_dev(ctx) (&(ctx)->idxd_dev.conf_dev)
413700af3a0SDave Jiang 
414700af3a0SDave Jiang #define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev)
415fcc2281bSDave Jiang #define idxd_dev_to_idxd(idxd_dev) container_of(idxd_dev, struct idxd_device, idxd_dev)
416fcc2281bSDave Jiang #define idxd_dev_to_wq(idxd_dev) container_of(idxd_dev, struct idxd_wq, idxd_dev)
417700af3a0SDave Jiang 
confdev_to_idxd(struct device * dev)418700af3a0SDave Jiang static inline struct idxd_device *confdev_to_idxd(struct device *dev)
419700af3a0SDave Jiang {
420700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
421700af3a0SDave Jiang 
422fcc2281bSDave Jiang 	return idxd_dev_to_idxd(idxd_dev);
423700af3a0SDave Jiang }
424700af3a0SDave Jiang 
confdev_to_wq(struct device * dev)425700af3a0SDave Jiang static inline struct idxd_wq *confdev_to_wq(struct device *dev)
426700af3a0SDave Jiang {
427700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
428700af3a0SDave Jiang 
429fcc2281bSDave Jiang 	return idxd_dev_to_wq(idxd_dev);
430700af3a0SDave Jiang }
431700af3a0SDave Jiang 
confdev_to_engine(struct device * dev)432700af3a0SDave Jiang static inline struct idxd_engine *confdev_to_engine(struct device *dev)
433700af3a0SDave Jiang {
434700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
435700af3a0SDave Jiang 
436700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_engine, idxd_dev);
437700af3a0SDave Jiang }
438700af3a0SDave Jiang 
confdev_to_group(struct device * dev)439700af3a0SDave Jiang static inline struct idxd_group *confdev_to_group(struct device *dev)
440700af3a0SDave Jiang {
441700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
442700af3a0SDave Jiang 
443700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_group, idxd_dev);
444700af3a0SDave Jiang }
445700af3a0SDave Jiang 
dev_to_cdev(struct device * dev)446700af3a0SDave Jiang static inline struct idxd_cdev *dev_to_cdev(struct device *dev)
447700af3a0SDave Jiang {
448700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
449700af3a0SDave Jiang 
450700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_cdev, idxd_dev);
451700af3a0SDave Jiang }
452700af3a0SDave Jiang 
idxd_dev_set_type(struct idxd_dev * idev,int type)453700af3a0SDave Jiang static inline void idxd_dev_set_type(struct idxd_dev *idev, int type)
454700af3a0SDave Jiang {
455700af3a0SDave Jiang 	if (type >= IDXD_DEV_MAX_TYPE) {
456700af3a0SDave Jiang 		idev->type = IDXD_DEV_NONE;
457700af3a0SDave Jiang 		return;
458700af3a0SDave Jiang 	}
459700af3a0SDave Jiang 
460700af3a0SDave Jiang 	idev->type = type;
461700af3a0SDave Jiang }
462bfe1d560SDave Jiang 
idxd_get_ie(struct idxd_device * idxd,int idx)463ec0d6423SDave Jiang static inline struct idxd_irq_entry *idxd_get_ie(struct idxd_device *idxd, int idx)
464ec0d6423SDave Jiang {
465ec0d6423SDave Jiang 	return (idx == 0) ? &idxd->ie : &idxd->wqs[idx - 1]->ie;
466ec0d6423SDave Jiang }
467ec0d6423SDave Jiang 
ie_to_wq(struct idxd_irq_entry * ie)468ec0d6423SDave Jiang static inline struct idxd_wq *ie_to_wq(struct idxd_irq_entry *ie)
469ec0d6423SDave Jiang {
470ec0d6423SDave Jiang 	return container_of(ie, struct idxd_wq, ie);
471ec0d6423SDave Jiang }
472ec0d6423SDave Jiang 
ie_to_idxd(struct idxd_irq_entry * ie)473ec0d6423SDave Jiang static inline struct idxd_device *ie_to_idxd(struct idxd_irq_entry *ie)
474ec0d6423SDave Jiang {
475ec0d6423SDave Jiang 	return container_of(ie, struct idxd_device, ie);
476ec0d6423SDave Jiang }
477ec0d6423SDave Jiang 
idxd_set_user_intr(struct idxd_device * idxd,bool enable)478f5ccf55eSJacob Pan static inline void idxd_set_user_intr(struct idxd_device *idxd, bool enable)
479f5ccf55eSJacob Pan {
480f5ccf55eSJacob Pan 	union gencfg_reg reg;
481f5ccf55eSJacob Pan 
482f5ccf55eSJacob Pan 	reg.bits = ioread32(idxd->reg_base + IDXD_GENCFG_OFFSET);
483f5ccf55eSJacob Pan 	reg.user_int_en = enable;
484f5ccf55eSJacob Pan 	iowrite32(reg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET);
485f5ccf55eSJacob Pan }
486f5ccf55eSJacob Pan 
48742d279f9SDave Jiang extern struct bus_type dsa_bus_type;
48842d279f9SDave Jiang 
4898e50d392SDave Jiang extern bool support_enqcmd;
4904b73e4ebSDave Jiang extern struct ida idxd_ida;
49147c16ac2SDave Jiang extern struct device_type dsa_device_type;
49247c16ac2SDave Jiang extern struct device_type iax_device_type;
4937c5dd23eSDave Jiang extern struct device_type idxd_wq_device_type;
49475b91130SDave Jiang extern struct device_type idxd_engine_device_type;
495defe49f9SDave Jiang extern struct device_type idxd_group_device_type;
49647c16ac2SDave Jiang 
is_dsa_dev(struct idxd_dev * idxd_dev)497fcc2281bSDave Jiang static inline bool is_dsa_dev(struct idxd_dev *idxd_dev)
49847c16ac2SDave Jiang {
499fcc2281bSDave Jiang 	return idxd_dev->type == IDXD_DEV_DSA;
50047c16ac2SDave Jiang }
50147c16ac2SDave Jiang 
is_iax_dev(struct idxd_dev * idxd_dev)502fcc2281bSDave Jiang static inline bool is_iax_dev(struct idxd_dev *idxd_dev)
50347c16ac2SDave Jiang {
504fcc2281bSDave Jiang 	return idxd_dev->type == IDXD_DEV_IAX;
50547c16ac2SDave Jiang }
50647c16ac2SDave Jiang 
is_idxd_dev(struct idxd_dev * idxd_dev)507fcc2281bSDave Jiang static inline bool is_idxd_dev(struct idxd_dev *idxd_dev)
50847c16ac2SDave Jiang {
509fcc2281bSDave Jiang 	return is_dsa_dev(idxd_dev) || is_iax_dev(idxd_dev);
51047c16ac2SDave Jiang }
5118e50d392SDave Jiang 
is_idxd_wq_dev(struct idxd_dev * idxd_dev)512fcc2281bSDave Jiang static inline bool is_idxd_wq_dev(struct idxd_dev *idxd_dev)
5137c5dd23eSDave Jiang {
514fcc2281bSDave Jiang 	return idxd_dev->type == IDXD_DEV_WQ;
5157c5dd23eSDave Jiang }
5167c5dd23eSDave Jiang 
is_idxd_wq_dmaengine(struct idxd_wq * wq)5177c5dd23eSDave Jiang static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq)
5187c5dd23eSDave Jiang {
5197c5dd23eSDave Jiang 	if (wq->type == IDXD_WQT_KERNEL && strcmp(wq->name, "dmaengine") == 0)
5207c5dd23eSDave Jiang 		return true;
5217c5dd23eSDave Jiang 	return false;
5227c5dd23eSDave Jiang }
5237c5dd23eSDave Jiang 
is_idxd_wq_user(struct idxd_wq * wq)5246e7f3ee9SDave Jiang static inline bool is_idxd_wq_user(struct idxd_wq *wq)
5257c5dd23eSDave Jiang {
5267c5dd23eSDave Jiang 	return wq->type == IDXD_WQT_USER;
5277c5dd23eSDave Jiang }
5287c5dd23eSDave Jiang 
is_idxd_wq_kernel(struct idxd_wq * wq)5296e7f3ee9SDave Jiang static inline bool is_idxd_wq_kernel(struct idxd_wq *wq)
5306e7f3ee9SDave Jiang {
5316e7f3ee9SDave Jiang 	return wq->type == IDXD_WQT_KERNEL;
5326e7f3ee9SDave Jiang }
5336e7f3ee9SDave Jiang 
wq_dedicated(struct idxd_wq * wq)534bfe1d560SDave Jiang static inline bool wq_dedicated(struct idxd_wq *wq)
535bfe1d560SDave Jiang {
536bfe1d560SDave Jiang 	return test_bit(WQ_FLAG_DEDICATED, &wq->flags);
537bfe1d560SDave Jiang }
538bfe1d560SDave Jiang 
wq_shared(struct idxd_wq * wq)5398e50d392SDave Jiang static inline bool wq_shared(struct idxd_wq *wq)
5408e50d392SDave Jiang {
5418e50d392SDave Jiang 	return !test_bit(WQ_FLAG_DEDICATED, &wq->flags);
5428e50d392SDave Jiang }
5438e50d392SDave Jiang 
device_pasid_enabled(struct idxd_device * idxd)5448e50d392SDave Jiang static inline bool device_pasid_enabled(struct idxd_device *idxd)
5458e50d392SDave Jiang {
5468e50d392SDave Jiang 	return test_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags);
5478e50d392SDave Jiang }
5488e50d392SDave Jiang 
device_user_pasid_enabled(struct idxd_device * idxd)54942a1b738SDave Jiang static inline bool device_user_pasid_enabled(struct idxd_device *idxd)
5508e50d392SDave Jiang {
55142a1b738SDave Jiang 	return test_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags);
55242a1b738SDave Jiang }
55342a1b738SDave Jiang 
wq_pasid_enabled(struct idxd_wq * wq)55442a1b738SDave Jiang static inline bool wq_pasid_enabled(struct idxd_wq *wq)
55542a1b738SDave Jiang {
55642a1b738SDave Jiang 	return (is_idxd_wq_kernel(wq) && device_pasid_enabled(wq->idxd)) ||
55742a1b738SDave Jiang 	       (is_idxd_wq_user(wq) && device_user_pasid_enabled(wq->idxd));
55842a1b738SDave Jiang }
55942a1b738SDave Jiang 
wq_shared_supported(struct idxd_wq * wq)56042a1b738SDave Jiang static inline bool wq_shared_supported(struct idxd_wq *wq)
56142a1b738SDave Jiang {
56242a1b738SDave Jiang 	return (support_enqcmd && wq_pasid_enabled(wq));
5638e50d392SDave Jiang }
5648e50d392SDave Jiang 
56542d279f9SDave Jiang enum idxd_portal_prot {
56642d279f9SDave Jiang 	IDXD_PORTAL_UNLIMITED = 0,
56742d279f9SDave Jiang 	IDXD_PORTAL_LIMITED,
56842d279f9SDave Jiang };
56942d279f9SDave Jiang 
570eb15e715SDave Jiang enum idxd_interrupt_type {
571eb15e715SDave Jiang 	IDXD_IRQ_MSIX = 0,
572eb15e715SDave Jiang 	IDXD_IRQ_IMS,
573eb15e715SDave Jiang };
574eb15e715SDave Jiang 
idxd_get_wq_portal_offset(enum idxd_portal_prot prot)57542d279f9SDave Jiang static inline int idxd_get_wq_portal_offset(enum idxd_portal_prot prot)
57642d279f9SDave Jiang {
57742d279f9SDave Jiang 	return prot * 0x1000;
57842d279f9SDave Jiang }
57942d279f9SDave Jiang 
idxd_get_wq_portal_full_offset(int wq_id,enum idxd_portal_prot prot)58042d279f9SDave Jiang static inline int idxd_get_wq_portal_full_offset(int wq_id,
58142d279f9SDave Jiang 						 enum idxd_portal_prot prot)
58242d279f9SDave Jiang {
58342d279f9SDave Jiang 	return ((wq_id * 4) << PAGE_SHIFT) + idxd_get_wq_portal_offset(prot);
58442d279f9SDave Jiang }
58542d279f9SDave Jiang 
586a9c17152SDave Jiang #define IDXD_PORTAL_MASK	(PAGE_SIZE - 1)
587a9c17152SDave Jiang 
588a9c17152SDave Jiang /*
589a9c17152SDave Jiang  * Even though this function can be accessed by multiple threads, it is safe to use.
590a9c17152SDave Jiang  * At worst the address gets used more than once before it gets incremented. We don't
591a9c17152SDave Jiang  * hit a threshold until iops becomes many million times a second. So the occasional
592a9c17152SDave Jiang  * reuse of the same address is tolerable compare to using an atomic variable. This is
593a9c17152SDave Jiang  * safe on a system that has atomic load/store for 32bit integers. Given that this is an
594a9c17152SDave Jiang  * Intel iEP device, that should not be a problem.
595a9c17152SDave Jiang  */
idxd_wq_portal_addr(struct idxd_wq * wq)596a9c17152SDave Jiang static inline void __iomem *idxd_wq_portal_addr(struct idxd_wq *wq)
597a9c17152SDave Jiang {
598a9c17152SDave Jiang 	int ofs = wq->portal_offset;
599a9c17152SDave Jiang 
600a9c17152SDave Jiang 	wq->portal_offset = (ofs + sizeof(struct dsa_raw_desc)) & IDXD_PORTAL_MASK;
601a9c17152SDave Jiang 	return wq->portal + ofs;
602a9c17152SDave Jiang }
603a9c17152SDave Jiang 
idxd_wq_get(struct idxd_wq * wq)604c52ca478SDave Jiang static inline void idxd_wq_get(struct idxd_wq *wq)
605c52ca478SDave Jiang {
606c52ca478SDave Jiang 	wq->client_count++;
607c52ca478SDave Jiang }
608c52ca478SDave Jiang 
idxd_wq_put(struct idxd_wq * wq)609c52ca478SDave Jiang static inline void idxd_wq_put(struct idxd_wq *wq)
610c52ca478SDave Jiang {
611c52ca478SDave Jiang 	wq->client_count--;
612c52ca478SDave Jiang }
613c52ca478SDave Jiang 
idxd_wq_refcount(struct idxd_wq * wq)614c52ca478SDave Jiang static inline int idxd_wq_refcount(struct idxd_wq *wq)
615c52ca478SDave Jiang {
616c52ca478SDave Jiang 	return wq->client_count;
617c52ca478SDave Jiang };
618c52ca478SDave Jiang 
619e8dbd644SXiaochen Shen /*
620e8dbd644SXiaochen Shen  * Intel IAA does not support batch processing.
621e8dbd644SXiaochen Shen  * The max batch size of device, max batch size of wq and
622e8dbd644SXiaochen Shen  * max batch shift of wqcfg should be always 0 on IAA.
623e8dbd644SXiaochen Shen  */
idxd_set_max_batch_size(int idxd_type,struct idxd_device * idxd,u32 max_batch_size)624e8dbd644SXiaochen Shen static inline void idxd_set_max_batch_size(int idxd_type, struct idxd_device *idxd,
625e8dbd644SXiaochen Shen 					   u32 max_batch_size)
626e8dbd644SXiaochen Shen {
627e8dbd644SXiaochen Shen 	if (idxd_type == IDXD_TYPE_IAX)
628e8dbd644SXiaochen Shen 		idxd->max_batch_size = 0;
629e8dbd644SXiaochen Shen 	else
630e8dbd644SXiaochen Shen 		idxd->max_batch_size = max_batch_size;
631e8dbd644SXiaochen Shen }
632e8dbd644SXiaochen Shen 
idxd_wq_set_max_batch_size(int idxd_type,struct idxd_wq * wq,u32 max_batch_size)633e8dbd644SXiaochen Shen static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq,
634e8dbd644SXiaochen Shen 					      u32 max_batch_size)
635e8dbd644SXiaochen Shen {
636e8dbd644SXiaochen Shen 	if (idxd_type == IDXD_TYPE_IAX)
637e8dbd644SXiaochen Shen 		wq->max_batch_size = 0;
638e8dbd644SXiaochen Shen 	else
639e8dbd644SXiaochen Shen 		wq->max_batch_size = max_batch_size;
640e8dbd644SXiaochen Shen }
641e8dbd644SXiaochen Shen 
idxd_wqcfg_set_max_batch_shift(int idxd_type,union wqcfg * wqcfg,u32 max_batch_shift)642e8dbd644SXiaochen Shen static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg,
643e8dbd644SXiaochen Shen 						  u32 max_batch_shift)
644e8dbd644SXiaochen Shen {
645e8dbd644SXiaochen Shen 	if (idxd_type == IDXD_TYPE_IAX)
646e8dbd644SXiaochen Shen 		wqcfg->max_batch_shift = 0;
647e8dbd644SXiaochen Shen 	else
648e8dbd644SXiaochen Shen 		wqcfg->max_batch_shift = max_batch_shift;
649e8dbd644SXiaochen Shen }
650e8dbd644SXiaochen Shen 
6513ecfc913SDave Jiang int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv,
6523ecfc913SDave Jiang 					struct module *module, const char *mod_name);
6533ecfc913SDave Jiang #define idxd_driver_register(driver) \
6543ecfc913SDave Jiang 	__idxd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
6553ecfc913SDave Jiang 
6563ecfc913SDave Jiang void idxd_driver_unregister(struct idxd_device_driver *idxd_drv);
6573ecfc913SDave Jiang 
6586e7f3ee9SDave Jiang #define module_idxd_driver(__idxd_driver) \
6596e7f3ee9SDave Jiang 	module_driver(__idxd_driver, idxd_driver_register, idxd_driver_unregister)
6606e7f3ee9SDave Jiang 
661c52ca478SDave Jiang int idxd_register_bus_type(void);
662c52ca478SDave Jiang void idxd_unregister_bus_type(void);
66347c16ac2SDave Jiang int idxd_register_devices(struct idxd_device *idxd);
66447c16ac2SDave Jiang void idxd_unregister_devices(struct idxd_device *idxd);
6655b0c68c4SDave Jiang void idxd_wqs_quiesce(struct idxd_device *idxd);
666f6d442f7SDave Jiang bool idxd_queue_int_handle_resubmit(struct idxd_desc *desc);
66734ca0066SDave Jiang void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count);
668bfe1d560SDave Jiang 
669bfe1d560SDave Jiang /* device interrupt control */
670bfe1d560SDave Jiang irqreturn_t idxd_misc_thread(int vec, void *data);
671bfe1d560SDave Jiang irqreturn_t idxd_wq_thread(int irq, void *data);
672bfe1d560SDave Jiang void idxd_mask_error_interrupts(struct idxd_device *idxd);
673bfe1d560SDave Jiang void idxd_unmask_error_interrupts(struct idxd_device *idxd);
674bfe1d560SDave Jiang 
675bfe1d560SDave Jiang /* device control */
676bd42805bSDave Jiang int idxd_device_drv_probe(struct idxd_dev *idxd_dev);
677745e92a6SDave Jiang void idxd_device_drv_remove(struct idxd_dev *idxd_dev);
6781f2bb403SDave Jiang int drv_enable_wq(struct idxd_wq *wq);
67969e4f8beSDave Jiang void drv_disable_wq(struct idxd_wq *wq);
68089e3becdSDave Jiang int idxd_device_init_reset(struct idxd_device *idxd);
681bfe1d560SDave Jiang int idxd_device_enable(struct idxd_device *idxd);
682bfe1d560SDave Jiang int idxd_device_disable(struct idxd_device *idxd);
6830d5c10b4SDave Jiang void idxd_device_reset(struct idxd_device *idxd);
6840dcfe41eSDave Jiang void idxd_device_clear_state(struct idxd_device *idxd);
685bfe1d560SDave Jiang int idxd_device_config(struct idxd_device *idxd);
6868e50d392SDave Jiang void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid);
6878c66bbdcSDave Jiang int idxd_device_load_config(struct idxd_device *idxd);
688eb15e715SDave Jiang int idxd_device_request_int_handle(struct idxd_device *idxd, int idx, int *handle,
689eb15e715SDave Jiang 				   enum idxd_interrupt_type irq_type);
690eb15e715SDave Jiang int idxd_device_release_int_handle(struct idxd_device *idxd, int handle,
691eb15e715SDave Jiang 				   enum idxd_interrupt_type irq_type);
692bfe1d560SDave Jiang 
693bfe1d560SDave Jiang /* work queue control */
6945b0c68c4SDave Jiang void idxd_wqs_unmap_portal(struct idxd_device *idxd);
695bfe1d560SDave Jiang int idxd_wq_alloc_resources(struct idxd_wq *wq);
696bfe1d560SDave Jiang void idxd_wq_free_resources(struct idxd_wq *wq);
697bfe1d560SDave Jiang int idxd_wq_enable(struct idxd_wq *wq);
6980dcfe41eSDave Jiang int idxd_wq_disable(struct idxd_wq *wq, bool reset_config);
6990d5c10b4SDave Jiang void idxd_wq_drain(struct idxd_wq *wq);
700ea9aadc0SDave Jiang void idxd_wq_reset(struct idxd_wq *wq);
701c52ca478SDave Jiang int idxd_wq_map_portal(struct idxd_wq *wq);
702c52ca478SDave Jiang void idxd_wq_unmap_portal(struct idxd_wq *wq);
7038e50d392SDave Jiang int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid);
7048e50d392SDave Jiang int idxd_wq_disable_pasid(struct idxd_wq *wq);
705bd5970a0SDave Jiang void __idxd_wq_quiesce(struct idxd_wq *wq);
70693a40a6dSDave Jiang void idxd_wq_quiesce(struct idxd_wq *wq);
70793a40a6dSDave Jiang int idxd_wq_init_percpu_ref(struct idxd_wq *wq);
708403a2e23SDave Jiang void idxd_wq_free_irq(struct idxd_wq *wq);
709403a2e23SDave Jiang int idxd_wq_request_irq(struct idxd_wq *wq);
710bfe1d560SDave Jiang 
711d1dfe5b8SDave Jiang /* submission */
712d1dfe5b8SDave Jiang int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);
713d1dfe5b8SDave Jiang struct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype);
714d1dfe5b8SDave Jiang void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc);
7157930d855SDave Jiang int idxd_enqcmds(struct idxd_wq *wq, void __iomem *portal, const void *desc);
716d1dfe5b8SDave Jiang 
7178f47d1a5SDave Jiang /* dmaengine */
7188f47d1a5SDave Jiang int idxd_register_dma_device(struct idxd_device *idxd);
7198f47d1a5SDave Jiang void idxd_unregister_dma_device(struct idxd_device *idxd);
7208f47d1a5SDave Jiang void idxd_dma_complete_txd(struct idxd_desc *desc,
7215d78abb6SDave Jiang 			   enum idxd_complete_type comp_type, bool free_desc);
7228f47d1a5SDave Jiang 
72342d279f9SDave Jiang /* cdev */
72442d279f9SDave Jiang int idxd_cdev_register(void);
72542d279f9SDave Jiang void idxd_cdev_remove(void);
72642d279f9SDave Jiang int idxd_cdev_get_major(struct idxd_device *idxd);
72742d279f9SDave Jiang int idxd_wq_add_cdev(struct idxd_wq *wq);
72842d279f9SDave Jiang void idxd_wq_del_cdev(struct idxd_wq *wq);
729b022f597SFenghua Yu int idxd_copy_cr(struct idxd_wq *wq, ioasid_t pasid, unsigned long addr,
730b022f597SFenghua Yu 		 void *buf, int len);
731fecae134SDave Jiang void idxd_user_counter_increment(struct idxd_wq *wq, u32 pasid, int index);
73242d279f9SDave Jiang 
73381dd4d4dSTom Zanussi /* perfmon */
73481dd4d4dSTom Zanussi #if IS_ENABLED(CONFIG_INTEL_IDXD_PERFMON)
73581dd4d4dSTom Zanussi int perfmon_pmu_init(struct idxd_device *idxd);
73681dd4d4dSTom Zanussi void perfmon_pmu_remove(struct idxd_device *idxd);
73781dd4d4dSTom Zanussi void perfmon_counter_overflow(struct idxd_device *idxd);
73881dd4d4dSTom Zanussi void perfmon_init(void);
73981dd4d4dSTom Zanussi void perfmon_exit(void);
74081dd4d4dSTom Zanussi #else
perfmon_pmu_init(struct idxd_device * idxd)74181dd4d4dSTom Zanussi static inline int perfmon_pmu_init(struct idxd_device *idxd) { return 0; }
perfmon_pmu_remove(struct idxd_device * idxd)74281dd4d4dSTom Zanussi static inline void perfmon_pmu_remove(struct idxd_device *idxd) {}
perfmon_counter_overflow(struct idxd_device * idxd)74381dd4d4dSTom Zanussi static inline void perfmon_counter_overflow(struct idxd_device *idxd) {}
perfmon_init(void)74481dd4d4dSTom Zanussi static inline void perfmon_init(void) {}
perfmon_exit(void)74581dd4d4dSTom Zanussi static inline void perfmon_exit(void) {}
74681dd4d4dSTom Zanussi #endif
74781dd4d4dSTom Zanussi 
7485fbe6503SDave Jiang /* debugfs */
7495fbe6503SDave Jiang int idxd_device_init_debugfs(struct idxd_device *idxd);
7505fbe6503SDave Jiang void idxd_device_remove_debugfs(struct idxd_device *idxd);
7515fbe6503SDave Jiang int idxd_init_debugfs(void);
7525fbe6503SDave Jiang void idxd_remove_debugfs(void);
7535fbe6503SDave Jiang 
754bfe1d560SDave Jiang #endif
755