162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* Copyright(c) 2019 Intel Corporation. All rights rsvd. */ 362306a36Sopenharmony_ci#ifndef _IDXD_H_ 462306a36Sopenharmony_ci#define _IDXD_H_ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/sbitmap.h> 762306a36Sopenharmony_ci#include <linux/dmaengine.h> 862306a36Sopenharmony_ci#include <linux/percpu-rwsem.h> 962306a36Sopenharmony_ci#include <linux/wait.h> 1062306a36Sopenharmony_ci#include <linux/cdev.h> 1162306a36Sopenharmony_ci#include <linux/idr.h> 1262306a36Sopenharmony_ci#include <linux/pci.h> 1362306a36Sopenharmony_ci#include <linux/bitmap.h> 1462306a36Sopenharmony_ci#include <linux/perf_event.h> 1562306a36Sopenharmony_ci#include <linux/iommu.h> 1662306a36Sopenharmony_ci#include <uapi/linux/idxd.h> 1762306a36Sopenharmony_ci#include "registers.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define IDXD_DRIVER_VERSION "1.00" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciextern struct kmem_cache *idxd_desc_pool; 2262306a36Sopenharmony_ciextern bool tc_override; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistruct idxd_wq; 2562306a36Sopenharmony_cistruct idxd_dev; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cienum idxd_dev_type { 2862306a36Sopenharmony_ci IDXD_DEV_NONE = -1, 2962306a36Sopenharmony_ci IDXD_DEV_DSA = 0, 3062306a36Sopenharmony_ci IDXD_DEV_IAX, 3162306a36Sopenharmony_ci IDXD_DEV_WQ, 3262306a36Sopenharmony_ci IDXD_DEV_GROUP, 3362306a36Sopenharmony_ci IDXD_DEV_ENGINE, 3462306a36Sopenharmony_ci IDXD_DEV_CDEV, 3562306a36Sopenharmony_ci IDXD_DEV_CDEV_FILE, 3662306a36Sopenharmony_ci IDXD_DEV_MAX_TYPE, 3762306a36Sopenharmony_ci}; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistruct idxd_dev { 4062306a36Sopenharmony_ci struct device conf_dev; 4162306a36Sopenharmony_ci enum idxd_dev_type type; 4262306a36Sopenharmony_ci}; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#define IDXD_REG_TIMEOUT 50 4562306a36Sopenharmony_ci#define IDXD_DRAIN_TIMEOUT 5000 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cienum idxd_type { 4862306a36Sopenharmony_ci IDXD_TYPE_UNKNOWN = -1, 4962306a36Sopenharmony_ci IDXD_TYPE_DSA = 0, 5062306a36Sopenharmony_ci IDXD_TYPE_IAX, 5162306a36Sopenharmony_ci IDXD_TYPE_MAX, 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#define IDXD_NAME_SIZE 128 5562306a36Sopenharmony_ci#define IDXD_PMU_EVENT_MAX 64 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci#define IDXD_ENQCMDS_RETRIES 32 5862306a36Sopenharmony_ci#define IDXD_ENQCMDS_MAX_RETRIES 64 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistruct idxd_device_driver { 6162306a36Sopenharmony_ci const char *name; 6262306a36Sopenharmony_ci enum idxd_dev_type *type; 6362306a36Sopenharmony_ci int (*probe)(struct idxd_dev *idxd_dev); 6462306a36Sopenharmony_ci void (*remove)(struct idxd_dev *idxd_dev); 6562306a36Sopenharmony_ci struct device_driver drv; 6662306a36Sopenharmony_ci}; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ciextern struct idxd_device_driver dsa_drv; 6962306a36Sopenharmony_ciextern struct idxd_device_driver idxd_drv; 7062306a36Sopenharmony_ciextern struct idxd_device_driver idxd_dmaengine_drv; 7162306a36Sopenharmony_ciextern struct idxd_device_driver idxd_user_drv; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#define INVALID_INT_HANDLE -1 7462306a36Sopenharmony_cistruct idxd_irq_entry { 7562306a36Sopenharmony_ci int id; 7662306a36Sopenharmony_ci int vector; 7762306a36Sopenharmony_ci struct llist_head pending_llist; 7862306a36Sopenharmony_ci struct list_head work_list; 7962306a36Sopenharmony_ci /* 8062306a36Sopenharmony_ci * Lock to protect access between irq thread process descriptor 8162306a36Sopenharmony_ci * and irq thread processing error descriptor. 8262306a36Sopenharmony_ci */ 8362306a36Sopenharmony_ci spinlock_t list_lock; 8462306a36Sopenharmony_ci int int_handle; 8562306a36Sopenharmony_ci ioasid_t pasid; 8662306a36Sopenharmony_ci}; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistruct idxd_group { 8962306a36Sopenharmony_ci struct idxd_dev idxd_dev; 9062306a36Sopenharmony_ci struct idxd_device *idxd; 9162306a36Sopenharmony_ci struct grpcfg grpcfg; 9262306a36Sopenharmony_ci int id; 9362306a36Sopenharmony_ci int num_engines; 9462306a36Sopenharmony_ci int num_wqs; 9562306a36Sopenharmony_ci bool use_rdbuf_limit; 9662306a36Sopenharmony_ci u8 rdbufs_allowed; 9762306a36Sopenharmony_ci u8 rdbufs_reserved; 9862306a36Sopenharmony_ci int tc_a; 9962306a36Sopenharmony_ci int tc_b; 10062306a36Sopenharmony_ci int desc_progress_limit; 10162306a36Sopenharmony_ci int batch_progress_limit; 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistruct idxd_pmu { 10562306a36Sopenharmony_ci struct idxd_device *idxd; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci struct perf_event *event_list[IDXD_PMU_EVENT_MAX]; 10862306a36Sopenharmony_ci int n_events; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci DECLARE_BITMAP(used_mask, IDXD_PMU_EVENT_MAX); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci struct pmu pmu; 11362306a36Sopenharmony_ci char name[IDXD_NAME_SIZE]; 11462306a36Sopenharmony_ci int cpu; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci int n_counters; 11762306a36Sopenharmony_ci int counter_width; 11862306a36Sopenharmony_ci int n_event_categories; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci bool per_counter_caps_supported; 12162306a36Sopenharmony_ci unsigned long supported_event_categories; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci unsigned long supported_filters; 12462306a36Sopenharmony_ci int n_filters; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci struct hlist_node cpuhp_node; 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#define IDXD_MAX_PRIORITY 0xf 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cienum { 13262306a36Sopenharmony_ci COUNTER_FAULTS = 0, 13362306a36Sopenharmony_ci COUNTER_FAULT_FAILS, 13462306a36Sopenharmony_ci COUNTER_MAX 13562306a36Sopenharmony_ci}; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cienum idxd_wq_state { 13862306a36Sopenharmony_ci IDXD_WQ_DISABLED = 0, 13962306a36Sopenharmony_ci IDXD_WQ_ENABLED, 14062306a36Sopenharmony_ci}; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cienum idxd_wq_flag { 14362306a36Sopenharmony_ci WQ_FLAG_DEDICATED = 0, 14462306a36Sopenharmony_ci WQ_FLAG_BLOCK_ON_FAULT, 14562306a36Sopenharmony_ci WQ_FLAG_ATS_DISABLE, 14662306a36Sopenharmony_ci WQ_FLAG_PRS_DISABLE, 14762306a36Sopenharmony_ci}; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cienum idxd_wq_type { 15062306a36Sopenharmony_ci IDXD_WQT_NONE = 0, 15162306a36Sopenharmony_ci IDXD_WQT_KERNEL, 15262306a36Sopenharmony_ci IDXD_WQT_USER, 15362306a36Sopenharmony_ci}; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistruct idxd_cdev { 15662306a36Sopenharmony_ci struct idxd_wq *wq; 15762306a36Sopenharmony_ci struct cdev cdev; 15862306a36Sopenharmony_ci struct idxd_dev idxd_dev; 15962306a36Sopenharmony_ci int minor; 16062306a36Sopenharmony_ci}; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci#define IDXD_ALLOCATED_BATCH_SIZE 128U 16362306a36Sopenharmony_ci#define WQ_NAME_SIZE 1024 16462306a36Sopenharmony_ci#define WQ_TYPE_SIZE 10 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci#define WQ_DEFAULT_QUEUE_DEPTH 16 16762306a36Sopenharmony_ci#define WQ_DEFAULT_MAX_XFER SZ_2M 16862306a36Sopenharmony_ci#define WQ_DEFAULT_MAX_BATCH 32 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cienum idxd_op_type { 17162306a36Sopenharmony_ci IDXD_OP_BLOCK = 0, 17262306a36Sopenharmony_ci IDXD_OP_NONBLOCK = 1, 17362306a36Sopenharmony_ci}; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cienum idxd_complete_type { 17662306a36Sopenharmony_ci IDXD_COMPLETE_NORMAL = 0, 17762306a36Sopenharmony_ci IDXD_COMPLETE_ABORT, 17862306a36Sopenharmony_ci IDXD_COMPLETE_DEV_FAIL, 17962306a36Sopenharmony_ci}; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistruct idxd_dma_chan { 18262306a36Sopenharmony_ci struct dma_chan chan; 18362306a36Sopenharmony_ci struct idxd_wq *wq; 18462306a36Sopenharmony_ci}; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistruct idxd_wq { 18762306a36Sopenharmony_ci void __iomem *portal; 18862306a36Sopenharmony_ci u32 portal_offset; 18962306a36Sopenharmony_ci unsigned int enqcmds_retries; 19062306a36Sopenharmony_ci struct percpu_ref wq_active; 19162306a36Sopenharmony_ci struct completion wq_dead; 19262306a36Sopenharmony_ci struct completion wq_resurrect; 19362306a36Sopenharmony_ci struct idxd_dev idxd_dev; 19462306a36Sopenharmony_ci struct idxd_cdev *idxd_cdev; 19562306a36Sopenharmony_ci struct wait_queue_head err_queue; 19662306a36Sopenharmony_ci struct workqueue_struct *wq; 19762306a36Sopenharmony_ci struct idxd_device *idxd; 19862306a36Sopenharmony_ci int id; 19962306a36Sopenharmony_ci struct idxd_irq_entry ie; 20062306a36Sopenharmony_ci enum idxd_wq_type type; 20162306a36Sopenharmony_ci struct idxd_group *group; 20262306a36Sopenharmony_ci int client_count; 20362306a36Sopenharmony_ci struct mutex wq_lock; /* mutex for workqueue */ 20462306a36Sopenharmony_ci u32 size; 20562306a36Sopenharmony_ci u32 threshold; 20662306a36Sopenharmony_ci u32 priority; 20762306a36Sopenharmony_ci enum idxd_wq_state state; 20862306a36Sopenharmony_ci unsigned long flags; 20962306a36Sopenharmony_ci union wqcfg *wqcfg; 21062306a36Sopenharmony_ci unsigned long *opcap_bmap; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci struct dsa_hw_desc **hw_descs; 21362306a36Sopenharmony_ci int num_descs; 21462306a36Sopenharmony_ci union { 21562306a36Sopenharmony_ci struct dsa_completion_record *compls; 21662306a36Sopenharmony_ci struct iax_completion_record *iax_compls; 21762306a36Sopenharmony_ci }; 21862306a36Sopenharmony_ci dma_addr_t compls_addr; 21962306a36Sopenharmony_ci int compls_size; 22062306a36Sopenharmony_ci struct idxd_desc **descs; 22162306a36Sopenharmony_ci struct sbitmap_queue sbq; 22262306a36Sopenharmony_ci struct idxd_dma_chan *idxd_chan; 22362306a36Sopenharmony_ci char name[WQ_NAME_SIZE + 1]; 22462306a36Sopenharmony_ci u64 max_xfer_bytes; 22562306a36Sopenharmony_ci u32 max_batch_size; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci /* Lock to protect upasid_xa access. */ 22862306a36Sopenharmony_ci struct mutex uc_lock; 22962306a36Sopenharmony_ci struct xarray upasid_xa; 23062306a36Sopenharmony_ci}; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_cistruct idxd_engine { 23362306a36Sopenharmony_ci struct idxd_dev idxd_dev; 23462306a36Sopenharmony_ci int id; 23562306a36Sopenharmony_ci struct idxd_group *group; 23662306a36Sopenharmony_ci struct idxd_device *idxd; 23762306a36Sopenharmony_ci}; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci/* shadow registers */ 24062306a36Sopenharmony_cistruct idxd_hw { 24162306a36Sopenharmony_ci u32 version; 24262306a36Sopenharmony_ci union gen_cap_reg gen_cap; 24362306a36Sopenharmony_ci union wq_cap_reg wq_cap; 24462306a36Sopenharmony_ci union group_cap_reg group_cap; 24562306a36Sopenharmony_ci union engine_cap_reg engine_cap; 24662306a36Sopenharmony_ci struct opcap opcap; 24762306a36Sopenharmony_ci u32 cmd_cap; 24862306a36Sopenharmony_ci union iaa_cap_reg iaa_cap; 24962306a36Sopenharmony_ci}; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cienum idxd_device_state { 25262306a36Sopenharmony_ci IDXD_DEV_HALTED = -1, 25362306a36Sopenharmony_ci IDXD_DEV_DISABLED = 0, 25462306a36Sopenharmony_ci IDXD_DEV_ENABLED, 25562306a36Sopenharmony_ci}; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cienum idxd_device_flag { 25862306a36Sopenharmony_ci IDXD_FLAG_CONFIGURABLE = 0, 25962306a36Sopenharmony_ci IDXD_FLAG_CMD_RUNNING, 26062306a36Sopenharmony_ci IDXD_FLAG_PASID_ENABLED, 26162306a36Sopenharmony_ci IDXD_FLAG_USER_PASID_ENABLED, 26262306a36Sopenharmony_ci}; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cistruct idxd_dma_dev { 26562306a36Sopenharmony_ci struct idxd_device *idxd; 26662306a36Sopenharmony_ci struct dma_device dma; 26762306a36Sopenharmony_ci}; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_cistruct idxd_driver_data { 27062306a36Sopenharmony_ci const char *name_prefix; 27162306a36Sopenharmony_ci enum idxd_type type; 27262306a36Sopenharmony_ci struct device_type *dev_type; 27362306a36Sopenharmony_ci int compl_size; 27462306a36Sopenharmony_ci int align; 27562306a36Sopenharmony_ci int evl_cr_off; 27662306a36Sopenharmony_ci int cr_status_off; 27762306a36Sopenharmony_ci int cr_result_off; 27862306a36Sopenharmony_ci}; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_cistruct idxd_evl { 28162306a36Sopenharmony_ci /* Lock to protect event log access. */ 28262306a36Sopenharmony_ci spinlock_t lock; 28362306a36Sopenharmony_ci void *log; 28462306a36Sopenharmony_ci dma_addr_t dma; 28562306a36Sopenharmony_ci /* Total size of event log = number of entries * entry size. */ 28662306a36Sopenharmony_ci unsigned int log_size; 28762306a36Sopenharmony_ci /* The number of entries in the event log. */ 28862306a36Sopenharmony_ci u16 size; 28962306a36Sopenharmony_ci unsigned long *bmap; 29062306a36Sopenharmony_ci bool batch_fail[IDXD_MAX_BATCH_IDENT]; 29162306a36Sopenharmony_ci}; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_cistruct idxd_evl_fault { 29462306a36Sopenharmony_ci struct work_struct work; 29562306a36Sopenharmony_ci struct idxd_wq *wq; 29662306a36Sopenharmony_ci u8 status; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci /* make this last member always */ 29962306a36Sopenharmony_ci struct __evl_entry entry[]; 30062306a36Sopenharmony_ci}; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_cistruct idxd_device { 30362306a36Sopenharmony_ci struct idxd_dev idxd_dev; 30462306a36Sopenharmony_ci struct idxd_driver_data *data; 30562306a36Sopenharmony_ci struct list_head list; 30662306a36Sopenharmony_ci struct idxd_hw hw; 30762306a36Sopenharmony_ci enum idxd_device_state state; 30862306a36Sopenharmony_ci unsigned long flags; 30962306a36Sopenharmony_ci int id; 31062306a36Sopenharmony_ci int major; 31162306a36Sopenharmony_ci u32 cmd_status; 31262306a36Sopenharmony_ci struct idxd_irq_entry ie; /* misc irq, msix 0 */ 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci struct pci_dev *pdev; 31562306a36Sopenharmony_ci void __iomem *reg_base; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci spinlock_t dev_lock; /* spinlock for device */ 31862306a36Sopenharmony_ci spinlock_t cmd_lock; /* spinlock for device commands */ 31962306a36Sopenharmony_ci struct completion *cmd_done; 32062306a36Sopenharmony_ci struct idxd_group **groups; 32162306a36Sopenharmony_ci struct idxd_wq **wqs; 32262306a36Sopenharmony_ci struct idxd_engine **engines; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci struct iommu_sva *sva; 32562306a36Sopenharmony_ci unsigned int pasid; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci int num_groups; 32862306a36Sopenharmony_ci int irq_cnt; 32962306a36Sopenharmony_ci bool request_int_handles; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci u32 msix_perm_offset; 33262306a36Sopenharmony_ci u32 wqcfg_offset; 33362306a36Sopenharmony_ci u32 grpcfg_offset; 33462306a36Sopenharmony_ci u32 perfmon_offset; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci u64 max_xfer_bytes; 33762306a36Sopenharmony_ci u32 max_batch_size; 33862306a36Sopenharmony_ci int max_groups; 33962306a36Sopenharmony_ci int max_engines; 34062306a36Sopenharmony_ci int max_rdbufs; 34162306a36Sopenharmony_ci int max_wqs; 34262306a36Sopenharmony_ci int max_wq_size; 34362306a36Sopenharmony_ci int rdbuf_limit; 34462306a36Sopenharmony_ci int nr_rdbufs; /* non-reserved read buffers */ 34562306a36Sopenharmony_ci unsigned int wqcfg_size; 34662306a36Sopenharmony_ci unsigned long *wq_enable_map; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci union sw_err_reg sw_err; 34962306a36Sopenharmony_ci wait_queue_head_t cmd_waitq; 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci struct idxd_dma_dev *idxd_dma; 35262306a36Sopenharmony_ci struct workqueue_struct *wq; 35362306a36Sopenharmony_ci struct work_struct work; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci struct idxd_pmu *idxd_pmu; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci unsigned long *opcap_bmap; 35862306a36Sopenharmony_ci struct idxd_evl *evl; 35962306a36Sopenharmony_ci struct kmem_cache *evl_cache; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci struct dentry *dbgfs_dir; 36262306a36Sopenharmony_ci struct dentry *dbgfs_evl_file; 36362306a36Sopenharmony_ci}; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_cistatic inline unsigned int evl_ent_size(struct idxd_device *idxd) 36662306a36Sopenharmony_ci{ 36762306a36Sopenharmony_ci return idxd->hw.gen_cap.evl_support ? 36862306a36Sopenharmony_ci (32 * (1 << idxd->hw.gen_cap.evl_support)) : 0; 36962306a36Sopenharmony_ci} 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_cistatic inline unsigned int evl_size(struct idxd_device *idxd) 37262306a36Sopenharmony_ci{ 37362306a36Sopenharmony_ci return idxd->evl->size * evl_ent_size(idxd); 37462306a36Sopenharmony_ci} 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci/* IDXD software descriptor */ 37762306a36Sopenharmony_cistruct idxd_desc { 37862306a36Sopenharmony_ci union { 37962306a36Sopenharmony_ci struct dsa_hw_desc *hw; 38062306a36Sopenharmony_ci struct iax_hw_desc *iax_hw; 38162306a36Sopenharmony_ci }; 38262306a36Sopenharmony_ci dma_addr_t desc_dma; 38362306a36Sopenharmony_ci union { 38462306a36Sopenharmony_ci struct dsa_completion_record *completion; 38562306a36Sopenharmony_ci struct iax_completion_record *iax_completion; 38662306a36Sopenharmony_ci }; 38762306a36Sopenharmony_ci dma_addr_t compl_dma; 38862306a36Sopenharmony_ci struct dma_async_tx_descriptor txd; 38962306a36Sopenharmony_ci struct llist_node llnode; 39062306a36Sopenharmony_ci struct list_head list; 39162306a36Sopenharmony_ci int id; 39262306a36Sopenharmony_ci int cpu; 39362306a36Sopenharmony_ci struct idxd_wq *wq; 39462306a36Sopenharmony_ci}; 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci/* 39762306a36Sopenharmony_ci * This is software defined error for the completion status. We overload the error code 39862306a36Sopenharmony_ci * that will never appear in completion status and only SWERR register. 39962306a36Sopenharmony_ci */ 40062306a36Sopenharmony_cienum idxd_completion_status { 40162306a36Sopenharmony_ci IDXD_COMP_DESC_ABORT = 0xff, 40262306a36Sopenharmony_ci}; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci#define idxd_confdev(idxd) &idxd->idxd_dev.conf_dev 40562306a36Sopenharmony_ci#define wq_confdev(wq) &wq->idxd_dev.conf_dev 40662306a36Sopenharmony_ci#define engine_confdev(engine) &engine->idxd_dev.conf_dev 40762306a36Sopenharmony_ci#define group_confdev(group) &group->idxd_dev.conf_dev 40862306a36Sopenharmony_ci#define cdev_dev(cdev) &cdev->idxd_dev.conf_dev 40962306a36Sopenharmony_ci#define user_ctx_dev(ctx) (&(ctx)->idxd_dev.conf_dev) 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci#define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev) 41262306a36Sopenharmony_ci#define idxd_dev_to_idxd(idxd_dev) container_of(idxd_dev, struct idxd_device, idxd_dev) 41362306a36Sopenharmony_ci#define idxd_dev_to_wq(idxd_dev) container_of(idxd_dev, struct idxd_wq, idxd_dev) 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_cistatic inline struct idxd_device *confdev_to_idxd(struct device *dev) 41662306a36Sopenharmony_ci{ 41762306a36Sopenharmony_ci struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci return idxd_dev_to_idxd(idxd_dev); 42062306a36Sopenharmony_ci} 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_cistatic inline struct idxd_wq *confdev_to_wq(struct device *dev) 42362306a36Sopenharmony_ci{ 42462306a36Sopenharmony_ci struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci return idxd_dev_to_wq(idxd_dev); 42762306a36Sopenharmony_ci} 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_cistatic inline struct idxd_engine *confdev_to_engine(struct device *dev) 43062306a36Sopenharmony_ci{ 43162306a36Sopenharmony_ci struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci return container_of(idxd_dev, struct idxd_engine, idxd_dev); 43462306a36Sopenharmony_ci} 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_cistatic inline struct idxd_group *confdev_to_group(struct device *dev) 43762306a36Sopenharmony_ci{ 43862306a36Sopenharmony_ci struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci return container_of(idxd_dev, struct idxd_group, idxd_dev); 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_cistatic inline struct idxd_cdev *dev_to_cdev(struct device *dev) 44462306a36Sopenharmony_ci{ 44562306a36Sopenharmony_ci struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci return container_of(idxd_dev, struct idxd_cdev, idxd_dev); 44862306a36Sopenharmony_ci} 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_cistatic inline void idxd_dev_set_type(struct idxd_dev *idev, int type) 45162306a36Sopenharmony_ci{ 45262306a36Sopenharmony_ci if (type >= IDXD_DEV_MAX_TYPE) { 45362306a36Sopenharmony_ci idev->type = IDXD_DEV_NONE; 45462306a36Sopenharmony_ci return; 45562306a36Sopenharmony_ci } 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci idev->type = type; 45862306a36Sopenharmony_ci} 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_cistatic inline struct idxd_irq_entry *idxd_get_ie(struct idxd_device *idxd, int idx) 46162306a36Sopenharmony_ci{ 46262306a36Sopenharmony_ci return (idx == 0) ? &idxd->ie : &idxd->wqs[idx - 1]->ie; 46362306a36Sopenharmony_ci} 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_cistatic inline struct idxd_wq *ie_to_wq(struct idxd_irq_entry *ie) 46662306a36Sopenharmony_ci{ 46762306a36Sopenharmony_ci return container_of(ie, struct idxd_wq, ie); 46862306a36Sopenharmony_ci} 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_cistatic inline struct idxd_device *ie_to_idxd(struct idxd_irq_entry *ie) 47162306a36Sopenharmony_ci{ 47262306a36Sopenharmony_ci return container_of(ie, struct idxd_device, ie); 47362306a36Sopenharmony_ci} 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_cistatic inline void idxd_set_user_intr(struct idxd_device *idxd, bool enable) 47662306a36Sopenharmony_ci{ 47762306a36Sopenharmony_ci union gencfg_reg reg; 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci reg.bits = ioread32(idxd->reg_base + IDXD_GENCFG_OFFSET); 48062306a36Sopenharmony_ci reg.user_int_en = enable; 48162306a36Sopenharmony_ci iowrite32(reg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET); 48262306a36Sopenharmony_ci} 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ciextern struct bus_type dsa_bus_type; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ciextern bool support_enqcmd; 48762306a36Sopenharmony_ciextern struct ida idxd_ida; 48862306a36Sopenharmony_ciextern struct device_type dsa_device_type; 48962306a36Sopenharmony_ciextern struct device_type iax_device_type; 49062306a36Sopenharmony_ciextern struct device_type idxd_wq_device_type; 49162306a36Sopenharmony_ciextern struct device_type idxd_engine_device_type; 49262306a36Sopenharmony_ciextern struct device_type idxd_group_device_type; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_cistatic inline bool is_dsa_dev(struct idxd_dev *idxd_dev) 49562306a36Sopenharmony_ci{ 49662306a36Sopenharmony_ci return idxd_dev->type == IDXD_DEV_DSA; 49762306a36Sopenharmony_ci} 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_cistatic inline bool is_iax_dev(struct idxd_dev *idxd_dev) 50062306a36Sopenharmony_ci{ 50162306a36Sopenharmony_ci return idxd_dev->type == IDXD_DEV_IAX; 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_cistatic inline bool is_idxd_dev(struct idxd_dev *idxd_dev) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci return is_dsa_dev(idxd_dev) || is_iax_dev(idxd_dev); 50762306a36Sopenharmony_ci} 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_cistatic inline bool is_idxd_wq_dev(struct idxd_dev *idxd_dev) 51062306a36Sopenharmony_ci{ 51162306a36Sopenharmony_ci return idxd_dev->type == IDXD_DEV_WQ; 51262306a36Sopenharmony_ci} 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_cistatic inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq) 51562306a36Sopenharmony_ci{ 51662306a36Sopenharmony_ci if (wq->type == IDXD_WQT_KERNEL && strcmp(wq->name, "dmaengine") == 0) 51762306a36Sopenharmony_ci return true; 51862306a36Sopenharmony_ci return false; 51962306a36Sopenharmony_ci} 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_cistatic inline bool is_idxd_wq_user(struct idxd_wq *wq) 52262306a36Sopenharmony_ci{ 52362306a36Sopenharmony_ci return wq->type == IDXD_WQT_USER; 52462306a36Sopenharmony_ci} 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_cistatic inline bool is_idxd_wq_kernel(struct idxd_wq *wq) 52762306a36Sopenharmony_ci{ 52862306a36Sopenharmony_ci return wq->type == IDXD_WQT_KERNEL; 52962306a36Sopenharmony_ci} 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_cistatic inline bool wq_dedicated(struct idxd_wq *wq) 53262306a36Sopenharmony_ci{ 53362306a36Sopenharmony_ci return test_bit(WQ_FLAG_DEDICATED, &wq->flags); 53462306a36Sopenharmony_ci} 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistatic inline bool wq_shared(struct idxd_wq *wq) 53762306a36Sopenharmony_ci{ 53862306a36Sopenharmony_ci return !test_bit(WQ_FLAG_DEDICATED, &wq->flags); 53962306a36Sopenharmony_ci} 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_cistatic inline bool device_pasid_enabled(struct idxd_device *idxd) 54262306a36Sopenharmony_ci{ 54362306a36Sopenharmony_ci return test_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags); 54462306a36Sopenharmony_ci} 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_cistatic inline bool device_user_pasid_enabled(struct idxd_device *idxd) 54762306a36Sopenharmony_ci{ 54862306a36Sopenharmony_ci return test_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags); 54962306a36Sopenharmony_ci} 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_cistatic inline bool wq_pasid_enabled(struct idxd_wq *wq) 55262306a36Sopenharmony_ci{ 55362306a36Sopenharmony_ci return (is_idxd_wq_kernel(wq) && device_pasid_enabled(wq->idxd)) || 55462306a36Sopenharmony_ci (is_idxd_wq_user(wq) && device_user_pasid_enabled(wq->idxd)); 55562306a36Sopenharmony_ci} 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_cistatic inline bool wq_shared_supported(struct idxd_wq *wq) 55862306a36Sopenharmony_ci{ 55962306a36Sopenharmony_ci return (support_enqcmd && wq_pasid_enabled(wq)); 56062306a36Sopenharmony_ci} 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_cienum idxd_portal_prot { 56362306a36Sopenharmony_ci IDXD_PORTAL_UNLIMITED = 0, 56462306a36Sopenharmony_ci IDXD_PORTAL_LIMITED, 56562306a36Sopenharmony_ci}; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_cienum idxd_interrupt_type { 56862306a36Sopenharmony_ci IDXD_IRQ_MSIX = 0, 56962306a36Sopenharmony_ci IDXD_IRQ_IMS, 57062306a36Sopenharmony_ci}; 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_cistatic inline int idxd_get_wq_portal_offset(enum idxd_portal_prot prot) 57362306a36Sopenharmony_ci{ 57462306a36Sopenharmony_ci return prot * 0x1000; 57562306a36Sopenharmony_ci} 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_cistatic inline int idxd_get_wq_portal_full_offset(int wq_id, 57862306a36Sopenharmony_ci enum idxd_portal_prot prot) 57962306a36Sopenharmony_ci{ 58062306a36Sopenharmony_ci return ((wq_id * 4) << PAGE_SHIFT) + idxd_get_wq_portal_offset(prot); 58162306a36Sopenharmony_ci} 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci#define IDXD_PORTAL_MASK (PAGE_SIZE - 1) 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci/* 58662306a36Sopenharmony_ci * Even though this function can be accessed by multiple threads, it is safe to use. 58762306a36Sopenharmony_ci * At worst the address gets used more than once before it gets incremented. We don't 58862306a36Sopenharmony_ci * hit a threshold until iops becomes many million times a second. So the occasional 58962306a36Sopenharmony_ci * reuse of the same address is tolerable compare to using an atomic variable. This is 59062306a36Sopenharmony_ci * safe on a system that has atomic load/store for 32bit integers. Given that this is an 59162306a36Sopenharmony_ci * Intel iEP device, that should not be a problem. 59262306a36Sopenharmony_ci */ 59362306a36Sopenharmony_cistatic inline void __iomem *idxd_wq_portal_addr(struct idxd_wq *wq) 59462306a36Sopenharmony_ci{ 59562306a36Sopenharmony_ci int ofs = wq->portal_offset; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci wq->portal_offset = (ofs + sizeof(struct dsa_raw_desc)) & IDXD_PORTAL_MASK; 59862306a36Sopenharmony_ci return wq->portal + ofs; 59962306a36Sopenharmony_ci} 60062306a36Sopenharmony_ci 60162306a36Sopenharmony_cistatic inline void idxd_wq_get(struct idxd_wq *wq) 60262306a36Sopenharmony_ci{ 60362306a36Sopenharmony_ci wq->client_count++; 60462306a36Sopenharmony_ci} 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_cistatic inline void idxd_wq_put(struct idxd_wq *wq) 60762306a36Sopenharmony_ci{ 60862306a36Sopenharmony_ci wq->client_count--; 60962306a36Sopenharmony_ci} 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_cistatic inline int idxd_wq_refcount(struct idxd_wq *wq) 61262306a36Sopenharmony_ci{ 61362306a36Sopenharmony_ci return wq->client_count; 61462306a36Sopenharmony_ci}; 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci/* 61762306a36Sopenharmony_ci * Intel IAA does not support batch processing. 61862306a36Sopenharmony_ci * The max batch size of device, max batch size of wq and 61962306a36Sopenharmony_ci * max batch shift of wqcfg should be always 0 on IAA. 62062306a36Sopenharmony_ci */ 62162306a36Sopenharmony_cistatic inline void idxd_set_max_batch_size(int idxd_type, struct idxd_device *idxd, 62262306a36Sopenharmony_ci u32 max_batch_size) 62362306a36Sopenharmony_ci{ 62462306a36Sopenharmony_ci if (idxd_type == IDXD_TYPE_IAX) 62562306a36Sopenharmony_ci idxd->max_batch_size = 0; 62662306a36Sopenharmony_ci else 62762306a36Sopenharmony_ci idxd->max_batch_size = max_batch_size; 62862306a36Sopenharmony_ci} 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_cistatic inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq, 63162306a36Sopenharmony_ci u32 max_batch_size) 63262306a36Sopenharmony_ci{ 63362306a36Sopenharmony_ci if (idxd_type == IDXD_TYPE_IAX) 63462306a36Sopenharmony_ci wq->max_batch_size = 0; 63562306a36Sopenharmony_ci else 63662306a36Sopenharmony_ci wq->max_batch_size = max_batch_size; 63762306a36Sopenharmony_ci} 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_cistatic inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg, 64062306a36Sopenharmony_ci u32 max_batch_shift) 64162306a36Sopenharmony_ci{ 64262306a36Sopenharmony_ci if (idxd_type == IDXD_TYPE_IAX) 64362306a36Sopenharmony_ci wqcfg->max_batch_shift = 0; 64462306a36Sopenharmony_ci else 64562306a36Sopenharmony_ci wqcfg->max_batch_shift = max_batch_shift; 64662306a36Sopenharmony_ci} 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ciint __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv, 64962306a36Sopenharmony_ci struct module *module, const char *mod_name); 65062306a36Sopenharmony_ci#define idxd_driver_register(driver) \ 65162306a36Sopenharmony_ci __idxd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_civoid idxd_driver_unregister(struct idxd_device_driver *idxd_drv); 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci#define module_idxd_driver(__idxd_driver) \ 65662306a36Sopenharmony_ci module_driver(__idxd_driver, idxd_driver_register, idxd_driver_unregister) 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ciint idxd_register_bus_type(void); 65962306a36Sopenharmony_civoid idxd_unregister_bus_type(void); 66062306a36Sopenharmony_ciint idxd_register_devices(struct idxd_device *idxd); 66162306a36Sopenharmony_civoid idxd_unregister_devices(struct idxd_device *idxd); 66262306a36Sopenharmony_civoid idxd_wqs_quiesce(struct idxd_device *idxd); 66362306a36Sopenharmony_cibool idxd_queue_int_handle_resubmit(struct idxd_desc *desc); 66462306a36Sopenharmony_civoid multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count); 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci/* device interrupt control */ 66762306a36Sopenharmony_ciirqreturn_t idxd_misc_thread(int vec, void *data); 66862306a36Sopenharmony_ciirqreturn_t idxd_wq_thread(int irq, void *data); 66962306a36Sopenharmony_civoid idxd_mask_error_interrupts(struct idxd_device *idxd); 67062306a36Sopenharmony_civoid idxd_unmask_error_interrupts(struct idxd_device *idxd); 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci/* device control */ 67362306a36Sopenharmony_ciint idxd_device_drv_probe(struct idxd_dev *idxd_dev); 67462306a36Sopenharmony_civoid idxd_device_drv_remove(struct idxd_dev *idxd_dev); 67562306a36Sopenharmony_ciint drv_enable_wq(struct idxd_wq *wq); 67662306a36Sopenharmony_civoid drv_disable_wq(struct idxd_wq *wq); 67762306a36Sopenharmony_ciint idxd_device_init_reset(struct idxd_device *idxd); 67862306a36Sopenharmony_ciint idxd_device_enable(struct idxd_device *idxd); 67962306a36Sopenharmony_ciint idxd_device_disable(struct idxd_device *idxd); 68062306a36Sopenharmony_civoid idxd_device_reset(struct idxd_device *idxd); 68162306a36Sopenharmony_civoid idxd_device_clear_state(struct idxd_device *idxd); 68262306a36Sopenharmony_ciint idxd_device_config(struct idxd_device *idxd); 68362306a36Sopenharmony_civoid idxd_device_drain_pasid(struct idxd_device *idxd, int pasid); 68462306a36Sopenharmony_ciint idxd_device_load_config(struct idxd_device *idxd); 68562306a36Sopenharmony_ciint idxd_device_request_int_handle(struct idxd_device *idxd, int idx, int *handle, 68662306a36Sopenharmony_ci enum idxd_interrupt_type irq_type); 68762306a36Sopenharmony_ciint idxd_device_release_int_handle(struct idxd_device *idxd, int handle, 68862306a36Sopenharmony_ci enum idxd_interrupt_type irq_type); 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci/* work queue control */ 69162306a36Sopenharmony_civoid idxd_wqs_unmap_portal(struct idxd_device *idxd); 69262306a36Sopenharmony_ciint idxd_wq_alloc_resources(struct idxd_wq *wq); 69362306a36Sopenharmony_civoid idxd_wq_free_resources(struct idxd_wq *wq); 69462306a36Sopenharmony_ciint idxd_wq_enable(struct idxd_wq *wq); 69562306a36Sopenharmony_ciint idxd_wq_disable(struct idxd_wq *wq, bool reset_config); 69662306a36Sopenharmony_civoid idxd_wq_drain(struct idxd_wq *wq); 69762306a36Sopenharmony_civoid idxd_wq_reset(struct idxd_wq *wq); 69862306a36Sopenharmony_ciint idxd_wq_map_portal(struct idxd_wq *wq); 69962306a36Sopenharmony_civoid idxd_wq_unmap_portal(struct idxd_wq *wq); 70062306a36Sopenharmony_ciint idxd_wq_set_pasid(struct idxd_wq *wq, int pasid); 70162306a36Sopenharmony_ciint idxd_wq_disable_pasid(struct idxd_wq *wq); 70262306a36Sopenharmony_civoid __idxd_wq_quiesce(struct idxd_wq *wq); 70362306a36Sopenharmony_civoid idxd_wq_quiesce(struct idxd_wq *wq); 70462306a36Sopenharmony_ciint idxd_wq_init_percpu_ref(struct idxd_wq *wq); 70562306a36Sopenharmony_civoid idxd_wq_free_irq(struct idxd_wq *wq); 70662306a36Sopenharmony_ciint idxd_wq_request_irq(struct idxd_wq *wq); 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci/* submission */ 70962306a36Sopenharmony_ciint idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc); 71062306a36Sopenharmony_cistruct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype); 71162306a36Sopenharmony_civoid idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc); 71262306a36Sopenharmony_ciint idxd_enqcmds(struct idxd_wq *wq, void __iomem *portal, const void *desc); 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci/* dmaengine */ 71562306a36Sopenharmony_ciint idxd_register_dma_device(struct idxd_device *idxd); 71662306a36Sopenharmony_civoid idxd_unregister_dma_device(struct idxd_device *idxd); 71762306a36Sopenharmony_civoid idxd_dma_complete_txd(struct idxd_desc *desc, 71862306a36Sopenharmony_ci enum idxd_complete_type comp_type, bool free_desc); 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci/* cdev */ 72162306a36Sopenharmony_ciint idxd_cdev_register(void); 72262306a36Sopenharmony_civoid idxd_cdev_remove(void); 72362306a36Sopenharmony_ciint idxd_cdev_get_major(struct idxd_device *idxd); 72462306a36Sopenharmony_ciint idxd_wq_add_cdev(struct idxd_wq *wq); 72562306a36Sopenharmony_civoid idxd_wq_del_cdev(struct idxd_wq *wq); 72662306a36Sopenharmony_ciint idxd_copy_cr(struct idxd_wq *wq, ioasid_t pasid, unsigned long addr, 72762306a36Sopenharmony_ci void *buf, int len); 72862306a36Sopenharmony_civoid idxd_user_counter_increment(struct idxd_wq *wq, u32 pasid, int index); 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci/* perfmon */ 73162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_INTEL_IDXD_PERFMON) 73262306a36Sopenharmony_ciint perfmon_pmu_init(struct idxd_device *idxd); 73362306a36Sopenharmony_civoid perfmon_pmu_remove(struct idxd_device *idxd); 73462306a36Sopenharmony_civoid perfmon_counter_overflow(struct idxd_device *idxd); 73562306a36Sopenharmony_civoid perfmon_init(void); 73662306a36Sopenharmony_civoid perfmon_exit(void); 73762306a36Sopenharmony_ci#else 73862306a36Sopenharmony_cistatic inline int perfmon_pmu_init(struct idxd_device *idxd) { return 0; } 73962306a36Sopenharmony_cistatic inline void perfmon_pmu_remove(struct idxd_device *idxd) {} 74062306a36Sopenharmony_cistatic inline void perfmon_counter_overflow(struct idxd_device *idxd) {} 74162306a36Sopenharmony_cistatic inline void perfmon_init(void) {} 74262306a36Sopenharmony_cistatic inline void perfmon_exit(void) {} 74362306a36Sopenharmony_ci#endif 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci/* debugfs */ 74662306a36Sopenharmony_ciint idxd_device_init_debugfs(struct idxd_device *idxd); 74762306a36Sopenharmony_civoid idxd_device_remove_debugfs(struct idxd_device *idxd); 74862306a36Sopenharmony_ciint idxd_init_debugfs(void); 74962306a36Sopenharmony_civoid idxd_remove_debugfs(void); 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci#endif 752