1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+ 2*4882a593Smuzhiyun // Copyright 2017 IBM Corp. 3*4882a593Smuzhiyun #ifndef _MISC_OCXL_H_ 4*4882a593Smuzhiyun #define _MISC_OCXL_H_ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #include <linux/pci.h> 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun /* 9*4882a593Smuzhiyun * Opencapi drivers all need some common facilities, like parsing the 10*4882a593Smuzhiyun * device configuration space, adding a Process Element to the Shared 11*4882a593Smuzhiyun * Process Area, etc... 12*4882a593Smuzhiyun * 13*4882a593Smuzhiyun * The ocxl module provides a kernel API, to allow other drivers to 14*4882a593Smuzhiyun * reuse common code. A bit like a in-kernel library. 15*4882a593Smuzhiyun */ 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #define OCXL_AFU_NAME_SZ (24+1) /* add 1 for NULL termination */ 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun struct ocxl_afu_config { 21*4882a593Smuzhiyun u8 idx; 22*4882a593Smuzhiyun int dvsec_afu_control_pos; /* offset of AFU control DVSEC */ 23*4882a593Smuzhiyun char name[OCXL_AFU_NAME_SZ]; 24*4882a593Smuzhiyun u8 version_major; 25*4882a593Smuzhiyun u8 version_minor; 26*4882a593Smuzhiyun u8 afuc_type; 27*4882a593Smuzhiyun u8 afum_type; 28*4882a593Smuzhiyun u8 profile; 29*4882a593Smuzhiyun u8 global_mmio_bar; /* global MMIO area */ 30*4882a593Smuzhiyun u64 global_mmio_offset; 31*4882a593Smuzhiyun u32 global_mmio_size; 32*4882a593Smuzhiyun u8 pp_mmio_bar; /* per-process MMIO area */ 33*4882a593Smuzhiyun u64 pp_mmio_offset; 34*4882a593Smuzhiyun u32 pp_mmio_stride; 35*4882a593Smuzhiyun u64 lpc_mem_offset; 36*4882a593Smuzhiyun u64 lpc_mem_size; 37*4882a593Smuzhiyun u64 special_purpose_mem_offset; 38*4882a593Smuzhiyun u64 special_purpose_mem_size; 39*4882a593Smuzhiyun u8 pasid_supported_log; 40*4882a593Smuzhiyun u16 actag_supported; 41*4882a593Smuzhiyun }; 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun struct ocxl_fn_config { 44*4882a593Smuzhiyun int dvsec_tl_pos; /* offset of the Transaction Layer DVSEC */ 45*4882a593Smuzhiyun int dvsec_function_pos; /* offset of the Function DVSEC */ 46*4882a593Smuzhiyun int dvsec_afu_info_pos; /* offset of the AFU information DVSEC */ 47*4882a593Smuzhiyun s8 max_pasid_log; 48*4882a593Smuzhiyun s8 max_afu_index; 49*4882a593Smuzhiyun }; 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun enum ocxl_endian { 52*4882a593Smuzhiyun OCXL_BIG_ENDIAN = 0, /**< AFU data is big-endian */ 53*4882a593Smuzhiyun OCXL_LITTLE_ENDIAN = 1, /**< AFU data is little-endian */ 54*4882a593Smuzhiyun OCXL_HOST_ENDIAN = 2, /**< AFU data is the same endianness as the host */ 55*4882a593Smuzhiyun }; 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun // These are opaque outside the ocxl driver 58*4882a593Smuzhiyun struct ocxl_afu; 59*4882a593Smuzhiyun struct ocxl_fn; 60*4882a593Smuzhiyun struct ocxl_context; 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun // Device detection & initialisation 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /** 65*4882a593Smuzhiyun * ocxl_function_open() - Open an OpenCAPI function on an OpenCAPI device 66*4882a593Smuzhiyun * @dev: The PCI device that contains the function 67*4882a593Smuzhiyun * 68*4882a593Smuzhiyun * Returns an opaque pointer to the function, or an error pointer (check with IS_ERR) 69*4882a593Smuzhiyun */ 70*4882a593Smuzhiyun struct ocxl_fn *ocxl_function_open(struct pci_dev *dev); 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun /** 73*4882a593Smuzhiyun * ocxl_function_afu_list() - Get the list of AFUs associated with a PCI function device 74*4882a593Smuzhiyun * Returns a list of struct ocxl_afu * 75*4882a593Smuzhiyun * 76*4882a593Smuzhiyun * @fn: The OpenCAPI function containing the AFUs 77*4882a593Smuzhiyun */ 78*4882a593Smuzhiyun struct list_head *ocxl_function_afu_list(struct ocxl_fn *fn); 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun /** 81*4882a593Smuzhiyun * ocxl_function_fetch_afu() - Fetch an AFU instance from an OpenCAPI function 82*4882a593Smuzhiyun * @fn: The OpenCAPI function to get the AFU from 83*4882a593Smuzhiyun * @afu_idx: The index of the AFU to get 84*4882a593Smuzhiyun * 85*4882a593Smuzhiyun * If successful, the AFU should be released with ocxl_afu_put() 86*4882a593Smuzhiyun * 87*4882a593Smuzhiyun * Returns a pointer to the AFU, or NULL on error 88*4882a593Smuzhiyun */ 89*4882a593Smuzhiyun struct ocxl_afu *ocxl_function_fetch_afu(struct ocxl_fn *fn, u8 afu_idx); 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun /** 92*4882a593Smuzhiyun * ocxl_afu_get() - Take a reference to an AFU 93*4882a593Smuzhiyun * @afu: The AFU to increment the reference count on 94*4882a593Smuzhiyun */ 95*4882a593Smuzhiyun void ocxl_afu_get(struct ocxl_afu *afu); 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun /** 98*4882a593Smuzhiyun * ocxl_afu_put() - Release a reference to an AFU 99*4882a593Smuzhiyun * @afu: The AFU to decrement the reference count on 100*4882a593Smuzhiyun */ 101*4882a593Smuzhiyun void ocxl_afu_put(struct ocxl_afu *afu); 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun /** 105*4882a593Smuzhiyun * ocxl_function_config() - Get the configuration information for an OpenCAPI function 106*4882a593Smuzhiyun * @fn: The OpenCAPI function to get the config for 107*4882a593Smuzhiyun * 108*4882a593Smuzhiyun * Returns the function config, or NULL on error 109*4882a593Smuzhiyun */ 110*4882a593Smuzhiyun const struct ocxl_fn_config *ocxl_function_config(struct ocxl_fn *fn); 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun /** 113*4882a593Smuzhiyun * ocxl_function_close() - Close an OpenCAPI function 114*4882a593Smuzhiyun * This will free any AFUs previously retrieved from the function, and 115*4882a593Smuzhiyun * detach and associated contexts. The contexts must by freed by the caller. 116*4882a593Smuzhiyun * 117*4882a593Smuzhiyun * @fn: The OpenCAPI function to close 118*4882a593Smuzhiyun * 119*4882a593Smuzhiyun */ 120*4882a593Smuzhiyun void ocxl_function_close(struct ocxl_fn *fn); 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun // Context allocation 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun /** 125*4882a593Smuzhiyun * ocxl_context_alloc() - Allocate an OpenCAPI context 126*4882a593Smuzhiyun * @context: The OpenCAPI context to allocate, must be freed with ocxl_context_free 127*4882a593Smuzhiyun * @afu: The AFU the context belongs to 128*4882a593Smuzhiyun * @mapping: The mapping to unmap when the context is closed (may be NULL) 129*4882a593Smuzhiyun */ 130*4882a593Smuzhiyun int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu, 131*4882a593Smuzhiyun struct address_space *mapping); 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun /** 134*4882a593Smuzhiyun * ocxl_context_free() - Free an OpenCAPI context 135*4882a593Smuzhiyun * @ctx: The OpenCAPI context to free 136*4882a593Smuzhiyun */ 137*4882a593Smuzhiyun void ocxl_context_free(struct ocxl_context *ctx); 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun /** 140*4882a593Smuzhiyun * ocxl_context_attach() - Grant access to an MM to an OpenCAPI context 141*4882a593Smuzhiyun * @ctx: The OpenCAPI context to attach 142*4882a593Smuzhiyun * @amr: The value of the AMR register to restrict access 143*4882a593Smuzhiyun * @mm: The mm to attach to the context 144*4882a593Smuzhiyun * 145*4882a593Smuzhiyun * Returns 0 on success, negative on failure 146*4882a593Smuzhiyun */ 147*4882a593Smuzhiyun int ocxl_context_attach(struct ocxl_context *ctx, u64 amr, 148*4882a593Smuzhiyun struct mm_struct *mm); 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun /** 151*4882a593Smuzhiyun * ocxl_context_detach() - Detach an MM from an OpenCAPI context 152*4882a593Smuzhiyun * @ctx: The OpenCAPI context to attach 153*4882a593Smuzhiyun * 154*4882a593Smuzhiyun * Returns 0 on success, negative on failure 155*4882a593Smuzhiyun */ 156*4882a593Smuzhiyun int ocxl_context_detach(struct ocxl_context *ctx); 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun // AFU IRQs 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun /** 161*4882a593Smuzhiyun * ocxl_afu_irq_alloc() - Allocate an IRQ associated with an AFU context 162*4882a593Smuzhiyun * @ctx: the AFU context 163*4882a593Smuzhiyun * @irq_id: out, the IRQ ID 164*4882a593Smuzhiyun * 165*4882a593Smuzhiyun * Returns 0 on success, negative on failure 166*4882a593Smuzhiyun */ 167*4882a593Smuzhiyun int ocxl_afu_irq_alloc(struct ocxl_context *ctx, int *irq_id); 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun /** 170*4882a593Smuzhiyun * ocxl_afu_irq_free() - Frees an IRQ associated with an AFU context 171*4882a593Smuzhiyun * @ctx: the AFU context 172*4882a593Smuzhiyun * @irq_id: the IRQ ID 173*4882a593Smuzhiyun * 174*4882a593Smuzhiyun * Returns 0 on success, negative on failure 175*4882a593Smuzhiyun */ 176*4882a593Smuzhiyun int ocxl_afu_irq_free(struct ocxl_context *ctx, int irq_id); 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun /** 179*4882a593Smuzhiyun * ocxl_afu_irq_get_addr() - Gets the address of the trigger page for an IRQ 180*4882a593Smuzhiyun * This can then be provided to an AFU which will write to that 181*4882a593Smuzhiyun * page to trigger the IRQ. 182*4882a593Smuzhiyun * @ctx: The AFU context that the IRQ is associated with 183*4882a593Smuzhiyun * @irq_id: The IRQ ID 184*4882a593Smuzhiyun * 185*4882a593Smuzhiyun * returns the trigger page address, or 0 if the IRQ is not valid 186*4882a593Smuzhiyun */ 187*4882a593Smuzhiyun u64 ocxl_afu_irq_get_addr(struct ocxl_context *ctx, int irq_id); 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun /** 190*4882a593Smuzhiyun * ocxl_irq_set_handler() - Provide a callback to be called when an IRQ is triggered 191*4882a593Smuzhiyun * @ctx: The AFU context that the IRQ is associated with 192*4882a593Smuzhiyun * @irq_id: The IRQ ID 193*4882a593Smuzhiyun * @handler: the callback to be called when the IRQ is triggered 194*4882a593Smuzhiyun * @free_private: the callback to be called when the IRQ is freed (may be NULL) 195*4882a593Smuzhiyun * @private: Private data to be passed to the callbacks 196*4882a593Smuzhiyun * 197*4882a593Smuzhiyun * Returns 0 on success, negative on failure 198*4882a593Smuzhiyun */ 199*4882a593Smuzhiyun int ocxl_irq_set_handler(struct ocxl_context *ctx, int irq_id, 200*4882a593Smuzhiyun irqreturn_t (*handler)(void *private), 201*4882a593Smuzhiyun void (*free_private)(void *private), 202*4882a593Smuzhiyun void *private); 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun // AFU Metadata 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun /** 207*4882a593Smuzhiyun * ocxl_afu_config() - Get a pointer to the config for an AFU 208*4882a593Smuzhiyun * @afu: a pointer to the AFU to get the config for 209*4882a593Smuzhiyun * 210*4882a593Smuzhiyun * Returns a pointer to the AFU config 211*4882a593Smuzhiyun */ 212*4882a593Smuzhiyun struct ocxl_afu_config *ocxl_afu_config(struct ocxl_afu *afu); 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun /** 215*4882a593Smuzhiyun * ocxl_afu_set_private() - Assign opaque hardware specific information to an OpenCAPI AFU. 216*4882a593Smuzhiyun * @afu: The OpenCAPI AFU 217*4882a593Smuzhiyun * @private: the opaque hardware specific information to assign to the driver 218*4882a593Smuzhiyun */ 219*4882a593Smuzhiyun void ocxl_afu_set_private(struct ocxl_afu *afu, void *private); 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun /** 222*4882a593Smuzhiyun * ocxl_afu_get_private() - Fetch the hardware specific information associated with 223*4882a593Smuzhiyun * an external OpenCAPI AFU. This may be consumed by an external OpenCAPI driver. 224*4882a593Smuzhiyun * @afu: The OpenCAPI AFU 225*4882a593Smuzhiyun * 226*4882a593Smuzhiyun * Returns the opaque pointer associated with the device, or NULL if not set 227*4882a593Smuzhiyun */ 228*4882a593Smuzhiyun void *ocxl_afu_get_private(struct ocxl_afu *afu); 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun // Global MMIO 231*4882a593Smuzhiyun /** 232*4882a593Smuzhiyun * ocxl_global_mmio_read32() - Read a 32 bit value from global MMIO 233*4882a593Smuzhiyun * @afu: The AFU 234*4882a593Smuzhiyun * @offset: The Offset from the start of MMIO 235*4882a593Smuzhiyun * @endian: the endianness that the MMIO data is in 236*4882a593Smuzhiyun * @val: returns the value 237*4882a593Smuzhiyun * 238*4882a593Smuzhiyun * Returns 0 for success, negative on error 239*4882a593Smuzhiyun */ 240*4882a593Smuzhiyun int ocxl_global_mmio_read32(struct ocxl_afu *afu, size_t offset, 241*4882a593Smuzhiyun enum ocxl_endian endian, u32 *val); 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun /** 244*4882a593Smuzhiyun * ocxl_global_mmio_read64() - Read a 64 bit value from global MMIO 245*4882a593Smuzhiyun * @afu: The AFU 246*4882a593Smuzhiyun * @offset: The Offset from the start of MMIO 247*4882a593Smuzhiyun * @endian: the endianness that the MMIO data is in 248*4882a593Smuzhiyun * @val: returns the value 249*4882a593Smuzhiyun * 250*4882a593Smuzhiyun * Returns 0 for success, negative on error 251*4882a593Smuzhiyun */ 252*4882a593Smuzhiyun int ocxl_global_mmio_read64(struct ocxl_afu *afu, size_t offset, 253*4882a593Smuzhiyun enum ocxl_endian endian, u64 *val); 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun /** 256*4882a593Smuzhiyun * ocxl_global_mmio_write32() - Write a 32 bit value to global MMIO 257*4882a593Smuzhiyun * @afu: The AFU 258*4882a593Smuzhiyun * @offset: The Offset from the start of MMIO 259*4882a593Smuzhiyun * @endian: the endianness that the MMIO data is in 260*4882a593Smuzhiyun * @val: The value to write 261*4882a593Smuzhiyun * 262*4882a593Smuzhiyun * Returns 0 for success, negative on error 263*4882a593Smuzhiyun */ 264*4882a593Smuzhiyun int ocxl_global_mmio_write32(struct ocxl_afu *afu, size_t offset, 265*4882a593Smuzhiyun enum ocxl_endian endian, u32 val); 266*4882a593Smuzhiyun 267*4882a593Smuzhiyun /** 268*4882a593Smuzhiyun * ocxl_global_mmio_write64() - Write a 64 bit value to global MMIO 269*4882a593Smuzhiyun * @afu: The AFU 270*4882a593Smuzhiyun * @offset: The Offset from the start of MMIO 271*4882a593Smuzhiyun * @endian: the endianness that the MMIO data is in 272*4882a593Smuzhiyun * @val: The value to write 273*4882a593Smuzhiyun * 274*4882a593Smuzhiyun * Returns 0 for success, negative on error 275*4882a593Smuzhiyun */ 276*4882a593Smuzhiyun int ocxl_global_mmio_write64(struct ocxl_afu *afu, size_t offset, 277*4882a593Smuzhiyun enum ocxl_endian endian, u64 val); 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun /** 280*4882a593Smuzhiyun * ocxl_global_mmio_set32() - Set bits in a 32 bit global MMIO register 281*4882a593Smuzhiyun * @afu: The AFU 282*4882a593Smuzhiyun * @offset: The Offset from the start of MMIO 283*4882a593Smuzhiyun * @endian: the endianness that the MMIO data is in 284*4882a593Smuzhiyun * @mask: a mask of the bits to set 285*4882a593Smuzhiyun * 286*4882a593Smuzhiyun * Returns 0 for success, negative on error 287*4882a593Smuzhiyun */ 288*4882a593Smuzhiyun int ocxl_global_mmio_set32(struct ocxl_afu *afu, size_t offset, 289*4882a593Smuzhiyun enum ocxl_endian endian, u32 mask); 290*4882a593Smuzhiyun 291*4882a593Smuzhiyun /** 292*4882a593Smuzhiyun * ocxl_global_mmio_set64() - Set bits in a 64 bit global MMIO register 293*4882a593Smuzhiyun * @afu: The AFU 294*4882a593Smuzhiyun * @offset: The Offset from the start of MMIO 295*4882a593Smuzhiyun * @endian: the endianness that the MMIO data is in 296*4882a593Smuzhiyun * @mask: a mask of the bits to set 297*4882a593Smuzhiyun * 298*4882a593Smuzhiyun * Returns 0 for success, negative on error 299*4882a593Smuzhiyun */ 300*4882a593Smuzhiyun int ocxl_global_mmio_set64(struct ocxl_afu *afu, size_t offset, 301*4882a593Smuzhiyun enum ocxl_endian endian, u64 mask); 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun /** 304*4882a593Smuzhiyun * ocxl_global_mmio_clear32() - Set bits in a 32 bit global MMIO register 305*4882a593Smuzhiyun * @afu: The AFU 306*4882a593Smuzhiyun * @offset: The Offset from the start of MMIO 307*4882a593Smuzhiyun * @endian: the endianness that the MMIO data is in 308*4882a593Smuzhiyun * @mask: a mask of the bits to set 309*4882a593Smuzhiyun * 310*4882a593Smuzhiyun * Returns 0 for success, negative on error 311*4882a593Smuzhiyun */ 312*4882a593Smuzhiyun int ocxl_global_mmio_clear32(struct ocxl_afu *afu, size_t offset, 313*4882a593Smuzhiyun enum ocxl_endian endian, u32 mask); 314*4882a593Smuzhiyun 315*4882a593Smuzhiyun /** 316*4882a593Smuzhiyun * ocxl_global_mmio_clear64() - Set bits in a 64 bit global MMIO register 317*4882a593Smuzhiyun * @afu: The AFU 318*4882a593Smuzhiyun * @offset: The Offset from the start of MMIO 319*4882a593Smuzhiyun * @endian: the endianness that the MMIO data is in 320*4882a593Smuzhiyun * @mask: a mask of the bits to set 321*4882a593Smuzhiyun * 322*4882a593Smuzhiyun * Returns 0 for success, negative on error 323*4882a593Smuzhiyun */ 324*4882a593Smuzhiyun int ocxl_global_mmio_clear64(struct ocxl_afu *afu, size_t offset, 325*4882a593Smuzhiyun enum ocxl_endian endian, u64 mask); 326*4882a593Smuzhiyun 327*4882a593Smuzhiyun // Functions left here are for compatibility with the cxlflash driver 328*4882a593Smuzhiyun 329*4882a593Smuzhiyun /* 330*4882a593Smuzhiyun * Read the configuration space of a function for the AFU specified by 331*4882a593Smuzhiyun * the index 'afu_idx'. Fills in a ocxl_afu_config structure 332*4882a593Smuzhiyun */ 333*4882a593Smuzhiyun int ocxl_config_read_afu(struct pci_dev *dev, 334*4882a593Smuzhiyun struct ocxl_fn_config *fn, 335*4882a593Smuzhiyun struct ocxl_afu_config *afu, 336*4882a593Smuzhiyun u8 afu_idx); 337*4882a593Smuzhiyun 338*4882a593Smuzhiyun /* 339*4882a593Smuzhiyun * Tell an AFU, by writing in the configuration space, the PASIDs that 340*4882a593Smuzhiyun * it can use. Range starts at 'pasid_base' and its size is a multiple 341*4882a593Smuzhiyun * of 2 342*4882a593Smuzhiyun * 343*4882a593Smuzhiyun * 'afu_control_offset' is the offset of the AFU control DVSEC which 344*4882a593Smuzhiyun * can be found in the function configuration 345*4882a593Smuzhiyun */ 346*4882a593Smuzhiyun void ocxl_config_set_afu_pasid(struct pci_dev *dev, 347*4882a593Smuzhiyun int afu_control_offset, 348*4882a593Smuzhiyun int pasid_base, u32 pasid_count_log); 349*4882a593Smuzhiyun 350*4882a593Smuzhiyun /* 351*4882a593Smuzhiyun * Get the actag configuration for the function: 352*4882a593Smuzhiyun * 'base' is the first actag value that can be used. 353*4882a593Smuzhiyun * 'enabled' it the number of actags available, starting from base. 354*4882a593Smuzhiyun * 'supported' is the total number of actags desired by all the AFUs 355*4882a593Smuzhiyun * of the function. 356*4882a593Smuzhiyun */ 357*4882a593Smuzhiyun int ocxl_config_get_actag_info(struct pci_dev *dev, 358*4882a593Smuzhiyun u16 *base, u16 *enabled, u16 *supported); 359*4882a593Smuzhiyun 360*4882a593Smuzhiyun /* 361*4882a593Smuzhiyun * Tell a function, by writing in the configuration space, the actags 362*4882a593Smuzhiyun * it can use. 363*4882a593Smuzhiyun * 364*4882a593Smuzhiyun * 'func_offset' is the offset of the Function DVSEC that can found in 365*4882a593Smuzhiyun * the function configuration 366*4882a593Smuzhiyun */ 367*4882a593Smuzhiyun void ocxl_config_set_actag(struct pci_dev *dev, int func_offset, 368*4882a593Smuzhiyun u32 actag_base, u32 actag_count); 369*4882a593Smuzhiyun 370*4882a593Smuzhiyun /* 371*4882a593Smuzhiyun * Tell an AFU, by writing in the configuration space, the actags it 372*4882a593Smuzhiyun * can use. 373*4882a593Smuzhiyun * 374*4882a593Smuzhiyun * 'afu_control_offset' is the offset of the AFU control DVSEC for the 375*4882a593Smuzhiyun * desired AFU. It can be found in the AFU configuration 376*4882a593Smuzhiyun */ 377*4882a593Smuzhiyun void ocxl_config_set_afu_actag(struct pci_dev *dev, 378*4882a593Smuzhiyun int afu_control_offset, 379*4882a593Smuzhiyun int actag_base, int actag_count); 380*4882a593Smuzhiyun 381*4882a593Smuzhiyun /* 382*4882a593Smuzhiyun * Enable/disable an AFU, by writing in the configuration space. 383*4882a593Smuzhiyun * 384*4882a593Smuzhiyun * 'afu_control_offset' is the offset of the AFU control DVSEC for the 385*4882a593Smuzhiyun * desired AFU. It can be found in the AFU configuration 386*4882a593Smuzhiyun */ 387*4882a593Smuzhiyun void ocxl_config_set_afu_state(struct pci_dev *dev, 388*4882a593Smuzhiyun int afu_control_offset, int enable); 389*4882a593Smuzhiyun 390*4882a593Smuzhiyun /* 391*4882a593Smuzhiyun * Set the Transaction Layer configuration in the configuration space. 392*4882a593Smuzhiyun * Only needed for function 0. 393*4882a593Smuzhiyun * 394*4882a593Smuzhiyun * It queries the host TL capabilities, find some common ground 395*4882a593Smuzhiyun * between the host and device, and set the Transaction Layer on both 396*4882a593Smuzhiyun * accordingly. 397*4882a593Smuzhiyun */ 398*4882a593Smuzhiyun int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec); 399*4882a593Smuzhiyun 400*4882a593Smuzhiyun /* 401*4882a593Smuzhiyun * Request an AFU to terminate a PASID. 402*4882a593Smuzhiyun * Will return once the AFU has acked the request, or an error in case 403*4882a593Smuzhiyun * of timeout. 404*4882a593Smuzhiyun * 405*4882a593Smuzhiyun * The hardware can only terminate one PASID at a time, so caller must 406*4882a593Smuzhiyun * guarantee some kind of serialization. 407*4882a593Smuzhiyun * 408*4882a593Smuzhiyun * 'afu_control_offset' is the offset of the AFU control DVSEC for the 409*4882a593Smuzhiyun * desired AFU. It can be found in the AFU configuration 410*4882a593Smuzhiyun */ 411*4882a593Smuzhiyun int ocxl_config_terminate_pasid(struct pci_dev *dev, 412*4882a593Smuzhiyun int afu_control_offset, int pasid); 413*4882a593Smuzhiyun 414*4882a593Smuzhiyun /* 415*4882a593Smuzhiyun * Read the configuration space of a function and fill in a 416*4882a593Smuzhiyun * ocxl_fn_config structure with all the function details 417*4882a593Smuzhiyun */ 418*4882a593Smuzhiyun int ocxl_config_read_function(struct pci_dev *dev, 419*4882a593Smuzhiyun struct ocxl_fn_config *fn); 420*4882a593Smuzhiyun 421*4882a593Smuzhiyun /* 422*4882a593Smuzhiyun * Set up the opencapi link for the function. 423*4882a593Smuzhiyun * 424*4882a593Smuzhiyun * When called for the first time for a link, it sets up the Shared 425*4882a593Smuzhiyun * Process Area for the link and the interrupt handler to process 426*4882a593Smuzhiyun * translation faults. 427*4882a593Smuzhiyun * 428*4882a593Smuzhiyun * Returns a 'link handle' that should be used for further calls for 429*4882a593Smuzhiyun * the link 430*4882a593Smuzhiyun */ 431*4882a593Smuzhiyun int ocxl_link_setup(struct pci_dev *dev, int PE_mask, 432*4882a593Smuzhiyun void **link_handle); 433*4882a593Smuzhiyun 434*4882a593Smuzhiyun /* 435*4882a593Smuzhiyun * Remove the association between the function and its link. 436*4882a593Smuzhiyun */ 437*4882a593Smuzhiyun void ocxl_link_release(struct pci_dev *dev, void *link_handle); 438*4882a593Smuzhiyun 439*4882a593Smuzhiyun /* 440*4882a593Smuzhiyun * Add a Process Element to the Shared Process Area for a link. 441*4882a593Smuzhiyun * The process is defined by its PASID, pid, tid and its mm_struct. 442*4882a593Smuzhiyun * 443*4882a593Smuzhiyun * 'xsl_err_cb' is an optional callback if the driver wants to be 444*4882a593Smuzhiyun * notified when the translation fault interrupt handler detects an 445*4882a593Smuzhiyun * address error. 446*4882a593Smuzhiyun * 'xsl_err_data' is an argument passed to the above callback, if 447*4882a593Smuzhiyun * defined 448*4882a593Smuzhiyun */ 449*4882a593Smuzhiyun int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr, 450*4882a593Smuzhiyun u64 amr, struct mm_struct *mm, 451*4882a593Smuzhiyun void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr), 452*4882a593Smuzhiyun void *xsl_err_data); 453*4882a593Smuzhiyun 454*4882a593Smuzhiyun /* 455*4882a593Smuzhiyun * Remove a Process Element from the Shared Process Area for a link 456*4882a593Smuzhiyun */ 457*4882a593Smuzhiyun int ocxl_link_remove_pe(void *link_handle, int pasid); 458*4882a593Smuzhiyun 459*4882a593Smuzhiyun /* 460*4882a593Smuzhiyun * Allocate an AFU interrupt associated to the link. 461*4882a593Smuzhiyun * 462*4882a593Smuzhiyun * 'hw_irq' is the hardware interrupt number 463*4882a593Smuzhiyun */ 464*4882a593Smuzhiyun int ocxl_link_irq_alloc(void *link_handle, int *hw_irq); 465*4882a593Smuzhiyun 466*4882a593Smuzhiyun /* 467*4882a593Smuzhiyun * Free a previously allocated AFU interrupt 468*4882a593Smuzhiyun */ 469*4882a593Smuzhiyun void ocxl_link_free_irq(void *link_handle, int hw_irq); 470*4882a593Smuzhiyun 471*4882a593Smuzhiyun #endif /* _MISC_OCXL_H_ */ 472