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> 138b67426eSDave Jiang #include <linux/ioasid.h> 14de5819b9SJerry Snitselaar #include <linux/bitmap.h> 1581dd4d4dSTom Zanussi #include <linux/perf_event.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, 35700af3a0SDave Jiang IDXD_DEV_MAX_TYPE, 36700af3a0SDave Jiang }; 37700af3a0SDave Jiang 38700af3a0SDave Jiang struct idxd_dev { 39700af3a0SDave Jiang struct device conf_dev; 40700af3a0SDave Jiang enum idxd_dev_type type; 41700af3a0SDave Jiang }; 4239786285SDave Jiang 43bfe1d560SDave Jiang #define IDXD_REG_TIMEOUT 50 44bfe1d560SDave Jiang #define IDXD_DRAIN_TIMEOUT 5000 45bfe1d560SDave Jiang 46bfe1d560SDave Jiang enum idxd_type { 47bfe1d560SDave Jiang IDXD_TYPE_UNKNOWN = -1, 48bfe1d560SDave Jiang IDXD_TYPE_DSA = 0, 49f25b4638SDave Jiang IDXD_TYPE_IAX, 50f25b4638SDave Jiang IDXD_TYPE_MAX, 51bfe1d560SDave Jiang }; 52bfe1d560SDave Jiang 53bfe1d560SDave Jiang #define IDXD_NAME_SIZE 128 5481dd4d4dSTom Zanussi #define IDXD_PMU_EVENT_MAX 64 55bfe1d560SDave Jiang 567930d855SDave Jiang #define IDXD_ENQCMDS_RETRIES 32 577930d855SDave Jiang #define IDXD_ENQCMDS_MAX_RETRIES 64 587930d855SDave Jiang 59bfe1d560SDave Jiang struct idxd_device_driver { 60da5a11d7SDave Jiang const char *name; 615fee6567SDave Jiang enum idxd_dev_type *type; 62fcc2281bSDave Jiang int (*probe)(struct idxd_dev *idxd_dev); 63fcc2281bSDave Jiang void (*remove)(struct idxd_dev *idxd_dev); 64bfe1d560SDave Jiang struct device_driver drv; 65bfe1d560SDave Jiang }; 66bfe1d560SDave Jiang 67c05257b5SDave Jiang extern struct idxd_device_driver dsa_drv; 68034b3290SDave Jiang extern struct idxd_device_driver idxd_drv; 690cda4f69SDave Jiang extern struct idxd_device_driver idxd_dmaengine_drv; 70448c3de8SDave Jiang extern struct idxd_device_driver idxd_user_drv; 71c05257b5SDave Jiang 728b67426eSDave Jiang #define INVALID_INT_HANDLE -1 73bfe1d560SDave Jiang struct idxd_irq_entry { 74bfe1d560SDave Jiang int id; 755fc8e85fSDave Jiang int vector; 76bfe1d560SDave Jiang struct llist_head pending_llist; 77bfe1d560SDave Jiang struct list_head work_list; 78e4f4d8cdSDave Jiang /* 79e4f4d8cdSDave Jiang * Lock to protect access between irq thread process descriptor 80e4f4d8cdSDave Jiang * and irq thread processing error descriptor. 81e4f4d8cdSDave Jiang */ 82e4f4d8cdSDave Jiang spinlock_t list_lock; 838b67426eSDave Jiang int int_handle; 848b67426eSDave Jiang ioasid_t pasid; 85bfe1d560SDave Jiang }; 86bfe1d560SDave Jiang 87bfe1d560SDave Jiang struct idxd_group { 88700af3a0SDave Jiang struct idxd_dev idxd_dev; 89bfe1d560SDave Jiang struct idxd_device *idxd; 90bfe1d560SDave Jiang struct grpcfg grpcfg; 91bfe1d560SDave Jiang int id; 92bfe1d560SDave Jiang int num_engines; 93bfe1d560SDave Jiang int num_wqs; 947ed6f1b8SDave Jiang bool use_rdbuf_limit; 957ed6f1b8SDave Jiang u8 rdbufs_allowed; 967ed6f1b8SDave Jiang u8 rdbufs_reserved; 97bfe1d560SDave Jiang int tc_a; 98bfe1d560SDave Jiang int tc_b; 991f273752SDave Jiang int desc_progress_limit; 1007ca68fa3SDave Jiang int batch_progress_limit; 101bfe1d560SDave Jiang }; 102bfe1d560SDave Jiang 10381dd4d4dSTom Zanussi struct idxd_pmu { 10481dd4d4dSTom Zanussi struct idxd_device *idxd; 10581dd4d4dSTom Zanussi 10681dd4d4dSTom Zanussi struct perf_event *event_list[IDXD_PMU_EVENT_MAX]; 10781dd4d4dSTom Zanussi int n_events; 10881dd4d4dSTom Zanussi 10981dd4d4dSTom Zanussi DECLARE_BITMAP(used_mask, IDXD_PMU_EVENT_MAX); 11081dd4d4dSTom Zanussi 11181dd4d4dSTom Zanussi struct pmu pmu; 11281dd4d4dSTom Zanussi char name[IDXD_NAME_SIZE]; 11381dd4d4dSTom Zanussi int cpu; 11481dd4d4dSTom Zanussi 11581dd4d4dSTom Zanussi int n_counters; 11681dd4d4dSTom Zanussi int counter_width; 11781dd4d4dSTom Zanussi int n_event_categories; 11881dd4d4dSTom Zanussi 11981dd4d4dSTom Zanussi bool per_counter_caps_supported; 12081dd4d4dSTom Zanussi unsigned long supported_event_categories; 12181dd4d4dSTom Zanussi 12281dd4d4dSTom Zanussi unsigned long supported_filters; 12381dd4d4dSTom Zanussi int n_filters; 12481dd4d4dSTom Zanussi 12581dd4d4dSTom Zanussi struct hlist_node cpuhp_node; 12681dd4d4dSTom Zanussi }; 12781dd4d4dSTom Zanussi 128bfe1d560SDave Jiang #define IDXD_MAX_PRIORITY 0xf 129bfe1d560SDave Jiang 130bfe1d560SDave Jiang enum idxd_wq_state { 131bfe1d560SDave Jiang IDXD_WQ_DISABLED = 0, 132bfe1d560SDave Jiang IDXD_WQ_ENABLED, 133bfe1d560SDave Jiang }; 134bfe1d560SDave Jiang 135bfe1d560SDave Jiang enum idxd_wq_flag { 136bfe1d560SDave Jiang WQ_FLAG_DEDICATED = 0, 1378e50d392SDave Jiang WQ_FLAG_BLOCK_ON_FAULT, 13822bd0df8SDave Jiang WQ_FLAG_ATS_DISABLE, 139bfe1d560SDave Jiang }; 140bfe1d560SDave Jiang 141bfe1d560SDave Jiang enum idxd_wq_type { 142bfe1d560SDave Jiang IDXD_WQT_NONE = 0, 143bfe1d560SDave Jiang IDXD_WQT_KERNEL, 14442d279f9SDave Jiang IDXD_WQT_USER, 14542d279f9SDave Jiang }; 14642d279f9SDave Jiang 14742d279f9SDave Jiang struct idxd_cdev { 14804922b74SDave Jiang struct idxd_wq *wq; 14942d279f9SDave Jiang struct cdev cdev; 150700af3a0SDave Jiang struct idxd_dev idxd_dev; 15142d279f9SDave Jiang int minor; 152bfe1d560SDave Jiang }; 153bfe1d560SDave Jiang 154bfe1d560SDave Jiang #define IDXD_ALLOCATED_BATCH_SIZE 128U 155bfe1d560SDave Jiang #define WQ_NAME_SIZE 1024 156bfe1d560SDave Jiang #define WQ_TYPE_SIZE 10 157bfe1d560SDave Jiang 15892452a72SDave Jiang #define WQ_DEFAULT_QUEUE_DEPTH 16 15992452a72SDave Jiang #define WQ_DEFAULT_MAX_XFER SZ_2M 16092452a72SDave Jiang #define WQ_DEFAULT_MAX_BATCH 32 16192452a72SDave Jiang 162d1dfe5b8SDave Jiang enum idxd_op_type { 163d1dfe5b8SDave Jiang IDXD_OP_BLOCK = 0, 164d1dfe5b8SDave Jiang IDXD_OP_NONBLOCK = 1, 165d1dfe5b8SDave Jiang }; 166d1dfe5b8SDave Jiang 1678f47d1a5SDave Jiang enum idxd_complete_type { 1688f47d1a5SDave Jiang IDXD_COMPLETE_NORMAL = 0, 1698f47d1a5SDave Jiang IDXD_COMPLETE_ABORT, 1708e50d392SDave Jiang IDXD_COMPLETE_DEV_FAIL, 1718f47d1a5SDave Jiang }; 1728f47d1a5SDave Jiang 17339786285SDave Jiang struct idxd_dma_chan { 17439786285SDave Jiang struct dma_chan chan; 17539786285SDave Jiang struct idxd_wq *wq; 17639786285SDave Jiang }; 17739786285SDave Jiang 178bfe1d560SDave Jiang struct idxd_wq { 1798e50d392SDave Jiang void __iomem *portal; 180a9c17152SDave Jiang u32 portal_offset; 1817930d855SDave Jiang unsigned int enqcmds_retries; 18293a40a6dSDave Jiang struct percpu_ref wq_active; 18393a40a6dSDave Jiang struct completion wq_dead; 18456fc39f5SDave Jiang struct completion wq_resurrect; 185700af3a0SDave Jiang struct idxd_dev idxd_dev; 18604922b74SDave Jiang struct idxd_cdev *idxd_cdev; 18704922b74SDave Jiang struct wait_queue_head err_queue; 1882f30decdSDave Jiang struct workqueue_struct *wq; 189bfe1d560SDave Jiang struct idxd_device *idxd; 190bfe1d560SDave Jiang int id; 191ec0d6423SDave Jiang struct idxd_irq_entry ie; 192bfe1d560SDave Jiang enum idxd_wq_type type; 193bfe1d560SDave Jiang struct idxd_group *group; 194bfe1d560SDave Jiang int client_count; 195bfe1d560SDave Jiang struct mutex wq_lock; /* mutex for workqueue */ 196bfe1d560SDave Jiang u32 size; 197bfe1d560SDave Jiang u32 threshold; 198bfe1d560SDave Jiang u32 priority; 199bfe1d560SDave Jiang enum idxd_wq_state state; 200bfe1d560SDave Jiang unsigned long flags; 201d98793b5SDave Jiang union wqcfg *wqcfg; 202b0325aefSDave Jiang unsigned long *opcap_bmap; 203b0325aefSDave Jiang 204bfe1d560SDave Jiang struct dsa_hw_desc **hw_descs; 205bfe1d560SDave Jiang int num_descs; 206f25b4638SDave Jiang union { 207bfe1d560SDave Jiang struct dsa_completion_record *compls; 208f25b4638SDave Jiang struct iax_completion_record *iax_compls; 209f25b4638SDave Jiang }; 210bfe1d560SDave Jiang dma_addr_t compls_addr; 211bfe1d560SDave Jiang int compls_size; 212bfe1d560SDave Jiang struct idxd_desc **descs; 2130705107fSDave Jiang struct sbitmap_queue sbq; 21439786285SDave Jiang struct idxd_dma_chan *idxd_chan; 215bfe1d560SDave Jiang char name[WQ_NAME_SIZE + 1]; 216d7aad555SDave Jiang u64 max_xfer_bytes; 217e7184b15SDave Jiang u32 max_batch_size; 218b022f597SFenghua Yu 219b022f597SFenghua Yu /* Lock to protect upasid_xa access. */ 220b022f597SFenghua Yu struct mutex uc_lock; 221b022f597SFenghua Yu struct xarray upasid_xa; 222bfe1d560SDave Jiang }; 223bfe1d560SDave Jiang 224bfe1d560SDave Jiang struct idxd_engine { 225700af3a0SDave Jiang struct idxd_dev idxd_dev; 226bfe1d560SDave Jiang int id; 227bfe1d560SDave Jiang struct idxd_group *group; 228bfe1d560SDave Jiang struct idxd_device *idxd; 229bfe1d560SDave Jiang }; 230bfe1d560SDave Jiang 231bfe1d560SDave Jiang /* shadow registers */ 232bfe1d560SDave Jiang struct idxd_hw { 233bfe1d560SDave Jiang u32 version; 234bfe1d560SDave Jiang union gen_cap_reg gen_cap; 235bfe1d560SDave Jiang union wq_cap_reg wq_cap; 236bfe1d560SDave Jiang union group_cap_reg group_cap; 237bfe1d560SDave Jiang union engine_cap_reg engine_cap; 238bfe1d560SDave Jiang struct opcap opcap; 239eb15e715SDave Jiang u32 cmd_cap; 2409f0d99b3SDave Jiang union iaa_cap_reg iaa_cap; 241bfe1d560SDave Jiang }; 242bfe1d560SDave Jiang 243bfe1d560SDave Jiang enum idxd_device_state { 244bfe1d560SDave Jiang IDXD_DEV_HALTED = -1, 245bfe1d560SDave Jiang IDXD_DEV_DISABLED = 0, 246bfe1d560SDave Jiang IDXD_DEV_ENABLED, 247bfe1d560SDave Jiang }; 248bfe1d560SDave Jiang 249bfe1d560SDave Jiang enum idxd_device_flag { 250bfe1d560SDave Jiang IDXD_FLAG_CONFIGURABLE = 0, 2510d5c10b4SDave Jiang IDXD_FLAG_CMD_RUNNING, 2528e50d392SDave Jiang IDXD_FLAG_PASID_ENABLED, 25342a1b738SDave Jiang IDXD_FLAG_USER_PASID_ENABLED, 254bfe1d560SDave Jiang }; 255bfe1d560SDave Jiang 25639786285SDave Jiang struct idxd_dma_dev { 25739786285SDave Jiang struct idxd_device *idxd; 25839786285SDave Jiang struct dma_device dma; 25939786285SDave Jiang }; 26039786285SDave Jiang 261435b512dSDave Jiang struct idxd_driver_data { 262435b512dSDave Jiang const char *name_prefix; 263bfe1d560SDave Jiang enum idxd_type type; 264435b512dSDave Jiang struct device_type *dev_type; 265435b512dSDave Jiang int compl_size; 266435b512dSDave Jiang int align; 267c40bd7d9SDave Jiang int evl_cr_off; 268*2442b747SDave Jiang int cr_status_off; 269*2442b747SDave Jiang int cr_result_off; 270435b512dSDave Jiang }; 271435b512dSDave Jiang 2721649091fSDave Jiang struct idxd_evl { 273244da66cSDave Jiang /* Lock to protect event log access. */ 274244da66cSDave Jiang spinlock_t lock; 275244da66cSDave Jiang void *log; 276244da66cSDave Jiang dma_addr_t dma; 277244da66cSDave Jiang /* Total size of event log = number of entries * entry size. */ 278244da66cSDave Jiang unsigned int log_size; 279244da66cSDave Jiang /* The number of entries in the event log. */ 2801649091fSDave Jiang u16 size; 281244da66cSDave Jiang u16 head; 282c40bd7d9SDave Jiang unsigned long *bmap; 283*2442b747SDave Jiang bool batch_fail[IDXD_MAX_BATCH_IDENT]; 2841649091fSDave Jiang }; 2851649091fSDave Jiang 286c2f156bfSDave Jiang struct idxd_evl_fault { 287c2f156bfSDave Jiang struct work_struct work; 288c2f156bfSDave Jiang struct idxd_wq *wq; 289c2f156bfSDave Jiang u8 status; 290c2f156bfSDave Jiang 291c2f156bfSDave Jiang /* make this last member always */ 292c2f156bfSDave Jiang struct __evl_entry entry[]; 293c2f156bfSDave Jiang }; 294c2f156bfSDave Jiang 295435b512dSDave Jiang struct idxd_device { 296700af3a0SDave Jiang struct idxd_dev idxd_dev; 297435b512dSDave Jiang struct idxd_driver_data *data; 298bfe1d560SDave Jiang struct list_head list; 299bfe1d560SDave Jiang struct idxd_hw hw; 300bfe1d560SDave Jiang enum idxd_device_state state; 301bfe1d560SDave Jiang unsigned long flags; 302bfe1d560SDave Jiang int id; 30342d279f9SDave Jiang int major; 304125d1037SDave Jiang u32 cmd_status; 305ec0d6423SDave Jiang struct idxd_irq_entry ie; /* misc irq, msix 0 */ 306bfe1d560SDave Jiang 307bfe1d560SDave Jiang struct pci_dev *pdev; 308bfe1d560SDave Jiang void __iomem *reg_base; 309bfe1d560SDave Jiang 310bfe1d560SDave Jiang spinlock_t dev_lock; /* spinlock for device */ 31153b2ee7fSDave Jiang spinlock_t cmd_lock; /* spinlock for device commands */ 3120d5c10b4SDave Jiang struct completion *cmd_done; 313defe49f9SDave Jiang struct idxd_group **groups; 3147c5dd23eSDave Jiang struct idxd_wq **wqs; 31575b91130SDave Jiang struct idxd_engine **engines; 316bfe1d560SDave Jiang 3178e50d392SDave Jiang struct iommu_sva *sva; 3188e50d392SDave Jiang unsigned int pasid; 3198e50d392SDave Jiang 320bfe1d560SDave Jiang int num_groups; 3218b67426eSDave Jiang int irq_cnt; 3228b67426eSDave Jiang bool request_int_handles; 323bfe1d560SDave Jiang 324bfe1d560SDave Jiang u32 msix_perm_offset; 325bfe1d560SDave Jiang u32 wqcfg_offset; 326bfe1d560SDave Jiang u32 grpcfg_offset; 327bfe1d560SDave Jiang u32 perfmon_offset; 328bfe1d560SDave Jiang 329bfe1d560SDave Jiang u64 max_xfer_bytes; 330bfe1d560SDave Jiang u32 max_batch_size; 331bfe1d560SDave Jiang int max_groups; 332bfe1d560SDave Jiang int max_engines; 3337ed6f1b8SDave Jiang int max_rdbufs; 334bfe1d560SDave Jiang int max_wqs; 335bfe1d560SDave Jiang int max_wq_size; 3367ed6f1b8SDave Jiang int rdbuf_limit; 3377ed6f1b8SDave Jiang int nr_rdbufs; /* non-reserved read buffers */ 338d98793b5SDave Jiang unsigned int wqcfg_size; 339de5819b9SJerry Snitselaar unsigned long *wq_enable_map; 340bfe1d560SDave Jiang 341bfe1d560SDave Jiang union sw_err_reg sw_err; 3420d5c10b4SDave Jiang wait_queue_head_t cmd_waitq; 3438f47d1a5SDave Jiang 34439786285SDave Jiang struct idxd_dma_dev *idxd_dma; 3450d5c10b4SDave Jiang struct workqueue_struct *wq; 3460d5c10b4SDave Jiang struct work_struct work; 347eb15e715SDave Jiang 34881dd4d4dSTom Zanussi struct idxd_pmu *idxd_pmu; 349a8563a33SDave Jiang 350a8563a33SDave Jiang unsigned long *opcap_bmap; 3511649091fSDave Jiang struct idxd_evl *evl; 352c2f156bfSDave Jiang struct kmem_cache *evl_cache; 3535fbe6503SDave Jiang 3545fbe6503SDave Jiang struct dentry *dbgfs_dir; 3555fbe6503SDave Jiang struct dentry *dbgfs_evl_file; 356bfe1d560SDave Jiang }; 357bfe1d560SDave Jiang 358244da66cSDave Jiang static inline unsigned int evl_ent_size(struct idxd_device *idxd) 359244da66cSDave Jiang { 360244da66cSDave Jiang return idxd->hw.gen_cap.evl_support ? 361244da66cSDave Jiang (32 * (1 << idxd->hw.gen_cap.evl_support)) : 0; 362244da66cSDave Jiang } 363244da66cSDave Jiang 364244da66cSDave Jiang static inline unsigned int evl_size(struct idxd_device *idxd) 365244da66cSDave Jiang { 366244da66cSDave Jiang return idxd->evl->size * evl_ent_size(idxd); 367244da66cSDave Jiang } 368244da66cSDave Jiang 369bfe1d560SDave Jiang /* IDXD software descriptor */ 370bfe1d560SDave Jiang struct idxd_desc { 371f25b4638SDave Jiang union { 372bfe1d560SDave Jiang struct dsa_hw_desc *hw; 373f25b4638SDave Jiang struct iax_hw_desc *iax_hw; 374f25b4638SDave Jiang }; 375bfe1d560SDave Jiang dma_addr_t desc_dma; 376f25b4638SDave Jiang union { 377bfe1d560SDave Jiang struct dsa_completion_record *completion; 378f25b4638SDave Jiang struct iax_completion_record *iax_completion; 379f25b4638SDave Jiang }; 380bfe1d560SDave Jiang dma_addr_t compl_dma; 3818f47d1a5SDave Jiang struct dma_async_tx_descriptor txd; 382bfe1d560SDave Jiang struct llist_node llnode; 383bfe1d560SDave Jiang struct list_head list; 384bfe1d560SDave Jiang int id; 3850705107fSDave Jiang int cpu; 386bfe1d560SDave Jiang struct idxd_wq *wq; 387bfe1d560SDave Jiang }; 388bfe1d560SDave Jiang 3896b4b87f2SDave Jiang /* 3906b4b87f2SDave Jiang * This is software defined error for the completion status. We overload the error code 3916b4b87f2SDave Jiang * that will never appear in completion status and only SWERR register. 3926b4b87f2SDave Jiang */ 3936b4b87f2SDave Jiang enum idxd_completion_status { 3946b4b87f2SDave Jiang IDXD_COMP_DESC_ABORT = 0xff, 3956b4b87f2SDave Jiang }; 3966b4b87f2SDave Jiang 397700af3a0SDave Jiang #define idxd_confdev(idxd) &idxd->idxd_dev.conf_dev 398700af3a0SDave Jiang #define wq_confdev(wq) &wq->idxd_dev.conf_dev 399700af3a0SDave Jiang #define engine_confdev(engine) &engine->idxd_dev.conf_dev 400700af3a0SDave Jiang #define group_confdev(group) &group->idxd_dev.conf_dev 401700af3a0SDave Jiang #define cdev_dev(cdev) &cdev->idxd_dev.conf_dev 402700af3a0SDave Jiang 403700af3a0SDave Jiang #define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev) 404fcc2281bSDave Jiang #define idxd_dev_to_idxd(idxd_dev) container_of(idxd_dev, struct idxd_device, idxd_dev) 405fcc2281bSDave Jiang #define idxd_dev_to_wq(idxd_dev) container_of(idxd_dev, struct idxd_wq, idxd_dev) 406700af3a0SDave Jiang 407700af3a0SDave Jiang static inline struct idxd_device *confdev_to_idxd(struct device *dev) 408700af3a0SDave Jiang { 409700af3a0SDave Jiang struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 410700af3a0SDave Jiang 411fcc2281bSDave Jiang return idxd_dev_to_idxd(idxd_dev); 412700af3a0SDave Jiang } 413700af3a0SDave Jiang 414700af3a0SDave Jiang static inline struct idxd_wq *confdev_to_wq(struct device *dev) 415700af3a0SDave Jiang { 416700af3a0SDave Jiang struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 417700af3a0SDave Jiang 418fcc2281bSDave Jiang return idxd_dev_to_wq(idxd_dev); 419700af3a0SDave Jiang } 420700af3a0SDave Jiang 421700af3a0SDave Jiang static inline struct idxd_engine *confdev_to_engine(struct device *dev) 422700af3a0SDave Jiang { 423700af3a0SDave Jiang struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 424700af3a0SDave Jiang 425700af3a0SDave Jiang return container_of(idxd_dev, struct idxd_engine, idxd_dev); 426700af3a0SDave Jiang } 427700af3a0SDave Jiang 428700af3a0SDave Jiang static inline struct idxd_group *confdev_to_group(struct device *dev) 429700af3a0SDave Jiang { 430700af3a0SDave Jiang struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 431700af3a0SDave Jiang 432700af3a0SDave Jiang return container_of(idxd_dev, struct idxd_group, idxd_dev); 433700af3a0SDave Jiang } 434700af3a0SDave Jiang 435700af3a0SDave Jiang static inline struct idxd_cdev *dev_to_cdev(struct device *dev) 436700af3a0SDave Jiang { 437700af3a0SDave Jiang struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 438700af3a0SDave Jiang 439700af3a0SDave Jiang return container_of(idxd_dev, struct idxd_cdev, idxd_dev); 440700af3a0SDave Jiang } 441700af3a0SDave Jiang 442700af3a0SDave Jiang static inline void idxd_dev_set_type(struct idxd_dev *idev, int type) 443700af3a0SDave Jiang { 444700af3a0SDave Jiang if (type >= IDXD_DEV_MAX_TYPE) { 445700af3a0SDave Jiang idev->type = IDXD_DEV_NONE; 446700af3a0SDave Jiang return; 447700af3a0SDave Jiang } 448700af3a0SDave Jiang 449700af3a0SDave Jiang idev->type = type; 450700af3a0SDave Jiang } 451bfe1d560SDave Jiang 452ec0d6423SDave Jiang static inline struct idxd_irq_entry *idxd_get_ie(struct idxd_device *idxd, int idx) 453ec0d6423SDave Jiang { 454ec0d6423SDave Jiang return (idx == 0) ? &idxd->ie : &idxd->wqs[idx - 1]->ie; 455ec0d6423SDave Jiang } 456ec0d6423SDave Jiang 457ec0d6423SDave Jiang static inline struct idxd_wq *ie_to_wq(struct idxd_irq_entry *ie) 458ec0d6423SDave Jiang { 459ec0d6423SDave Jiang return container_of(ie, struct idxd_wq, ie); 460ec0d6423SDave Jiang } 461ec0d6423SDave Jiang 462ec0d6423SDave Jiang static inline struct idxd_device *ie_to_idxd(struct idxd_irq_entry *ie) 463ec0d6423SDave Jiang { 464ec0d6423SDave Jiang return container_of(ie, struct idxd_device, ie); 465ec0d6423SDave Jiang } 466ec0d6423SDave Jiang 46742d279f9SDave Jiang extern struct bus_type dsa_bus_type; 46842d279f9SDave Jiang 4698e50d392SDave Jiang extern bool support_enqcmd; 4704b73e4ebSDave Jiang extern struct ida idxd_ida; 47147c16ac2SDave Jiang extern struct device_type dsa_device_type; 47247c16ac2SDave Jiang extern struct device_type iax_device_type; 4737c5dd23eSDave Jiang extern struct device_type idxd_wq_device_type; 47475b91130SDave Jiang extern struct device_type idxd_engine_device_type; 475defe49f9SDave Jiang extern struct device_type idxd_group_device_type; 47647c16ac2SDave Jiang 477fcc2281bSDave Jiang static inline bool is_dsa_dev(struct idxd_dev *idxd_dev) 47847c16ac2SDave Jiang { 479fcc2281bSDave Jiang return idxd_dev->type == IDXD_DEV_DSA; 48047c16ac2SDave Jiang } 48147c16ac2SDave Jiang 482fcc2281bSDave Jiang static inline bool is_iax_dev(struct idxd_dev *idxd_dev) 48347c16ac2SDave Jiang { 484fcc2281bSDave Jiang return idxd_dev->type == IDXD_DEV_IAX; 48547c16ac2SDave Jiang } 48647c16ac2SDave Jiang 487fcc2281bSDave Jiang static inline bool is_idxd_dev(struct idxd_dev *idxd_dev) 48847c16ac2SDave Jiang { 489fcc2281bSDave Jiang return is_dsa_dev(idxd_dev) || is_iax_dev(idxd_dev); 49047c16ac2SDave Jiang } 4918e50d392SDave Jiang 492fcc2281bSDave Jiang static inline bool is_idxd_wq_dev(struct idxd_dev *idxd_dev) 4937c5dd23eSDave Jiang { 494fcc2281bSDave Jiang return idxd_dev->type == IDXD_DEV_WQ; 4957c5dd23eSDave Jiang } 4967c5dd23eSDave Jiang 4977c5dd23eSDave Jiang static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq) 4987c5dd23eSDave Jiang { 4997c5dd23eSDave Jiang if (wq->type == IDXD_WQT_KERNEL && strcmp(wq->name, "dmaengine") == 0) 5007c5dd23eSDave Jiang return true; 5017c5dd23eSDave Jiang return false; 5027c5dd23eSDave Jiang } 5037c5dd23eSDave Jiang 5046e7f3ee9SDave Jiang static inline bool is_idxd_wq_user(struct idxd_wq *wq) 5057c5dd23eSDave Jiang { 5067c5dd23eSDave Jiang return wq->type == IDXD_WQT_USER; 5077c5dd23eSDave Jiang } 5087c5dd23eSDave Jiang 5096e7f3ee9SDave Jiang static inline bool is_idxd_wq_kernel(struct idxd_wq *wq) 5106e7f3ee9SDave Jiang { 5116e7f3ee9SDave Jiang return wq->type == IDXD_WQT_KERNEL; 5126e7f3ee9SDave Jiang } 5136e7f3ee9SDave Jiang 514bfe1d560SDave Jiang static inline bool wq_dedicated(struct idxd_wq *wq) 515bfe1d560SDave Jiang { 516bfe1d560SDave Jiang return test_bit(WQ_FLAG_DEDICATED, &wq->flags); 517bfe1d560SDave Jiang } 518bfe1d560SDave Jiang 5198e50d392SDave Jiang static inline bool wq_shared(struct idxd_wq *wq) 5208e50d392SDave Jiang { 5218e50d392SDave Jiang return !test_bit(WQ_FLAG_DEDICATED, &wq->flags); 5228e50d392SDave Jiang } 5238e50d392SDave Jiang 5248e50d392SDave Jiang static inline bool device_pasid_enabled(struct idxd_device *idxd) 5258e50d392SDave Jiang { 5268e50d392SDave Jiang return test_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags); 5278e50d392SDave Jiang } 5288e50d392SDave Jiang 52942a1b738SDave Jiang static inline bool device_user_pasid_enabled(struct idxd_device *idxd) 5308e50d392SDave Jiang { 53142a1b738SDave Jiang return test_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags); 53242a1b738SDave Jiang } 53342a1b738SDave Jiang 53442a1b738SDave Jiang static inline bool wq_pasid_enabled(struct idxd_wq *wq) 53542a1b738SDave Jiang { 53642a1b738SDave Jiang return (is_idxd_wq_kernel(wq) && device_pasid_enabled(wq->idxd)) || 53742a1b738SDave Jiang (is_idxd_wq_user(wq) && device_user_pasid_enabled(wq->idxd)); 53842a1b738SDave Jiang } 53942a1b738SDave Jiang 54042a1b738SDave Jiang static inline bool wq_shared_supported(struct idxd_wq *wq) 54142a1b738SDave Jiang { 54242a1b738SDave Jiang return (support_enqcmd && wq_pasid_enabled(wq)); 5438e50d392SDave Jiang } 5448e50d392SDave Jiang 54542d279f9SDave Jiang enum idxd_portal_prot { 54642d279f9SDave Jiang IDXD_PORTAL_UNLIMITED = 0, 54742d279f9SDave Jiang IDXD_PORTAL_LIMITED, 54842d279f9SDave Jiang }; 54942d279f9SDave Jiang 550eb15e715SDave Jiang enum idxd_interrupt_type { 551eb15e715SDave Jiang IDXD_IRQ_MSIX = 0, 552eb15e715SDave Jiang IDXD_IRQ_IMS, 553eb15e715SDave Jiang }; 554eb15e715SDave Jiang 55542d279f9SDave Jiang static inline int idxd_get_wq_portal_offset(enum idxd_portal_prot prot) 55642d279f9SDave Jiang { 55742d279f9SDave Jiang return prot * 0x1000; 55842d279f9SDave Jiang } 55942d279f9SDave Jiang 56042d279f9SDave Jiang static inline int idxd_get_wq_portal_full_offset(int wq_id, 56142d279f9SDave Jiang enum idxd_portal_prot prot) 56242d279f9SDave Jiang { 56342d279f9SDave Jiang return ((wq_id * 4) << PAGE_SHIFT) + idxd_get_wq_portal_offset(prot); 56442d279f9SDave Jiang } 56542d279f9SDave Jiang 566a9c17152SDave Jiang #define IDXD_PORTAL_MASK (PAGE_SIZE - 1) 567a9c17152SDave Jiang 568a9c17152SDave Jiang /* 569a9c17152SDave Jiang * Even though this function can be accessed by multiple threads, it is safe to use. 570a9c17152SDave Jiang * At worst the address gets used more than once before it gets incremented. We don't 571a9c17152SDave Jiang * hit a threshold until iops becomes many million times a second. So the occasional 572a9c17152SDave Jiang * reuse of the same address is tolerable compare to using an atomic variable. This is 573a9c17152SDave Jiang * safe on a system that has atomic load/store for 32bit integers. Given that this is an 574a9c17152SDave Jiang * Intel iEP device, that should not be a problem. 575a9c17152SDave Jiang */ 576a9c17152SDave Jiang static inline void __iomem *idxd_wq_portal_addr(struct idxd_wq *wq) 577a9c17152SDave Jiang { 578a9c17152SDave Jiang int ofs = wq->portal_offset; 579a9c17152SDave Jiang 580a9c17152SDave Jiang wq->portal_offset = (ofs + sizeof(struct dsa_raw_desc)) & IDXD_PORTAL_MASK; 581a9c17152SDave Jiang return wq->portal + ofs; 582a9c17152SDave Jiang } 583a9c17152SDave Jiang 584c52ca478SDave Jiang static inline void idxd_wq_get(struct idxd_wq *wq) 585c52ca478SDave Jiang { 586c52ca478SDave Jiang wq->client_count++; 587c52ca478SDave Jiang } 588c52ca478SDave Jiang 589c52ca478SDave Jiang static inline void idxd_wq_put(struct idxd_wq *wq) 590c52ca478SDave Jiang { 591c52ca478SDave Jiang wq->client_count--; 592c52ca478SDave Jiang } 593c52ca478SDave Jiang 594c52ca478SDave Jiang static inline int idxd_wq_refcount(struct idxd_wq *wq) 595c52ca478SDave Jiang { 596c52ca478SDave Jiang return wq->client_count; 597c52ca478SDave Jiang }; 598c52ca478SDave Jiang 599e8dbd644SXiaochen Shen /* 600e8dbd644SXiaochen Shen * Intel IAA does not support batch processing. 601e8dbd644SXiaochen Shen * The max batch size of device, max batch size of wq and 602e8dbd644SXiaochen Shen * max batch shift of wqcfg should be always 0 on IAA. 603e8dbd644SXiaochen Shen */ 604e8dbd644SXiaochen Shen static inline void idxd_set_max_batch_size(int idxd_type, struct idxd_device *idxd, 605e8dbd644SXiaochen Shen u32 max_batch_size) 606e8dbd644SXiaochen Shen { 607e8dbd644SXiaochen Shen if (idxd_type == IDXD_TYPE_IAX) 608e8dbd644SXiaochen Shen idxd->max_batch_size = 0; 609e8dbd644SXiaochen Shen else 610e8dbd644SXiaochen Shen idxd->max_batch_size = max_batch_size; 611e8dbd644SXiaochen Shen } 612e8dbd644SXiaochen Shen 613e8dbd644SXiaochen Shen static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq, 614e8dbd644SXiaochen Shen u32 max_batch_size) 615e8dbd644SXiaochen Shen { 616e8dbd644SXiaochen Shen if (idxd_type == IDXD_TYPE_IAX) 617e8dbd644SXiaochen Shen wq->max_batch_size = 0; 618e8dbd644SXiaochen Shen else 619e8dbd644SXiaochen Shen wq->max_batch_size = max_batch_size; 620e8dbd644SXiaochen Shen } 621e8dbd644SXiaochen Shen 622e8dbd644SXiaochen Shen static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg, 623e8dbd644SXiaochen Shen u32 max_batch_shift) 624e8dbd644SXiaochen Shen { 625e8dbd644SXiaochen Shen if (idxd_type == IDXD_TYPE_IAX) 626e8dbd644SXiaochen Shen wqcfg->max_batch_shift = 0; 627e8dbd644SXiaochen Shen else 628e8dbd644SXiaochen Shen wqcfg->max_batch_shift = max_batch_shift; 629e8dbd644SXiaochen Shen } 630e8dbd644SXiaochen Shen 6313ecfc913SDave Jiang int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv, 6323ecfc913SDave Jiang struct module *module, const char *mod_name); 6333ecfc913SDave Jiang #define idxd_driver_register(driver) \ 6343ecfc913SDave Jiang __idxd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) 6353ecfc913SDave Jiang 6363ecfc913SDave Jiang void idxd_driver_unregister(struct idxd_device_driver *idxd_drv); 6373ecfc913SDave Jiang 6386e7f3ee9SDave Jiang #define module_idxd_driver(__idxd_driver) \ 6396e7f3ee9SDave Jiang module_driver(__idxd_driver, idxd_driver_register, idxd_driver_unregister) 6406e7f3ee9SDave Jiang 641c52ca478SDave Jiang int idxd_register_bus_type(void); 642c52ca478SDave Jiang void idxd_unregister_bus_type(void); 64347c16ac2SDave Jiang int idxd_register_devices(struct idxd_device *idxd); 64447c16ac2SDave Jiang void idxd_unregister_devices(struct idxd_device *idxd); 645c52ca478SDave Jiang int idxd_register_driver(void); 646c52ca478SDave Jiang void idxd_unregister_driver(void); 6475b0c68c4SDave Jiang void idxd_wqs_quiesce(struct idxd_device *idxd); 648f6d442f7SDave Jiang bool idxd_queue_int_handle_resubmit(struct idxd_desc *desc); 64934ca0066SDave Jiang void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count); 650bfe1d560SDave Jiang 651bfe1d560SDave Jiang /* device interrupt control */ 652bfe1d560SDave Jiang irqreturn_t idxd_misc_thread(int vec, void *data); 653bfe1d560SDave Jiang irqreturn_t idxd_wq_thread(int irq, void *data); 654bfe1d560SDave Jiang void idxd_mask_error_interrupts(struct idxd_device *idxd); 655bfe1d560SDave Jiang void idxd_unmask_error_interrupts(struct idxd_device *idxd); 656bfe1d560SDave Jiang 657bfe1d560SDave Jiang /* device control */ 658034b3290SDave Jiang int idxd_register_idxd_drv(void); 659034b3290SDave Jiang void idxd_unregister_idxd_drv(void); 660bd42805bSDave Jiang int idxd_device_drv_probe(struct idxd_dev *idxd_dev); 661745e92a6SDave Jiang void idxd_device_drv_remove(struct idxd_dev *idxd_dev); 6621f2bb403SDave Jiang int drv_enable_wq(struct idxd_wq *wq); 66369e4f8beSDave Jiang void drv_disable_wq(struct idxd_wq *wq); 66489e3becdSDave Jiang int idxd_device_init_reset(struct idxd_device *idxd); 665bfe1d560SDave Jiang int idxd_device_enable(struct idxd_device *idxd); 666bfe1d560SDave Jiang int idxd_device_disable(struct idxd_device *idxd); 6670d5c10b4SDave Jiang void idxd_device_reset(struct idxd_device *idxd); 6680dcfe41eSDave Jiang void idxd_device_clear_state(struct idxd_device *idxd); 669bfe1d560SDave Jiang int idxd_device_config(struct idxd_device *idxd); 6708e50d392SDave Jiang void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid); 6718c66bbdcSDave Jiang int idxd_device_load_config(struct idxd_device *idxd); 672eb15e715SDave Jiang int idxd_device_request_int_handle(struct idxd_device *idxd, int idx, int *handle, 673eb15e715SDave Jiang enum idxd_interrupt_type irq_type); 674eb15e715SDave Jiang int idxd_device_release_int_handle(struct idxd_device *idxd, int handle, 675eb15e715SDave Jiang enum idxd_interrupt_type irq_type); 676bfe1d560SDave Jiang 677bfe1d560SDave Jiang /* work queue control */ 6785b0c68c4SDave Jiang void idxd_wqs_unmap_portal(struct idxd_device *idxd); 679bfe1d560SDave Jiang int idxd_wq_alloc_resources(struct idxd_wq *wq); 680bfe1d560SDave Jiang void idxd_wq_free_resources(struct idxd_wq *wq); 681bfe1d560SDave Jiang int idxd_wq_enable(struct idxd_wq *wq); 6820dcfe41eSDave Jiang int idxd_wq_disable(struct idxd_wq *wq, bool reset_config); 6830d5c10b4SDave Jiang void idxd_wq_drain(struct idxd_wq *wq); 684ea9aadc0SDave Jiang void idxd_wq_reset(struct idxd_wq *wq); 685c52ca478SDave Jiang int idxd_wq_map_portal(struct idxd_wq *wq); 686c52ca478SDave Jiang void idxd_wq_unmap_portal(struct idxd_wq *wq); 6878e50d392SDave Jiang int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid); 6888e50d392SDave Jiang int idxd_wq_disable_pasid(struct idxd_wq *wq); 689bd5970a0SDave Jiang void __idxd_wq_quiesce(struct idxd_wq *wq); 69093a40a6dSDave Jiang void idxd_wq_quiesce(struct idxd_wq *wq); 69193a40a6dSDave Jiang int idxd_wq_init_percpu_ref(struct idxd_wq *wq); 692403a2e23SDave Jiang void idxd_wq_free_irq(struct idxd_wq *wq); 693403a2e23SDave Jiang int idxd_wq_request_irq(struct idxd_wq *wq); 694bfe1d560SDave Jiang 695d1dfe5b8SDave Jiang /* submission */ 696d1dfe5b8SDave Jiang int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc); 697d1dfe5b8SDave Jiang struct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype); 698d1dfe5b8SDave Jiang void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc); 6997930d855SDave Jiang int idxd_enqcmds(struct idxd_wq *wq, void __iomem *portal, const void *desc); 700d1dfe5b8SDave Jiang 7018f47d1a5SDave Jiang /* dmaengine */ 7028f47d1a5SDave Jiang int idxd_register_dma_device(struct idxd_device *idxd); 7038f47d1a5SDave Jiang void idxd_unregister_dma_device(struct idxd_device *idxd); 7048f47d1a5SDave Jiang void idxd_parse_completion_status(u8 status, enum dmaengine_tx_result *res); 7058f47d1a5SDave Jiang void idxd_dma_complete_txd(struct idxd_desc *desc, 7065d78abb6SDave Jiang enum idxd_complete_type comp_type, bool free_desc); 7078f47d1a5SDave Jiang 70842d279f9SDave Jiang /* cdev */ 70942d279f9SDave Jiang int idxd_cdev_register(void); 71042d279f9SDave Jiang void idxd_cdev_remove(void); 71142d279f9SDave Jiang int idxd_cdev_get_major(struct idxd_device *idxd); 71242d279f9SDave Jiang int idxd_wq_add_cdev(struct idxd_wq *wq); 71342d279f9SDave Jiang void idxd_wq_del_cdev(struct idxd_wq *wq); 714b022f597SFenghua Yu int idxd_copy_cr(struct idxd_wq *wq, ioasid_t pasid, unsigned long addr, 715b022f597SFenghua Yu void *buf, int len); 71642d279f9SDave Jiang 71781dd4d4dSTom Zanussi /* perfmon */ 71881dd4d4dSTom Zanussi #if IS_ENABLED(CONFIG_INTEL_IDXD_PERFMON) 71981dd4d4dSTom Zanussi int perfmon_pmu_init(struct idxd_device *idxd); 72081dd4d4dSTom Zanussi void perfmon_pmu_remove(struct idxd_device *idxd); 72181dd4d4dSTom Zanussi void perfmon_counter_overflow(struct idxd_device *idxd); 72281dd4d4dSTom Zanussi void perfmon_init(void); 72381dd4d4dSTom Zanussi void perfmon_exit(void); 72481dd4d4dSTom Zanussi #else 72581dd4d4dSTom Zanussi static inline int perfmon_pmu_init(struct idxd_device *idxd) { return 0; } 72681dd4d4dSTom Zanussi static inline void perfmon_pmu_remove(struct idxd_device *idxd) {} 72781dd4d4dSTom Zanussi static inline void perfmon_counter_overflow(struct idxd_device *idxd) {} 72881dd4d4dSTom Zanussi static inline void perfmon_init(void) {} 72981dd4d4dSTom Zanussi static inline void perfmon_exit(void) {} 73081dd4d4dSTom Zanussi #endif 73181dd4d4dSTom Zanussi 7325fbe6503SDave Jiang /* debugfs */ 7335fbe6503SDave Jiang int idxd_device_init_debugfs(struct idxd_device *idxd); 7345fbe6503SDave Jiang void idxd_device_remove_debugfs(struct idxd_device *idxd); 7355fbe6503SDave Jiang int idxd_init_debugfs(void); 7365fbe6503SDave Jiang void idxd_remove_debugfs(void); 7375fbe6503SDave Jiang 738bfe1d560SDave Jiang #endif 739