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