xref: /linux/drivers/dma/idxd/idxd.h (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
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>
16aa8d18beSTom Zanussi #include <linux/crypto.h>
17a9c17152SDave Jiang #include <uapi/linux/idxd.h>
18bfe1d560SDave Jiang #include "registers.h"
19bfe1d560SDave Jiang 
20bfe1d560SDave Jiang #define IDXD_DRIVER_VERSION	"1.00"
21bfe1d560SDave Jiang 
22bfe1d560SDave Jiang extern struct kmem_cache *idxd_desc_pool;
23ade8a86bSDave Jiang extern bool tc_override;
24bfe1d560SDave Jiang 
2539786285SDave Jiang struct idxd_wq;
26700af3a0SDave Jiang struct idxd_dev;
27700af3a0SDave Jiang 
28700af3a0SDave Jiang enum idxd_dev_type {
29700af3a0SDave Jiang 	IDXD_DEV_NONE = -1,
30700af3a0SDave Jiang 	IDXD_DEV_DSA = 0,
31700af3a0SDave Jiang 	IDXD_DEV_IAX,
32700af3a0SDave Jiang 	IDXD_DEV_WQ,
33700af3a0SDave Jiang 	IDXD_DEV_GROUP,
34700af3a0SDave Jiang 	IDXD_DEV_ENGINE,
35700af3a0SDave Jiang 	IDXD_DEV_CDEV,
36e6fd6d7eSDave Jiang 	IDXD_DEV_CDEV_FILE,
37700af3a0SDave Jiang 	IDXD_DEV_MAX_TYPE,
38700af3a0SDave Jiang };
39700af3a0SDave Jiang 
40700af3a0SDave Jiang struct idxd_dev {
41700af3a0SDave Jiang 	struct device conf_dev;
42700af3a0SDave Jiang 	enum idxd_dev_type type;
43700af3a0SDave Jiang };
4439786285SDave Jiang 
45bfe1d560SDave Jiang #define IDXD_REG_TIMEOUT	50
46bfe1d560SDave Jiang #define IDXD_DRAIN_TIMEOUT	5000
47bfe1d560SDave Jiang 
48bfe1d560SDave Jiang enum idxd_type {
49bfe1d560SDave Jiang 	IDXD_TYPE_UNKNOWN = -1,
50bfe1d560SDave Jiang 	IDXD_TYPE_DSA = 0,
51f25b4638SDave Jiang 	IDXD_TYPE_IAX,
52f25b4638SDave Jiang 	IDXD_TYPE_MAX,
53bfe1d560SDave Jiang };
54bfe1d560SDave Jiang 
55bfe1d560SDave Jiang #define IDXD_NAME_SIZE		128
5681dd4d4dSTom Zanussi #define IDXD_PMU_EVENT_MAX	64
57bfe1d560SDave Jiang 
587930d855SDave Jiang #define IDXD_ENQCMDS_RETRIES		32
597930d855SDave Jiang #define IDXD_ENQCMDS_MAX_RETRIES	64
607930d855SDave Jiang 
61aa8d18beSTom Zanussi enum idxd_complete_type {
62aa8d18beSTom Zanussi 	IDXD_COMPLETE_NORMAL = 0,
63aa8d18beSTom Zanussi 	IDXD_COMPLETE_ABORT,
64aa8d18beSTom Zanussi 	IDXD_COMPLETE_DEV_FAIL,
65aa8d18beSTom Zanussi };
66aa8d18beSTom Zanussi 
67aa8d18beSTom Zanussi struct idxd_desc;
68aa8d18beSTom Zanussi 
69bfe1d560SDave Jiang struct idxd_device_driver {
70da5a11d7SDave Jiang 	const char *name;
715fee6567SDave Jiang 	enum idxd_dev_type *type;
72fcc2281bSDave Jiang 	int (*probe)(struct idxd_dev *idxd_dev);
73fcc2281bSDave Jiang 	void (*remove)(struct idxd_dev *idxd_dev);
74aa8d18beSTom Zanussi 	void (*desc_complete)(struct idxd_desc *desc,
75aa8d18beSTom Zanussi 			      enum idxd_complete_type comp_type,
76aa8d18beSTom Zanussi 			      bool free_desc,
77aa8d18beSTom Zanussi 			      void *ctx, u32 *status);
78bfe1d560SDave Jiang 	struct device_driver drv;
79bfe1d560SDave Jiang };
80bfe1d560SDave Jiang 
81c05257b5SDave Jiang extern struct idxd_device_driver dsa_drv;
82034b3290SDave Jiang extern struct idxd_device_driver idxd_drv;
830cda4f69SDave Jiang extern struct idxd_device_driver idxd_dmaengine_drv;
84448c3de8SDave Jiang extern struct idxd_device_driver idxd_user_drv;
85c05257b5SDave Jiang 
868b67426eSDave Jiang #define INVALID_INT_HANDLE	-1
87bfe1d560SDave Jiang struct idxd_irq_entry {
88bfe1d560SDave Jiang 	int id;
895fc8e85fSDave Jiang 	int vector;
90bfe1d560SDave Jiang 	struct llist_head pending_llist;
91bfe1d560SDave Jiang 	struct list_head work_list;
92e4f4d8cdSDave Jiang 	/*
93e4f4d8cdSDave Jiang 	 * Lock to protect access between irq thread process descriptor
94e4f4d8cdSDave Jiang 	 * and irq thread processing error descriptor.
95e4f4d8cdSDave Jiang 	 */
96e4f4d8cdSDave Jiang 	spinlock_t list_lock;
978b67426eSDave Jiang 	int int_handle;
988b67426eSDave Jiang 	ioasid_t pasid;
99bfe1d560SDave Jiang };
100bfe1d560SDave Jiang 
101bfe1d560SDave Jiang struct idxd_group {
102700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
103bfe1d560SDave Jiang 	struct idxd_device *idxd;
104bfe1d560SDave Jiang 	struct grpcfg grpcfg;
105bfe1d560SDave Jiang 	int id;
106bfe1d560SDave Jiang 	int num_engines;
107bfe1d560SDave Jiang 	int num_wqs;
1087ed6f1b8SDave Jiang 	bool use_rdbuf_limit;
1097ed6f1b8SDave Jiang 	u8 rdbufs_allowed;
1107ed6f1b8SDave Jiang 	u8 rdbufs_reserved;
111bfe1d560SDave Jiang 	int tc_a;
112bfe1d560SDave Jiang 	int tc_b;
1131f273752SDave Jiang 	int desc_progress_limit;
1147ca68fa3SDave Jiang 	int batch_progress_limit;
115bfe1d560SDave Jiang };
116bfe1d560SDave Jiang 
11781dd4d4dSTom Zanussi struct idxd_pmu {
11881dd4d4dSTom Zanussi 	struct idxd_device *idxd;
11981dd4d4dSTom Zanussi 
12081dd4d4dSTom Zanussi 	struct perf_event *event_list[IDXD_PMU_EVENT_MAX];
12181dd4d4dSTom Zanussi 	int n_events;
12281dd4d4dSTom Zanussi 
12381dd4d4dSTom Zanussi 	DECLARE_BITMAP(used_mask, IDXD_PMU_EVENT_MAX);
12481dd4d4dSTom Zanussi 
12581dd4d4dSTom Zanussi 	struct pmu pmu;
12681dd4d4dSTom Zanussi 	char name[IDXD_NAME_SIZE];
12781dd4d4dSTom Zanussi 
12881dd4d4dSTom Zanussi 	int n_counters;
12981dd4d4dSTom Zanussi 	int counter_width;
13081dd4d4dSTom Zanussi 	int n_event_categories;
13181dd4d4dSTom Zanussi 
13281dd4d4dSTom Zanussi 	bool per_counter_caps_supported;
13381dd4d4dSTom Zanussi 	unsigned long supported_event_categories;
13481dd4d4dSTom Zanussi 
13581dd4d4dSTom Zanussi 	unsigned long supported_filters;
13681dd4d4dSTom Zanussi 	int n_filters;
13781dd4d4dSTom Zanussi };
13881dd4d4dSTom Zanussi 
139bfe1d560SDave Jiang #define IDXD_MAX_PRIORITY	0xf
140bfe1d560SDave Jiang 
141fecae134SDave Jiang enum {
142fecae134SDave Jiang 	COUNTER_FAULTS = 0,
143fecae134SDave Jiang 	COUNTER_FAULT_FAILS,
144fecae134SDave Jiang 	COUNTER_MAX
145fecae134SDave Jiang };
146fecae134SDave Jiang 
147bfe1d560SDave Jiang enum idxd_wq_state {
148bfe1d560SDave Jiang 	IDXD_WQ_DISABLED = 0,
149bfe1d560SDave Jiang 	IDXD_WQ_ENABLED,
150bfe1d560SDave Jiang };
151bfe1d560SDave Jiang 
152bfe1d560SDave Jiang enum idxd_wq_flag {
153bfe1d560SDave Jiang 	WQ_FLAG_DEDICATED = 0,
1548e50d392SDave Jiang 	WQ_FLAG_BLOCK_ON_FAULT,
15522bd0df8SDave Jiang 	WQ_FLAG_ATS_DISABLE,
156f2dc3271SDave Jiang 	WQ_FLAG_PRS_DISABLE,
157bfe1d560SDave Jiang };
158bfe1d560SDave Jiang 
159bfe1d560SDave Jiang enum idxd_wq_type {
160bfe1d560SDave Jiang 	IDXD_WQT_NONE = 0,
161bfe1d560SDave Jiang 	IDXD_WQT_KERNEL,
16242d279f9SDave Jiang 	IDXD_WQT_USER,
16342d279f9SDave Jiang };
16442d279f9SDave Jiang 
16542d279f9SDave Jiang struct idxd_cdev {
16604922b74SDave Jiang 	struct idxd_wq *wq;
16742d279f9SDave Jiang 	struct cdev cdev;
168700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
16942d279f9SDave Jiang 	int minor;
170bfe1d560SDave Jiang };
171bfe1d560SDave Jiang 
1727af1e0acSDave Jiang #define DRIVER_NAME_SIZE		128
1737af1e0acSDave Jiang 
174bfe1d560SDave Jiang #define IDXD_ALLOCATED_BATCH_SIZE	128U
175bfe1d560SDave Jiang #define WQ_NAME_SIZE   1024
176bfe1d560SDave Jiang #define WQ_TYPE_SIZE   10
177bfe1d560SDave Jiang 
17892452a72SDave Jiang #define WQ_DEFAULT_QUEUE_DEPTH		16
17992452a72SDave Jiang #define WQ_DEFAULT_MAX_XFER		SZ_2M
18092452a72SDave Jiang #define WQ_DEFAULT_MAX_BATCH		32
18192452a72SDave Jiang 
182d1dfe5b8SDave Jiang enum idxd_op_type {
183d1dfe5b8SDave Jiang 	IDXD_OP_BLOCK = 0,
184d1dfe5b8SDave Jiang 	IDXD_OP_NONBLOCK = 1,
185d1dfe5b8SDave Jiang };
186d1dfe5b8SDave Jiang 
18739786285SDave Jiang struct idxd_dma_chan {
18839786285SDave Jiang 	struct dma_chan chan;
18939786285SDave Jiang 	struct idxd_wq *wq;
19039786285SDave Jiang };
19139786285SDave Jiang 
192bfe1d560SDave Jiang struct idxd_wq {
1938e50d392SDave Jiang 	void __iomem *portal;
194a9c17152SDave Jiang 	u32 portal_offset;
1957930d855SDave Jiang 	unsigned int enqcmds_retries;
19693a40a6dSDave Jiang 	struct percpu_ref wq_active;
19793a40a6dSDave Jiang 	struct completion wq_dead;
19856fc39f5SDave Jiang 	struct completion wq_resurrect;
199700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
20004922b74SDave Jiang 	struct idxd_cdev *idxd_cdev;
20104922b74SDave Jiang 	struct wait_queue_head err_queue;
2022f30decdSDave Jiang 	struct workqueue_struct *wq;
203bfe1d560SDave Jiang 	struct idxd_device *idxd;
204bfe1d560SDave Jiang 	int id;
205ec0d6423SDave Jiang 	struct idxd_irq_entry ie;
206bfe1d560SDave Jiang 	enum idxd_wq_type type;
207bfe1d560SDave Jiang 	struct idxd_group *group;
208bfe1d560SDave Jiang 	int client_count;
209bfe1d560SDave Jiang 	struct mutex wq_lock;	/* mutex for workqueue */
210bfe1d560SDave Jiang 	u32 size;
211bfe1d560SDave Jiang 	u32 threshold;
212bfe1d560SDave Jiang 	u32 priority;
213bfe1d560SDave Jiang 	enum idxd_wq_state state;
214bfe1d560SDave Jiang 	unsigned long flags;
215d98793b5SDave Jiang 	union wqcfg *wqcfg;
216b0325aefSDave Jiang 	unsigned long *opcap_bmap;
217b0325aefSDave Jiang 
218bfe1d560SDave Jiang 	struct dsa_hw_desc **hw_descs;
219bfe1d560SDave Jiang 	int num_descs;
220f25b4638SDave Jiang 	union {
221bfe1d560SDave Jiang 		struct dsa_completion_record *compls;
222f25b4638SDave Jiang 		struct iax_completion_record *iax_compls;
223f25b4638SDave Jiang 	};
224bfe1d560SDave Jiang 	dma_addr_t compls_addr;
225bfe1d560SDave Jiang 	int compls_size;
226bfe1d560SDave Jiang 	struct idxd_desc **descs;
2270705107fSDave Jiang 	struct sbitmap_queue sbq;
22839786285SDave Jiang 	struct idxd_dma_chan *idxd_chan;
229bfe1d560SDave Jiang 	char name[WQ_NAME_SIZE + 1];
230d7aad555SDave Jiang 	u64 max_xfer_bytes;
231e7184b15SDave Jiang 	u32 max_batch_size;
232b022f597SFenghua Yu 
233b022f597SFenghua Yu 	/* Lock to protect upasid_xa access. */
234b022f597SFenghua Yu 	struct mutex uc_lock;
235b022f597SFenghua Yu 	struct xarray upasid_xa;
2367af1e0acSDave Jiang 
2377af1e0acSDave Jiang 	char driver_name[DRIVER_NAME_SIZE + 1];
238bfe1d560SDave Jiang };
239bfe1d560SDave Jiang 
240bfe1d560SDave Jiang struct idxd_engine {
241700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
242bfe1d560SDave Jiang 	int id;
243bfe1d560SDave Jiang 	struct idxd_group *group;
244bfe1d560SDave Jiang 	struct idxd_device *idxd;
245bfe1d560SDave Jiang };
246bfe1d560SDave Jiang 
247bfe1d560SDave Jiang /* shadow registers */
248bfe1d560SDave Jiang struct idxd_hw {
249bfe1d560SDave Jiang 	u32 version;
250bfe1d560SDave Jiang 	union gen_cap_reg gen_cap;
251bfe1d560SDave Jiang 	union wq_cap_reg wq_cap;
252bfe1d560SDave Jiang 	union group_cap_reg group_cap;
253bfe1d560SDave Jiang 	union engine_cap_reg engine_cap;
254bfe1d560SDave Jiang 	struct opcap opcap;
255eb15e715SDave Jiang 	u32 cmd_cap;
2569f0d99b3SDave Jiang 	union iaa_cap_reg iaa_cap;
257bfe1d560SDave Jiang };
258bfe1d560SDave Jiang 
259bfe1d560SDave Jiang enum idxd_device_state {
260bfe1d560SDave Jiang 	IDXD_DEV_HALTED = -1,
261bfe1d560SDave Jiang 	IDXD_DEV_DISABLED = 0,
262bfe1d560SDave Jiang 	IDXD_DEV_ENABLED,
263bfe1d560SDave Jiang };
264bfe1d560SDave Jiang 
265bfe1d560SDave Jiang enum idxd_device_flag {
266bfe1d560SDave Jiang 	IDXD_FLAG_CONFIGURABLE = 0,
2670d5c10b4SDave Jiang 	IDXD_FLAG_CMD_RUNNING,
2688e50d392SDave Jiang 	IDXD_FLAG_PASID_ENABLED,
26942a1b738SDave Jiang 	IDXD_FLAG_USER_PASID_ENABLED,
270bfe1d560SDave Jiang };
271bfe1d560SDave Jiang 
27239786285SDave Jiang struct idxd_dma_dev {
27339786285SDave Jiang 	struct idxd_device *idxd;
27439786285SDave Jiang 	struct dma_device dma;
27539786285SDave Jiang };
27639786285SDave Jiang 
277979f6dedSTom Zanussi typedef int (*load_device_defaults_fn_t) (struct idxd_device *idxd);
278979f6dedSTom Zanussi 
279435b512dSDave Jiang struct idxd_driver_data {
280435b512dSDave Jiang 	const char *name_prefix;
281bfe1d560SDave Jiang 	enum idxd_type type;
2821e0a2852SRicardo B. Marliere 	const struct device_type *dev_type;
283435b512dSDave Jiang 	int compl_size;
284435b512dSDave Jiang 	int align;
285c40bd7d9SDave Jiang 	int evl_cr_off;
2862442b747SDave Jiang 	int cr_status_off;
2872442b747SDave Jiang 	int cr_result_off;
288*e11452ebSArjan van de Ven 	bool user_submission_safe;
289979f6dedSTom Zanussi 	load_device_defaults_fn_t load_device_defaults;
290435b512dSDave Jiang };
291435b512dSDave Jiang 
2921649091fSDave Jiang struct idxd_evl {
293244da66cSDave Jiang 	/* Lock to protect event log access. */
294d5638de8SRex Zhang 	struct mutex lock;
295244da66cSDave Jiang 	void *log;
296244da66cSDave Jiang 	dma_addr_t dma;
297244da66cSDave Jiang 	/* Total size of event log = number of entries * entry size. */
298244da66cSDave Jiang 	unsigned int log_size;
299244da66cSDave Jiang 	/* The number of entries in the event log. */
3001649091fSDave Jiang 	u16 size;
301c40bd7d9SDave Jiang 	unsigned long *bmap;
3022442b747SDave Jiang 	bool batch_fail[IDXD_MAX_BATCH_IDENT];
3031649091fSDave Jiang };
3041649091fSDave Jiang 
305c2f156bfSDave Jiang struct idxd_evl_fault {
306c2f156bfSDave Jiang 	struct work_struct work;
307c2f156bfSDave Jiang 	struct idxd_wq *wq;
308c2f156bfSDave Jiang 	u8 status;
309c2f156bfSDave Jiang 
310c2f156bfSDave Jiang 	/* make this last member always */
311c2f156bfSDave Jiang 	struct __evl_entry entry[];
312435b512dSDave Jiang };
313435b512dSDave Jiang 
314435b512dSDave Jiang struct idxd_device {
315700af3a0SDave Jiang 	struct idxd_dev idxd_dev;
316435b512dSDave Jiang 	struct idxd_driver_data *data;
317bfe1d560SDave Jiang 	struct list_head list;
318bfe1d560SDave Jiang 	struct idxd_hw hw;
319bfe1d560SDave Jiang 	enum idxd_device_state state;
320bfe1d560SDave Jiang 	unsigned long flags;
321bfe1d560SDave Jiang 	int id;
32242d279f9SDave Jiang 	int major;
323125d1037SDave Jiang 	u32 cmd_status;
324ec0d6423SDave Jiang 	struct idxd_irq_entry ie;	/* misc irq, msix 0 */
325bfe1d560SDave Jiang 
326bfe1d560SDave Jiang 	struct pci_dev *pdev;
327bfe1d560SDave Jiang 	void __iomem *reg_base;
328bfe1d560SDave Jiang 
329bfe1d560SDave Jiang 	spinlock_t dev_lock;	/* spinlock for device */
33053b2ee7fSDave Jiang 	spinlock_t cmd_lock;	/* spinlock for device commands */
3310d5c10b4SDave Jiang 	struct completion *cmd_done;
332defe49f9SDave Jiang 	struct idxd_group **groups;
3337c5dd23eSDave Jiang 	struct idxd_wq **wqs;
33475b91130SDave Jiang 	struct idxd_engine **engines;
335bfe1d560SDave Jiang 
3368e50d392SDave Jiang 	struct iommu_sva *sva;
3378e50d392SDave Jiang 	unsigned int pasid;
3388e50d392SDave Jiang 
339bfe1d560SDave Jiang 	int num_groups;
3408b67426eSDave Jiang 	int irq_cnt;
3418b67426eSDave Jiang 	bool request_int_handles;
342bfe1d560SDave Jiang 
343bfe1d560SDave Jiang 	u32 msix_perm_offset;
344bfe1d560SDave Jiang 	u32 wqcfg_offset;
345bfe1d560SDave Jiang 	u32 grpcfg_offset;
346bfe1d560SDave Jiang 	u32 perfmon_offset;
347bfe1d560SDave Jiang 
348bfe1d560SDave Jiang 	u64 max_xfer_bytes;
349bfe1d560SDave Jiang 	u32 max_batch_size;
350bfe1d560SDave Jiang 	int max_groups;
351bfe1d560SDave Jiang 	int max_engines;
3527ed6f1b8SDave Jiang 	int max_rdbufs;
353bfe1d560SDave Jiang 	int max_wqs;
354bfe1d560SDave Jiang 	int max_wq_size;
3557ed6f1b8SDave Jiang 	int rdbuf_limit;
3567ed6f1b8SDave Jiang 	int nr_rdbufs;		/* non-reserved read buffers */
357d98793b5SDave Jiang 	unsigned int wqcfg_size;
358de5819b9SJerry Snitselaar 	unsigned long *wq_enable_map;
359bfe1d560SDave Jiang 
360bfe1d560SDave Jiang 	union sw_err_reg sw_err;
3610d5c10b4SDave Jiang 	wait_queue_head_t cmd_waitq;
3628f47d1a5SDave Jiang 
36339786285SDave Jiang 	struct idxd_dma_dev *idxd_dma;
3640d5c10b4SDave Jiang 	struct workqueue_struct *wq;
3650d5c10b4SDave Jiang 	struct work_struct work;
366eb15e715SDave Jiang 
36781dd4d4dSTom Zanussi 	struct idxd_pmu *idxd_pmu;
368a8563a33SDave Jiang 
369a8563a33SDave Jiang 	unsigned long *opcap_bmap;
3701649091fSDave Jiang 	struct idxd_evl *evl;
371c2f156bfSDave Jiang 	struct kmem_cache *evl_cache;
3725fbe6503SDave Jiang 
3735fbe6503SDave Jiang 	struct dentry *dbgfs_dir;
3745fbe6503SDave Jiang 	struct dentry *dbgfs_evl_file;
375*e11452ebSArjan van de Ven 
376*e11452ebSArjan van de Ven 	bool user_submission_safe;
377bfe1d560SDave Jiang };
378bfe1d560SDave Jiang 
evl_ent_size(struct idxd_device * idxd)379244da66cSDave Jiang static inline unsigned int evl_ent_size(struct idxd_device *idxd)
380244da66cSDave Jiang {
381244da66cSDave Jiang 	return idxd->hw.gen_cap.evl_support ?
382244da66cSDave Jiang 	       (32 * (1 << idxd->hw.gen_cap.evl_support)) : 0;
383244da66cSDave Jiang }
384244da66cSDave Jiang 
evl_size(struct idxd_device * idxd)385244da66cSDave Jiang static inline unsigned int evl_size(struct idxd_device *idxd)
386244da66cSDave Jiang {
387244da66cSDave Jiang 	return idxd->evl->size * evl_ent_size(idxd);
388244da66cSDave Jiang }
389244da66cSDave Jiang 
390aa8d18beSTom Zanussi struct crypto_ctx {
391aa8d18beSTom Zanussi 	struct acomp_req *req;
392aa8d18beSTom Zanussi 	struct crypto_tfm *tfm;
393aa8d18beSTom Zanussi 	dma_addr_t src_addr;
394aa8d18beSTom Zanussi 	dma_addr_t dst_addr;
395aa8d18beSTom Zanussi 	bool compress;
396aa8d18beSTom Zanussi };
397aa8d18beSTom Zanussi 
398bfe1d560SDave Jiang /* IDXD software descriptor */
399bfe1d560SDave Jiang struct idxd_desc {
400f25b4638SDave Jiang 	union {
401bfe1d560SDave Jiang 		struct dsa_hw_desc *hw;
402f25b4638SDave Jiang 		struct iax_hw_desc *iax_hw;
403f25b4638SDave Jiang 	};
404bfe1d560SDave Jiang 	dma_addr_t desc_dma;
405f25b4638SDave Jiang 	union {
406bfe1d560SDave Jiang 		struct dsa_completion_record *completion;
407f25b4638SDave Jiang 		struct iax_completion_record *iax_completion;
408f25b4638SDave Jiang 	};
409bfe1d560SDave Jiang 	dma_addr_t compl_dma;
410aa8d18beSTom Zanussi 	union {
4118f47d1a5SDave Jiang 		struct dma_async_tx_descriptor txd;
412aa8d18beSTom Zanussi 		struct crypto_ctx crypto;
413aa8d18beSTom Zanussi 	};
414bfe1d560SDave Jiang 	struct llist_node llnode;
415bfe1d560SDave Jiang 	struct list_head list;
416bfe1d560SDave Jiang 	int id;
4170705107fSDave Jiang 	int cpu;
418bfe1d560SDave Jiang 	struct idxd_wq *wq;
419bfe1d560SDave Jiang };
420bfe1d560SDave Jiang 
4216b4b87f2SDave Jiang /*
4226b4b87f2SDave Jiang  * This is software defined error for the completion status. We overload the error code
4236b4b87f2SDave Jiang  * that will never appear in completion status and only SWERR register.
4246b4b87f2SDave Jiang  */
4256b4b87f2SDave Jiang enum idxd_completion_status {
4266b4b87f2SDave Jiang 	IDXD_COMP_DESC_ABORT = 0xff,
4276b4b87f2SDave Jiang };
4286b4b87f2SDave Jiang 
429700af3a0SDave Jiang #define idxd_confdev(idxd) &idxd->idxd_dev.conf_dev
430700af3a0SDave Jiang #define wq_confdev(wq) &wq->idxd_dev.conf_dev
431700af3a0SDave Jiang #define engine_confdev(engine) &engine->idxd_dev.conf_dev
432700af3a0SDave Jiang #define group_confdev(group) &group->idxd_dev.conf_dev
433700af3a0SDave Jiang #define cdev_dev(cdev) &cdev->idxd_dev.conf_dev
434e6fd6d7eSDave Jiang #define user_ctx_dev(ctx) (&(ctx)->idxd_dev.conf_dev)
435700af3a0SDave Jiang 
436700af3a0SDave Jiang #define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev)
437fcc2281bSDave Jiang #define idxd_dev_to_idxd(idxd_dev) container_of(idxd_dev, struct idxd_device, idxd_dev)
438fcc2281bSDave Jiang #define idxd_dev_to_wq(idxd_dev) container_of(idxd_dev, struct idxd_wq, idxd_dev)
439700af3a0SDave Jiang 
wq_to_idxd_drv(struct idxd_wq * wq)440aa8d18beSTom Zanussi static inline struct idxd_device_driver *wq_to_idxd_drv(struct idxd_wq *wq)
441aa8d18beSTom Zanussi {
442aa8d18beSTom Zanussi 	struct device *dev = wq_confdev(wq);
443aa8d18beSTom Zanussi 	struct idxd_device_driver *idxd_drv =
444aa8d18beSTom Zanussi 		container_of(dev->driver, struct idxd_device_driver, drv);
445aa8d18beSTom Zanussi 
446aa8d18beSTom Zanussi 	return idxd_drv;
447aa8d18beSTom Zanussi }
448aa8d18beSTom Zanussi 
confdev_to_idxd(struct device * dev)449700af3a0SDave Jiang static inline struct idxd_device *confdev_to_idxd(struct device *dev)
450700af3a0SDave Jiang {
451700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
452700af3a0SDave Jiang 
453fcc2281bSDave Jiang 	return idxd_dev_to_idxd(idxd_dev);
454700af3a0SDave Jiang }
455700af3a0SDave Jiang 
confdev_to_wq(struct device * dev)456700af3a0SDave Jiang static inline struct idxd_wq *confdev_to_wq(struct device *dev)
457700af3a0SDave Jiang {
458700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
459700af3a0SDave Jiang 
460fcc2281bSDave Jiang 	return idxd_dev_to_wq(idxd_dev);
461700af3a0SDave Jiang }
462700af3a0SDave Jiang 
confdev_to_engine(struct device * dev)463700af3a0SDave Jiang static inline struct idxd_engine *confdev_to_engine(struct device *dev)
464700af3a0SDave Jiang {
465700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
466700af3a0SDave Jiang 
467700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_engine, idxd_dev);
468700af3a0SDave Jiang }
469700af3a0SDave Jiang 
confdev_to_group(struct device * dev)470700af3a0SDave Jiang static inline struct idxd_group *confdev_to_group(struct device *dev)
471700af3a0SDave Jiang {
472700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
473700af3a0SDave Jiang 
474700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_group, idxd_dev);
475700af3a0SDave Jiang }
476700af3a0SDave Jiang 
dev_to_cdev(struct device * dev)477700af3a0SDave Jiang static inline struct idxd_cdev *dev_to_cdev(struct device *dev)
478700af3a0SDave Jiang {
479700af3a0SDave Jiang 	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
480700af3a0SDave Jiang 
481700af3a0SDave Jiang 	return container_of(idxd_dev, struct idxd_cdev, idxd_dev);
482700af3a0SDave Jiang }
483700af3a0SDave Jiang 
idxd_dev_set_type(struct idxd_dev * idev,int type)484700af3a0SDave Jiang static inline void idxd_dev_set_type(struct idxd_dev *idev, int type)
485700af3a0SDave Jiang {
486700af3a0SDave Jiang 	if (type >= IDXD_DEV_MAX_TYPE) {
487700af3a0SDave Jiang 		idev->type = IDXD_DEV_NONE;
488700af3a0SDave Jiang 		return;
489700af3a0SDave Jiang 	}
490700af3a0SDave Jiang 
491700af3a0SDave Jiang 	idev->type = type;
492700af3a0SDave Jiang }
493bfe1d560SDave Jiang 
idxd_get_ie(struct idxd_device * idxd,int idx)494ec0d6423SDave Jiang static inline struct idxd_irq_entry *idxd_get_ie(struct idxd_device *idxd, int idx)
495ec0d6423SDave Jiang {
496ec0d6423SDave Jiang 	return (idx == 0) ? &idxd->ie : &idxd->wqs[idx - 1]->ie;
497ec0d6423SDave Jiang }
498ec0d6423SDave Jiang 
ie_to_wq(struct idxd_irq_entry * ie)499ec0d6423SDave Jiang static inline struct idxd_wq *ie_to_wq(struct idxd_irq_entry *ie)
500ec0d6423SDave Jiang {
501ec0d6423SDave Jiang 	return container_of(ie, struct idxd_wq, ie);
502ec0d6423SDave Jiang }
503ec0d6423SDave Jiang 
ie_to_idxd(struct idxd_irq_entry * ie)504ec0d6423SDave Jiang static inline struct idxd_device *ie_to_idxd(struct idxd_irq_entry *ie)
505ec0d6423SDave Jiang {
506ec0d6423SDave Jiang 	return container_of(ie, struct idxd_device, ie);
507ec0d6423SDave Jiang }
508ec0d6423SDave Jiang 
idxd_set_user_intr(struct idxd_device * idxd,bool enable)509f5ccf55eSJacob Pan static inline void idxd_set_user_intr(struct idxd_device *idxd, bool enable)
510f5ccf55eSJacob Pan {
511f5ccf55eSJacob Pan 	union gencfg_reg reg;
512f5ccf55eSJacob Pan 
513f5ccf55eSJacob Pan 	reg.bits = ioread32(idxd->reg_base + IDXD_GENCFG_OFFSET);
514f5ccf55eSJacob Pan 	reg.user_int_en = enable;
515f5ccf55eSJacob Pan 	iowrite32(reg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET);
516f5ccf55eSJacob Pan }
517f5ccf55eSJacob Pan 
518cf497f35SRicardo B. Marliere extern const struct bus_type dsa_bus_type;
51942d279f9SDave Jiang 
5208e50d392SDave Jiang extern bool support_enqcmd;
5214b73e4ebSDave Jiang extern struct ida idxd_ida;
5221e0a2852SRicardo B. Marliere extern const struct device_type dsa_device_type;
5231e0a2852SRicardo B. Marliere extern const struct device_type iax_device_type;
5241e0a2852SRicardo B. Marliere extern const struct device_type idxd_wq_device_type;
5251e0a2852SRicardo B. Marliere extern const struct device_type idxd_engine_device_type;
5261e0a2852SRicardo B. Marliere extern const struct device_type idxd_group_device_type;
52747c16ac2SDave Jiang 
is_dsa_dev(struct idxd_dev * idxd_dev)528fcc2281bSDave Jiang static inline bool is_dsa_dev(struct idxd_dev *idxd_dev)
52947c16ac2SDave Jiang {
530fcc2281bSDave Jiang 	return idxd_dev->type == IDXD_DEV_DSA;
53147c16ac2SDave Jiang }
53247c16ac2SDave Jiang 
is_iax_dev(struct idxd_dev * idxd_dev)533fcc2281bSDave Jiang static inline bool is_iax_dev(struct idxd_dev *idxd_dev)
53447c16ac2SDave Jiang {
535fcc2281bSDave Jiang 	return idxd_dev->type == IDXD_DEV_IAX;
53647c16ac2SDave Jiang }
53747c16ac2SDave Jiang 
is_idxd_dev(struct idxd_dev * idxd_dev)538fcc2281bSDave Jiang static inline bool is_idxd_dev(struct idxd_dev *idxd_dev)
53947c16ac2SDave Jiang {
540fcc2281bSDave Jiang 	return is_dsa_dev(idxd_dev) || is_iax_dev(idxd_dev);
54147c16ac2SDave Jiang }
5428e50d392SDave Jiang 
is_idxd_wq_dev(struct idxd_dev * idxd_dev)543fcc2281bSDave Jiang static inline bool is_idxd_wq_dev(struct idxd_dev *idxd_dev)
5447c5dd23eSDave Jiang {
545fcc2281bSDave Jiang 	return idxd_dev->type == IDXD_DEV_WQ;
5467c5dd23eSDave Jiang }
5477c5dd23eSDave Jiang 
is_idxd_wq_dmaengine(struct idxd_wq * wq)5487c5dd23eSDave Jiang static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq)
5497c5dd23eSDave Jiang {
5507c5dd23eSDave Jiang 	if (wq->type == IDXD_WQT_KERNEL && strcmp(wq->name, "dmaengine") == 0)
5517c5dd23eSDave Jiang 		return true;
5527c5dd23eSDave Jiang 	return false;
5537c5dd23eSDave Jiang }
5547c5dd23eSDave Jiang 
is_idxd_wq_user(struct idxd_wq * wq)5556e7f3ee9SDave Jiang static inline bool is_idxd_wq_user(struct idxd_wq *wq)
5567c5dd23eSDave Jiang {
5577c5dd23eSDave Jiang 	return wq->type == IDXD_WQT_USER;
5587c5dd23eSDave Jiang }
5597c5dd23eSDave Jiang 
is_idxd_wq_kernel(struct idxd_wq * wq)5606e7f3ee9SDave Jiang static inline bool is_idxd_wq_kernel(struct idxd_wq *wq)
5616e7f3ee9SDave Jiang {
5626e7f3ee9SDave Jiang 	return wq->type == IDXD_WQT_KERNEL;
5636e7f3ee9SDave Jiang }
5646e7f3ee9SDave Jiang 
wq_dedicated(struct idxd_wq * wq)565bfe1d560SDave Jiang static inline bool wq_dedicated(struct idxd_wq *wq)
566bfe1d560SDave Jiang {
567bfe1d560SDave Jiang 	return test_bit(WQ_FLAG_DEDICATED, &wq->flags);
568bfe1d560SDave Jiang }
569bfe1d560SDave Jiang 
wq_shared(struct idxd_wq * wq)5708e50d392SDave Jiang static inline bool wq_shared(struct idxd_wq *wq)
5718e50d392SDave Jiang {
5728e50d392SDave Jiang 	return !test_bit(WQ_FLAG_DEDICATED, &wq->flags);
5738e50d392SDave Jiang }
5748e50d392SDave Jiang 
device_pasid_enabled(struct idxd_device * idxd)5758e50d392SDave Jiang static inline bool device_pasid_enabled(struct idxd_device *idxd)
5768e50d392SDave Jiang {
5778e50d392SDave Jiang 	return test_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags);
5788e50d392SDave Jiang }
5798e50d392SDave Jiang 
device_user_pasid_enabled(struct idxd_device * idxd)58042a1b738SDave Jiang static inline bool device_user_pasid_enabled(struct idxd_device *idxd)
5818e50d392SDave Jiang {
58242a1b738SDave Jiang 	return test_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags);
58342a1b738SDave Jiang }
58442a1b738SDave Jiang 
wq_pasid_enabled(struct idxd_wq * wq)58542a1b738SDave Jiang static inline bool wq_pasid_enabled(struct idxd_wq *wq)
58642a1b738SDave Jiang {
58742a1b738SDave Jiang 	return (is_idxd_wq_kernel(wq) && device_pasid_enabled(wq->idxd)) ||
58842a1b738SDave Jiang 	       (is_idxd_wq_user(wq) && device_user_pasid_enabled(wq->idxd));
58942a1b738SDave Jiang }
59042a1b738SDave Jiang 
wq_shared_supported(struct idxd_wq * wq)59142a1b738SDave Jiang static inline bool wq_shared_supported(struct idxd_wq *wq)
59242a1b738SDave Jiang {
59342a1b738SDave Jiang 	return (support_enqcmd && wq_pasid_enabled(wq));
5948e50d392SDave Jiang }
5958e50d392SDave Jiang 
59642d279f9SDave Jiang enum idxd_portal_prot {
59742d279f9SDave Jiang 	IDXD_PORTAL_UNLIMITED = 0,
59842d279f9SDave Jiang 	IDXD_PORTAL_LIMITED,
59942d279f9SDave Jiang };
60042d279f9SDave Jiang 
601eb15e715SDave Jiang enum idxd_interrupt_type {
602eb15e715SDave Jiang 	IDXD_IRQ_MSIX = 0,
603eb15e715SDave Jiang 	IDXD_IRQ_IMS,
604eb15e715SDave Jiang };
605eb15e715SDave Jiang 
idxd_get_wq_portal_offset(enum idxd_portal_prot prot)60642d279f9SDave Jiang static inline int idxd_get_wq_portal_offset(enum idxd_portal_prot prot)
60742d279f9SDave Jiang {
60842d279f9SDave Jiang 	return prot * 0x1000;
60942d279f9SDave Jiang }
61042d279f9SDave Jiang 
idxd_get_wq_portal_full_offset(int wq_id,enum idxd_portal_prot prot)61142d279f9SDave Jiang static inline int idxd_get_wq_portal_full_offset(int wq_id,
61242d279f9SDave Jiang 						 enum idxd_portal_prot prot)
61342d279f9SDave Jiang {
61442d279f9SDave Jiang 	return ((wq_id * 4) << PAGE_SHIFT) + idxd_get_wq_portal_offset(prot);
61542d279f9SDave Jiang }
61642d279f9SDave Jiang 
617a9c17152SDave Jiang #define IDXD_PORTAL_MASK	(PAGE_SIZE - 1)
618a9c17152SDave Jiang 
619a9c17152SDave Jiang /*
620a9c17152SDave Jiang  * Even though this function can be accessed by multiple threads, it is safe to use.
621a9c17152SDave Jiang  * At worst the address gets used more than once before it gets incremented. We don't
622a9c17152SDave Jiang  * hit a threshold until iops becomes many million times a second. So the occasional
623a9c17152SDave Jiang  * reuse of the same address is tolerable compare to using an atomic variable. This is
624a9c17152SDave Jiang  * safe on a system that has atomic load/store for 32bit integers. Given that this is an
625a9c17152SDave Jiang  * Intel iEP device, that should not be a problem.
626a9c17152SDave Jiang  */
idxd_wq_portal_addr(struct idxd_wq * wq)627a9c17152SDave Jiang static inline void __iomem *idxd_wq_portal_addr(struct idxd_wq *wq)
628a9c17152SDave Jiang {
629a9c17152SDave Jiang 	int ofs = wq->portal_offset;
630a9c17152SDave Jiang 
631a9c17152SDave Jiang 	wq->portal_offset = (ofs + sizeof(struct dsa_raw_desc)) & IDXD_PORTAL_MASK;
632a9c17152SDave Jiang 	return wq->portal + ofs;
633a9c17152SDave Jiang }
634a9c17152SDave Jiang 
idxd_wq_get(struct idxd_wq * wq)635c52ca478SDave Jiang static inline void idxd_wq_get(struct idxd_wq *wq)
636c52ca478SDave Jiang {
637c52ca478SDave Jiang 	wq->client_count++;
638c52ca478SDave Jiang }
639c52ca478SDave Jiang 
idxd_wq_put(struct idxd_wq * wq)640c52ca478SDave Jiang static inline void idxd_wq_put(struct idxd_wq *wq)
641c52ca478SDave Jiang {
642c52ca478SDave Jiang 	wq->client_count--;
643c52ca478SDave Jiang }
644c52ca478SDave Jiang 
idxd_wq_refcount(struct idxd_wq * wq)645c52ca478SDave Jiang static inline int idxd_wq_refcount(struct idxd_wq *wq)
646c52ca478SDave Jiang {
647c52ca478SDave Jiang 	return wq->client_count;
648c52ca478SDave Jiang };
649c52ca478SDave Jiang 
idxd_wq_set_private(struct idxd_wq * wq,void * private)650786d0e7fSTom Zanussi static inline void idxd_wq_set_private(struct idxd_wq *wq, void *private)
651786d0e7fSTom Zanussi {
652786d0e7fSTom Zanussi 	dev_set_drvdata(wq_confdev(wq), private);
653786d0e7fSTom Zanussi }
654786d0e7fSTom Zanussi 
idxd_wq_get_private(struct idxd_wq * wq)655786d0e7fSTom Zanussi static inline void *idxd_wq_get_private(struct idxd_wq *wq)
656786d0e7fSTom Zanussi {
657786d0e7fSTom Zanussi 	return dev_get_drvdata(wq_confdev(wq));
658786d0e7fSTom Zanussi }
659786d0e7fSTom Zanussi 
660e8dbd644SXiaochen Shen /*
661e8dbd644SXiaochen Shen  * Intel IAA does not support batch processing.
662e8dbd644SXiaochen Shen  * The max batch size of device, max batch size of wq and
663e8dbd644SXiaochen Shen  * max batch shift of wqcfg should be always 0 on IAA.
664e8dbd644SXiaochen Shen  */
idxd_set_max_batch_size(int idxd_type,struct idxd_device * idxd,u32 max_batch_size)665e8dbd644SXiaochen Shen static inline void idxd_set_max_batch_size(int idxd_type, struct idxd_device *idxd,
666e8dbd644SXiaochen Shen 					   u32 max_batch_size)
667e8dbd644SXiaochen Shen {
668e8dbd644SXiaochen Shen 	if (idxd_type == IDXD_TYPE_IAX)
669e8dbd644SXiaochen Shen 		idxd->max_batch_size = 0;
670e8dbd644SXiaochen Shen 	else
671e8dbd644SXiaochen Shen 		idxd->max_batch_size = max_batch_size;
672e8dbd644SXiaochen Shen }
673e8dbd644SXiaochen Shen 
idxd_wq_set_max_batch_size(int idxd_type,struct idxd_wq * wq,u32 max_batch_size)674e8dbd644SXiaochen Shen static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq,
675e8dbd644SXiaochen Shen 					      u32 max_batch_size)
676e8dbd644SXiaochen Shen {
677e8dbd644SXiaochen Shen 	if (idxd_type == IDXD_TYPE_IAX)
678e8dbd644SXiaochen Shen 		wq->max_batch_size = 0;
679e8dbd644SXiaochen Shen 	else
680e8dbd644SXiaochen Shen 		wq->max_batch_size = max_batch_size;
681e8dbd644SXiaochen Shen }
682e8dbd644SXiaochen Shen 
idxd_wqcfg_set_max_batch_shift(int idxd_type,union wqcfg * wqcfg,u32 max_batch_shift)683e8dbd644SXiaochen Shen static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg,
684e8dbd644SXiaochen Shen 						  u32 max_batch_shift)
685e8dbd644SXiaochen Shen {
686e8dbd644SXiaochen Shen 	if (idxd_type == IDXD_TYPE_IAX)
687e8dbd644SXiaochen Shen 		wqcfg->max_batch_shift = 0;
688e8dbd644SXiaochen Shen 	else
689e8dbd644SXiaochen Shen 		wqcfg->max_batch_shift = max_batch_shift;
690e8dbd644SXiaochen Shen }
691e8dbd644SXiaochen Shen 
idxd_wq_driver_name_match(struct idxd_wq * wq,struct device * dev)6927af1e0acSDave Jiang static inline int idxd_wq_driver_name_match(struct idxd_wq *wq, struct device *dev)
6937af1e0acSDave Jiang {
6947af1e0acSDave Jiang 	return (strncmp(wq->driver_name, dev->driver->name, strlen(dev->driver->name)) == 0);
6957af1e0acSDave Jiang }
6967af1e0acSDave Jiang 
69715a61101SDave Jiang #define MODULE_ALIAS_IDXD_DEVICE(type) MODULE_ALIAS("idxd:t" __stringify(type) "*")
69815a61101SDave Jiang #define IDXD_DEVICES_MODALIAS_FMT "idxd:t%d"
69915a61101SDave Jiang 
7003ecfc913SDave Jiang int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv,
7013ecfc913SDave Jiang 					struct module *module, const char *mod_name);
7023ecfc913SDave Jiang #define idxd_driver_register(driver) \
7033ecfc913SDave Jiang 	__idxd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
7043ecfc913SDave Jiang 
7053ecfc913SDave Jiang void idxd_driver_unregister(struct idxd_device_driver *idxd_drv);
7063ecfc913SDave Jiang 
7076e7f3ee9SDave Jiang #define module_idxd_driver(__idxd_driver) \
7086e7f3ee9SDave Jiang 	module_driver(__idxd_driver, idxd_driver_register, idxd_driver_unregister)
7096e7f3ee9SDave Jiang 
710aa8d18beSTom Zanussi void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc);
711aa8d18beSTom Zanussi void idxd_dma_complete_txd(struct idxd_desc *desc,
712aa8d18beSTom Zanussi 			   enum idxd_complete_type comp_type,
713aa8d18beSTom Zanussi 			   bool free_desc, void *ctx, u32 *status);
714aa8d18beSTom Zanussi 
idxd_desc_complete(struct idxd_desc * desc,enum idxd_complete_type comp_type,bool free_desc)715aa8d18beSTom Zanussi static inline void idxd_desc_complete(struct idxd_desc *desc,
716aa8d18beSTom Zanussi 				      enum idxd_complete_type comp_type,
717aa8d18beSTom Zanussi 				      bool free_desc)
718aa8d18beSTom Zanussi {
719aa8d18beSTom Zanussi 	struct idxd_device_driver *drv;
720aa8d18beSTom Zanussi 	u32 status;
721aa8d18beSTom Zanussi 
722aa8d18beSTom Zanussi 	drv = wq_to_idxd_drv(desc->wq);
723aa8d18beSTom Zanussi 	if (drv->desc_complete)
724aa8d18beSTom Zanussi 		drv->desc_complete(desc, comp_type, free_desc,
725aa8d18beSTom Zanussi 				   &desc->txd, &status);
726aa8d18beSTom Zanussi }
727aa8d18beSTom Zanussi 
728c52ca478SDave Jiang int idxd_register_bus_type(void);
729c52ca478SDave Jiang void idxd_unregister_bus_type(void);
73047c16ac2SDave Jiang int idxd_register_devices(struct idxd_device *idxd);
73147c16ac2SDave Jiang void idxd_unregister_devices(struct idxd_device *idxd);
7325b0c68c4SDave Jiang void idxd_wqs_quiesce(struct idxd_device *idxd);
733f6d442f7SDave Jiang bool idxd_queue_int_handle_resubmit(struct idxd_desc *desc);
73434ca0066SDave Jiang void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count);
735979f6dedSTom Zanussi int idxd_load_iaa_device_defaults(struct idxd_device *idxd);
736bfe1d560SDave Jiang 
737bfe1d560SDave Jiang /* device interrupt control */
738bfe1d560SDave Jiang irqreturn_t idxd_misc_thread(int vec, void *data);
739bfe1d560SDave Jiang irqreturn_t idxd_wq_thread(int irq, void *data);
740bfe1d560SDave Jiang void idxd_mask_error_interrupts(struct idxd_device *idxd);
741bfe1d560SDave Jiang void idxd_unmask_error_interrupts(struct idxd_device *idxd);
742bfe1d560SDave Jiang 
743bfe1d560SDave Jiang /* device control */
744bd42805bSDave Jiang int idxd_device_drv_probe(struct idxd_dev *idxd_dev);
745745e92a6SDave Jiang void idxd_device_drv_remove(struct idxd_dev *idxd_dev);
746d7ad915dSTom Zanussi int idxd_drv_enable_wq(struct idxd_wq *wq);
747d7ad915dSTom Zanussi void idxd_drv_disable_wq(struct idxd_wq *wq);
74889e3becdSDave Jiang int idxd_device_init_reset(struct idxd_device *idxd);
749bfe1d560SDave Jiang int idxd_device_enable(struct idxd_device *idxd);
750bfe1d560SDave Jiang int idxd_device_disable(struct idxd_device *idxd);
7510d5c10b4SDave Jiang void idxd_device_reset(struct idxd_device *idxd);
7520dcfe41eSDave Jiang void idxd_device_clear_state(struct idxd_device *idxd);
753bfe1d560SDave Jiang int idxd_device_config(struct idxd_device *idxd);
7548e50d392SDave Jiang void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid);
7558c66bbdcSDave Jiang int idxd_device_load_config(struct idxd_device *idxd);
756eb15e715SDave Jiang int idxd_device_request_int_handle(struct idxd_device *idxd, int idx, int *handle,
757eb15e715SDave Jiang 				   enum idxd_interrupt_type irq_type);
758eb15e715SDave Jiang int idxd_device_release_int_handle(struct idxd_device *idxd, int handle,
759eb15e715SDave Jiang 				   enum idxd_interrupt_type irq_type);
760bfe1d560SDave Jiang 
761bfe1d560SDave Jiang /* work queue control */
7625b0c68c4SDave Jiang void idxd_wqs_unmap_portal(struct idxd_device *idxd);
763bfe1d560SDave Jiang int idxd_wq_alloc_resources(struct idxd_wq *wq);
764bfe1d560SDave Jiang void idxd_wq_free_resources(struct idxd_wq *wq);
765bfe1d560SDave Jiang int idxd_wq_enable(struct idxd_wq *wq);
7660dcfe41eSDave Jiang int idxd_wq_disable(struct idxd_wq *wq, bool reset_config);
7670d5c10b4SDave Jiang void idxd_wq_drain(struct idxd_wq *wq);
768ea9aadc0SDave Jiang void idxd_wq_reset(struct idxd_wq *wq);
769c52ca478SDave Jiang int idxd_wq_map_portal(struct idxd_wq *wq);
770c52ca478SDave Jiang void idxd_wq_unmap_portal(struct idxd_wq *wq);
7718e50d392SDave Jiang int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid);
7728e50d392SDave Jiang int idxd_wq_disable_pasid(struct idxd_wq *wq);
773bd5970a0SDave Jiang void __idxd_wq_quiesce(struct idxd_wq *wq);
77493a40a6dSDave Jiang void idxd_wq_quiesce(struct idxd_wq *wq);
77593a40a6dSDave Jiang int idxd_wq_init_percpu_ref(struct idxd_wq *wq);
776403a2e23SDave Jiang void idxd_wq_free_irq(struct idxd_wq *wq);
777403a2e23SDave Jiang int idxd_wq_request_irq(struct idxd_wq *wq);
778bfe1d560SDave Jiang 
779d1dfe5b8SDave Jiang /* submission */
780d1dfe5b8SDave Jiang int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);
781d1dfe5b8SDave Jiang struct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype);
7827930d855SDave Jiang int idxd_enqcmds(struct idxd_wq *wq, void __iomem *portal, const void *desc);
783d1dfe5b8SDave Jiang 
7848f47d1a5SDave Jiang /* dmaengine */
7858f47d1a5SDave Jiang int idxd_register_dma_device(struct idxd_device *idxd);
7868f47d1a5SDave Jiang void idxd_unregister_dma_device(struct idxd_device *idxd);
7878f47d1a5SDave Jiang 
78842d279f9SDave Jiang /* cdev */
78942d279f9SDave Jiang int idxd_cdev_register(void);
79042d279f9SDave Jiang void idxd_cdev_remove(void);
79142d279f9SDave Jiang int idxd_cdev_get_major(struct idxd_device *idxd);
79242d279f9SDave Jiang int idxd_wq_add_cdev(struct idxd_wq *wq);
79342d279f9SDave Jiang void idxd_wq_del_cdev(struct idxd_wq *wq);
794b022f597SFenghua Yu int idxd_copy_cr(struct idxd_wq *wq, ioasid_t pasid, unsigned long addr,
795b022f597SFenghua Yu 		 void *buf, int len);
796fecae134SDave Jiang void idxd_user_counter_increment(struct idxd_wq *wq, u32 pasid, int index);
79742d279f9SDave Jiang 
79881dd4d4dSTom Zanussi /* perfmon */
79981dd4d4dSTom Zanussi #if IS_ENABLED(CONFIG_INTEL_IDXD_PERFMON)
80081dd4d4dSTom Zanussi int perfmon_pmu_init(struct idxd_device *idxd);
80181dd4d4dSTom Zanussi void perfmon_pmu_remove(struct idxd_device *idxd);
80281dd4d4dSTom Zanussi void perfmon_counter_overflow(struct idxd_device *idxd);
80381dd4d4dSTom Zanussi #else
perfmon_pmu_init(struct idxd_device * idxd)80481dd4d4dSTom Zanussi static inline int perfmon_pmu_init(struct idxd_device *idxd) { return 0; }
perfmon_pmu_remove(struct idxd_device * idxd)80581dd4d4dSTom Zanussi static inline void perfmon_pmu_remove(struct idxd_device *idxd) {}
perfmon_counter_overflow(struct idxd_device * idxd)80681dd4d4dSTom Zanussi static inline void perfmon_counter_overflow(struct idxd_device *idxd) {}
80781dd4d4dSTom Zanussi #endif
80881dd4d4dSTom Zanussi 
8095fbe6503SDave Jiang /* debugfs */
8105fbe6503SDave Jiang int idxd_device_init_debugfs(struct idxd_device *idxd);
8115fbe6503SDave Jiang void idxd_device_remove_debugfs(struct idxd_device *idxd);
8125fbe6503SDave Jiang int idxd_init_debugfs(void);
8135fbe6503SDave Jiang void idxd_remove_debugfs(void);
8145fbe6503SDave Jiang 
815bfe1d560SDave Jiang #endif
816