Commit 5be587b1 authored by Frederic Barrat's avatar Frederic Barrat Committed by Michael Ellerman

cxl: Introduce implementation-specific API

The backend API (in cxl.h) lists some low-level functions whose
implementation is different on bare-metal and in a guest. Each
environment implements its own functions, and the common code uses
them through function pointers, defined in cxl_backend_ops
Co-authored-by: default avatarChristophe Lombard <clombard@linux.vnet.ibm.com>
Signed-off-by: default avatarFrederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: default avatarChristophe Lombard <clombard@linux.vnet.ibm.com>
Reviewed-by: default avatarManoj Kumar <manoj@linux.vnet.ibm.com>
Acked-by: default avatarIan Munsie <imunsie@au1.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent cca44c01
...@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs); ...@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
void cxl_free_afu_irqs(struct cxl_context *ctx) void cxl_free_afu_irqs(struct cxl_context *ctx)
{ {
afu_irq_name_free(ctx); afu_irq_name_free(ctx);
cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
} }
EXPORT_SYMBOL_GPL(cxl_free_afu_irqs); EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
...@@ -176,7 +176,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed, ...@@ -176,7 +176,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
cxl_ctx_get(); cxl_ctx_get();
if ((rc = cxl_attach_process(ctx, kernel, wed , 0))) { if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
put_pid(ctx->pid); put_pid(ctx->pid);
cxl_ctx_put(); cxl_ctx_put();
goto out; goto out;
...@@ -342,11 +342,11 @@ int cxl_afu_reset(struct cxl_context *ctx) ...@@ -342,11 +342,11 @@ int cxl_afu_reset(struct cxl_context *ctx)
struct cxl_afu *afu = ctx->afu; struct cxl_afu *afu = ctx->afu;
int rc; int rc;
rc = __cxl_afu_reset(afu); rc = cxl_ops->afu_reset(afu);
if (rc) if (rc)
return rc; return rc;
return cxl_afu_check_and_enable(afu); return cxl_ops->afu_check_and_enable(afu);
} }
EXPORT_SYMBOL_GPL(cxl_afu_reset); EXPORT_SYMBOL_GPL(cxl_afu_reset);
......
...@@ -214,8 +214,8 @@ int __detach_context(struct cxl_context *ctx) ...@@ -214,8 +214,8 @@ int __detach_context(struct cxl_context *ctx)
/* Only warn if we detached while the link was OK. /* Only warn if we detached while the link was OK.
* If detach fails when hw is down, we don't care. * If detach fails when hw is down, we don't care.
*/ */
WARN_ON(cxl_detach_process(ctx) && WARN_ON(cxl_ops->detach_process(ctx) &&
cxl_adapter_link_ok(ctx->afu->adapter)); cxl_ops->link_ok(ctx->afu->adapter));
flush_work(&ctx->fault_work); /* Only needed for dedicated process */ flush_work(&ctx->fault_work); /* Only needed for dedicated process */
/* release the reference to the group leader and mm handling pid */ /* release the reference to the group leader and mm handling pid */
......
...@@ -623,11 +623,6 @@ static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg) ...@@ -623,11 +623,6 @@ static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg)
return ~0ULL; return ~0ULL;
} }
u64 cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off);
u32 cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off);
u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off);
u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off);
ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
loff_t off, size_t count); loff_t off, size_t count);
...@@ -666,10 +661,6 @@ void cxl_sysfs_afu_m_remove(struct cxl_afu *afu); ...@@ -666,10 +661,6 @@ void cxl_sysfs_afu_m_remove(struct cxl_afu *afu);
struct cxl *cxl_alloc_adapter(void); struct cxl *cxl_alloc_adapter(void);
struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice); struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice);
int cxl_afu_activate_mode(struct cxl_afu *afu, int mode);
int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode);
int cxl_afu_deactivate_mode(struct cxl_afu *afu);
int cxl_afu_select_best_mode(struct cxl_afu *afu); int cxl_afu_select_best_mode(struct cxl_afu *afu);
int cxl_register_psl_irq(struct cxl_afu *afu); int cxl_register_psl_irq(struct cxl_afu *afu);
...@@ -681,8 +672,6 @@ void cxl_release_serr_irq(struct cxl_afu *afu); ...@@ -681,8 +672,6 @@ void cxl_release_serr_irq(struct cxl_afu *afu);
int afu_register_irqs(struct cxl_context *ctx, u32 count); int afu_register_irqs(struct cxl_context *ctx, u32 count);
void afu_release_irqs(struct cxl_context *ctx, void *cookie); void afu_release_irqs(struct cxl_context *ctx, void *cookie);
void afu_irq_name_free(struct cxl_context *ctx); void afu_irq_name_free(struct cxl_context *ctx);
irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr,
u64 errstat);
int cxl_debugfs_init(void); int cxl_debugfs_init(void);
void cxl_debugfs_exit(void); void cxl_debugfs_exit(void);
...@@ -727,18 +716,10 @@ int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler, ...@@ -727,18 +716,10 @@ int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler,
void *cookie, irq_hw_number_t *dest_hwirq, void *cookie, irq_hw_number_t *dest_hwirq,
unsigned int *dest_virq, const char *name); unsigned int *dest_virq, const char *name);
int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed,
u64 amr);
int cxl_detach_process(struct cxl_context *ctx);
int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
int cxl_check_error(struct cxl_afu *afu); int cxl_check_error(struct cxl_afu *afu);
int cxl_afu_slbia(struct cxl_afu *afu); int cxl_afu_slbia(struct cxl_afu *afu);
int cxl_tlb_slb_invalidate(struct cxl *adapter); int cxl_tlb_slb_invalidate(struct cxl *adapter);
int cxl_afu_disable(struct cxl_afu *afu); int cxl_afu_disable(struct cxl_afu *afu);
int __cxl_afu_reset(struct cxl_afu *afu);
int cxl_afu_check_and_enable(struct cxl_afu *afu);
int cxl_psl_purge(struct cxl_afu *afu); int cxl_psl_purge(struct cxl_afu *afu);
void cxl_stop_trace(struct cxl *cxl); void cxl_stop_trace(struct cxl *cxl);
...@@ -757,4 +738,38 @@ unsigned int afu_poll(struct file *file, struct poll_table_struct *poll); ...@@ -757,4 +738,38 @@ unsigned int afu_poll(struct file *file, struct poll_table_struct *poll);
ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off); ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off);
extern const struct file_operations afu_fops; extern const struct file_operations afu_fops;
struct cxl_backend_ops {
struct module *module;
int (*adapter_reset)(struct cxl *adapter);
int (*alloc_one_irq)(struct cxl *adapter);
void (*release_one_irq)(struct cxl *adapter, int hwirq);
int (*alloc_irq_ranges)(struct cxl_irq_ranges *irqs,
struct cxl *adapter, unsigned int num);
void (*release_irq_ranges)(struct cxl_irq_ranges *irqs,
struct cxl *adapter);
int (*setup_irq)(struct cxl *adapter, unsigned int hwirq,
unsigned int virq);
irqreturn_t (*handle_psl_slice_error)(struct cxl_context *ctx,
u64 dsisr, u64 errstat);
irqreturn_t (*psl_interrupt)(int irq, void *data);
int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
int (*attach_process)(struct cxl_context *ctx, bool kernel,
u64 wed, u64 amr);
int (*detach_process)(struct cxl_context *ctx);
bool (*link_ok)(struct cxl *cxl);
void (*release_afu)(struct device *dev);
ssize_t (*afu_read_err_buffer)(struct cxl_afu *afu, char *buf,
loff_t off, size_t count);
int (*afu_check_and_enable)(struct cxl_afu *afu);
int (*afu_activate_mode)(struct cxl_afu *afu, int mode);
int (*afu_deactivate_mode)(struct cxl_afu *afu, int mode);
int (*afu_reset)(struct cxl_afu *afu);
int (*afu_cr_read8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 *val);
int (*afu_cr_read16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 *val);
int (*afu_cr_read32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 *val);
int (*afu_cr_read64)(struct cxl_afu *afu, int cr_idx, u64 offset, u64 *val);
};
extern const struct cxl_backend_ops cxl_native_ops;
extern const struct cxl_backend_ops *cxl_ops;
#endif #endif
...@@ -101,7 +101,7 @@ static void cxl_ack_ae(struct cxl_context *ctx) ...@@ -101,7 +101,7 @@ static void cxl_ack_ae(struct cxl_context *ctx)
{ {
unsigned long flags; unsigned long flags;
cxl_ack_irq(ctx, CXL_PSL_TFC_An_AE, 0); cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_AE, 0);
spin_lock_irqsave(&ctx->lock, flags); spin_lock_irqsave(&ctx->lock, flags);
ctx->pending_fault = true; ctx->pending_fault = true;
...@@ -125,7 +125,7 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx, ...@@ -125,7 +125,7 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx,
else { else {
mb(); /* Order seg table write to TFC MMIO write */ mb(); /* Order seg table write to TFC MMIO write */
cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0); cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -163,7 +163,7 @@ static void cxl_handle_page_fault(struct cxl_context *ctx, ...@@ -163,7 +163,7 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,
local_irq_restore(flags); local_irq_restore(flags);
pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe); pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe);
cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0); cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
} }
/* /*
......
...@@ -79,7 +79,7 @@ static int __afu_open(struct inode *inode, struct file *file, bool master) ...@@ -79,7 +79,7 @@ static int __afu_open(struct inode *inode, struct file *file, bool master)
if (!afu->current_mode) if (!afu->current_mode)
goto err_put_afu; goto err_put_afu;
if (!cxl_adapter_link_ok(adapter)) { if (!cxl_ops->link_ok(adapter)) {
rc = -EIO; rc = -EIO;
goto err_put_afu; goto err_put_afu;
} }
...@@ -210,8 +210,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, ...@@ -210,8 +210,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor, if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
amr))) { amr))) {
afu_release_irqs(ctx, ctx); afu_release_irqs(ctx, ctx);
goto out; goto out;
} }
...@@ -222,6 +222,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, ...@@ -222,6 +222,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
mutex_unlock(&ctx->status_mutex); mutex_unlock(&ctx->status_mutex);
return rc; return rc;
} }
static long afu_ioctl_process_element(struct cxl_context *ctx, static long afu_ioctl_process_element(struct cxl_context *ctx,
int __user *upe) int __user *upe)
{ {
...@@ -259,7 +260,7 @@ long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -259,7 +260,7 @@ long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (ctx->status == CLOSED) if (ctx->status == CLOSED)
return -EIO; return -EIO;
if (!cxl_adapter_link_ok(ctx->afu->adapter)) if (!cxl_ops->link_ok(ctx->afu->adapter))
return -EIO; return -EIO;
pr_devel("afu_ioctl\n"); pr_devel("afu_ioctl\n");
...@@ -289,7 +290,7 @@ int afu_mmap(struct file *file, struct vm_area_struct *vm) ...@@ -289,7 +290,7 @@ int afu_mmap(struct file *file, struct vm_area_struct *vm)
if (ctx->status != STARTED) if (ctx->status != STARTED)
return -EIO; return -EIO;
if (!cxl_adapter_link_ok(ctx->afu->adapter)) if (!cxl_ops->link_ok(ctx->afu->adapter))
return -EIO; return -EIO;
return cxl_context_iomap(ctx, vm); return cxl_context_iomap(ctx, vm);
...@@ -336,7 +337,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count, ...@@ -336,7 +337,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
int rc; int rc;
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
if (!cxl_adapter_link_ok(ctx->afu->adapter)) if (!cxl_ops->link_ok(ctx->afu->adapter))
return -EIO; return -EIO;
if (count < CXL_READ_MIN_SIZE) if (count < CXL_READ_MIN_SIZE)
...@@ -349,7 +350,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count, ...@@ -349,7 +350,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
if (ctx_event_pending(ctx)) if (ctx_event_pending(ctx))
break; break;
if (!cxl_adapter_link_ok(ctx->afu->adapter)) { if (!cxl_ops->link_ok(ctx->afu->adapter)) {
rc = -EIO; rc = -EIO;
goto out; goto out;
} }
......
...@@ -79,7 +79,8 @@ irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info) ...@@ -79,7 +79,8 @@ irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
if (dsisr & CXL_PSL_DSISR_An_UR) if (dsisr & CXL_PSL_DSISR_An_UR)
pr_devel("CXL interrupt: AURP PTE not found\n"); pr_devel("CXL interrupt: AURP PTE not found\n");
if (dsisr & CXL_PSL_DSISR_An_PE) if (dsisr & CXL_PSL_DSISR_An_PE)
return handle_psl_slice_error(ctx, dsisr, irq_info->errstat); return cxl_ops->handle_psl_slice_error(ctx, dsisr,
irq_info->errstat);
if (dsisr & CXL_PSL_DSISR_An_AE) { if (dsisr & CXL_PSL_DSISR_An_AE) {
pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err); pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err);
...@@ -103,7 +104,7 @@ irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info) ...@@ -103,7 +104,7 @@ irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
wake_up_all(&ctx->wq); wake_up_all(&ctx->wq);
} }
cxl_ack_irq(ctx, CXL_PSL_TFC_An_A, 0); cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_A, 0);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
if (dsisr & CXL_PSL_DSISR_An_OC) if (dsisr & CXL_PSL_DSISR_An_OC)
...@@ -167,7 +168,8 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq, ...@@ -167,7 +168,8 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
return 0; return 0;
} }
cxl_setup_irq(adapter, hwirq, virq); if (cxl_ops->setup_irq)
cxl_ops->setup_irq(adapter, hwirq, virq);
pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq); pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq);
...@@ -195,7 +197,7 @@ int cxl_register_one_irq(struct cxl *adapter, ...@@ -195,7 +197,7 @@ int cxl_register_one_irq(struct cxl *adapter,
{ {
int hwirq, virq; int hwirq, virq;
if ((hwirq = cxl_alloc_one_irq(adapter)) < 0) if ((hwirq = cxl_ops->alloc_one_irq(adapter)) < 0)
return hwirq; return hwirq;
if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name))) if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name)))
...@@ -207,7 +209,7 @@ int cxl_register_one_irq(struct cxl *adapter, ...@@ -207,7 +209,7 @@ int cxl_register_one_irq(struct cxl *adapter,
return 0; return 0;
err: err:
cxl_release_one_irq(adapter, hwirq); cxl_ops->release_one_irq(adapter, hwirq);
return -ENOMEM; return -ENOMEM;
} }
...@@ -230,7 +232,8 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count) ...@@ -230,7 +232,8 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
/* Initialize the list head to hold irq names */ /* Initialize the list head to hold irq names */
INIT_LIST_HEAD(&ctx->irq_names); INIT_LIST_HEAD(&ctx->irq_names);
if ((rc = cxl_alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, count))) if ((rc = cxl_ops->alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter,
count)))
return rc; return rc;
/* Multiplexed PSL Interrupt */ /* Multiplexed PSL Interrupt */
...@@ -268,7 +271,7 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count) ...@@ -268,7 +271,7 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
return 0; return 0;
out: out:
cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
afu_irq_name_free(ctx); afu_irq_name_free(ctx);
return -ENOMEM; return -ENOMEM;
} }
...@@ -319,7 +322,7 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie) ...@@ -319,7 +322,7 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie)
} }
afu_irq_name_free(ctx); afu_irq_name_free(ctx);
cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
ctx->irq_count = 0; ctx->irq_count = 0;
} }
...@@ -32,6 +32,8 @@ uint cxl_verbose; ...@@ -32,6 +32,8 @@ uint cxl_verbose;
module_param_named(verbose, cxl_verbose, uint, 0600); module_param_named(verbose, cxl_verbose, uint, 0600);
MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
const struct cxl_backend_ops *cxl_ops;
int cxl_afu_slbia(struct cxl_afu *afu) int cxl_afu_slbia(struct cxl_afu *afu)
{ {
unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
...@@ -46,7 +48,7 @@ int cxl_afu_slbia(struct cxl_afu *afu) ...@@ -46,7 +48,7 @@ int cxl_afu_slbia(struct cxl_afu *afu)
/* If the adapter has gone down, we can assume that we /* If the adapter has gone down, we can assume that we
* will PERST it and that will invalidate everything. * will PERST it and that will invalidate everything.
*/ */
if (!cxl_adapter_link_ok(afu->adapter)) if (!cxl_ops->link_ok(afu->adapter))
return -EIO; return -EIO;
cpu_relax(); cpu_relax();
} }
...@@ -228,7 +230,7 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice) ...@@ -228,7 +230,7 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
afu->adapter = adapter; afu->adapter = adapter;
afu->dev.parent = &adapter->dev; afu->dev.parent = &adapter->dev;
afu->dev.release = cxl_release_afu; afu->dev.release = cxl_ops->release_afu;
afu->slice = slice; afu->slice = slice;
idr_init(&afu->contexts_idr); idr_init(&afu->contexts_idr);
mutex_init(&afu->contexts_lock); mutex_init(&afu->contexts_lock);
...@@ -244,10 +246,10 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice) ...@@ -244,10 +246,10 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
int cxl_afu_select_best_mode(struct cxl_afu *afu) int cxl_afu_select_best_mode(struct cxl_afu *afu)
{ {
if (afu->modes_supported & CXL_MODE_DIRECTED) if (afu->modes_supported & CXL_MODE_DIRECTED)
return cxl_afu_activate_mode(afu, CXL_MODE_DIRECTED); return cxl_ops->afu_activate_mode(afu, CXL_MODE_DIRECTED);
if (afu->modes_supported & CXL_MODE_DEDICATED) if (afu->modes_supported & CXL_MODE_DEDICATED)
return cxl_afu_activate_mode(afu, CXL_MODE_DEDICATED); return cxl_ops->afu_activate_mode(afu, CXL_MODE_DEDICATED);
dev_warn(&afu->dev, "No supported programming modes available\n"); dev_warn(&afu->dev, "No supported programming modes available\n");
/* We don't fail this so the user can inspect sysfs */ /* We don't fail this so the user can inspect sysfs */
...@@ -269,6 +271,7 @@ static int __init init_cxl(void) ...@@ -269,6 +271,7 @@ static int __init init_cxl(void)
if ((rc = register_cxl_calls(&cxl_calls))) if ((rc = register_cxl_calls(&cxl_calls)))
goto err; goto err;
cxl_ops = &cxl_native_ops;
if ((rc = pci_register_driver(&cxl_pci_driver))) if ((rc = pci_register_driver(&cxl_pci_driver)))
goto err1; goto err1;
......
...@@ -42,7 +42,7 @@ static int afu_control(struct cxl_afu *afu, u64 command, ...@@ -42,7 +42,7 @@ static int afu_control(struct cxl_afu *afu, u64 command,
goto out; goto out;
} }
if (!cxl_adapter_link_ok(afu->adapter)) { if (!cxl_ops->link_ok(afu->adapter)) {
afu->enabled = enabled; afu->enabled = enabled;
rc = -EIO; rc = -EIO;
goto out; goto out;
...@@ -80,7 +80,7 @@ int cxl_afu_disable(struct cxl_afu *afu) ...@@ -80,7 +80,7 @@ int cxl_afu_disable(struct cxl_afu *afu)
} }
/* This will disable as well as reset */ /* This will disable as well as reset */
int __cxl_afu_reset(struct cxl_afu *afu) static int __cxl_afu_reset(struct cxl_afu *afu)
{ {
pr_devel("AFU reset request\n"); pr_devel("AFU reset request\n");
...@@ -90,9 +90,9 @@ int __cxl_afu_reset(struct cxl_afu *afu) ...@@ -90,9 +90,9 @@ int __cxl_afu_reset(struct cxl_afu *afu)
false); false);
} }
int cxl_afu_check_and_enable(struct cxl_afu *afu) static int cxl_afu_check_and_enable(struct cxl_afu *afu)
{ {
if (!cxl_adapter_link_ok(afu->adapter)) { if (!cxl_ops->link_ok(afu->adapter)) {
WARN(1, "Refusing to enable afu while link down!\n"); WARN(1, "Refusing to enable afu while link down!\n");
return -EIO; return -EIO;
} }
...@@ -114,7 +114,7 @@ int cxl_psl_purge(struct cxl_afu *afu) ...@@ -114,7 +114,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
pr_devel("PSL purge request\n"); pr_devel("PSL purge request\n");
if (!cxl_adapter_link_ok(afu->adapter)) { if (!cxl_ops->link_ok(afu->adapter)) {
dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n"); dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n");
rc = -EIO; rc = -EIO;
goto out; goto out;
...@@ -136,7 +136,7 @@ int cxl_psl_purge(struct cxl_afu *afu) ...@@ -136,7 +136,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
rc = -EBUSY; rc = -EBUSY;
goto out; goto out;
} }
if (!cxl_adapter_link_ok(afu->adapter)) { if (!cxl_ops->link_ok(afu->adapter)) {
rc = -EIO; rc = -EIO;
goto out; goto out;
} }
...@@ -247,7 +247,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter) ...@@ -247,7 +247,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter)
dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n"); dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
return -EBUSY; return -EBUSY;
} }
if (!cxl_adapter_link_ok(adapter)) if (!cxl_ops->link_ok(adapter))
return -EIO; return -EIO;
cpu_relax(); cpu_relax();
} }
...@@ -258,7 +258,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter) ...@@ -258,7 +258,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter)
dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n"); dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
return -EBUSY; return -EBUSY;
} }
if (!cxl_adapter_link_ok(adapter)) if (!cxl_ops->link_ok(adapter))
return -EIO; return -EIO;
cpu_relax(); cpu_relax();
} }
...@@ -299,7 +299,7 @@ static void slb_invalid(struct cxl_context *ctx) ...@@ -299,7 +299,7 @@ static void slb_invalid(struct cxl_context *ctx)
cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID); cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
while (1) { while (1) {
if (!cxl_adapter_link_ok(adapter)) if (!cxl_ops->link_ok(adapter))
break; break;
slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA); slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
if (!(slbia & CXL_TLB_SLB_P)) if (!(slbia & CXL_TLB_SLB_P))
...@@ -330,7 +330,7 @@ static int do_process_element_cmd(struct cxl_context *ctx, ...@@ -330,7 +330,7 @@ static int do_process_element_cmd(struct cxl_context *ctx,
rc = -EBUSY; rc = -EBUSY;
goto out; goto out;
} }
if (!cxl_adapter_link_ok(ctx->afu->adapter)) { if (!cxl_ops->link_ok(ctx->afu->adapter)) {
dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n"); dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n");
rc = -EIO; rc = -EIO;
goto out; goto out;
...@@ -386,7 +386,7 @@ static int terminate_process_element(struct cxl_context *ctx) ...@@ -386,7 +386,7 @@ static int terminate_process_element(struct cxl_context *ctx)
* should always succeed: it's not running if the hw has gone * should always succeed: it's not running if the hw has gone
* away and is being reset. * away and is being reset.
*/ */
if (cxl_adapter_link_ok(ctx->afu->adapter)) if (cxl_ops->link_ok(ctx->afu->adapter))
rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE, rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T); CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
ctx->elem->software_state = 0; /* Remove Valid bit */ ctx->elem->software_state = 0; /* Remove Valid bit */
...@@ -405,7 +405,7 @@ static int remove_process_element(struct cxl_context *ctx) ...@@ -405,7 +405,7 @@ static int remove_process_element(struct cxl_context *ctx)
/* We could be asked to remove when the hw is down. Again, if /* We could be asked to remove when the hw is down. Again, if
* the hw is down, the PE is gone, so we succeed. * the hw is down, the PE is gone, so we succeed.
*/ */
if (cxl_adapter_link_ok(ctx->afu->adapter)) if (cxl_ops->link_ok(ctx->afu->adapter))
rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0); rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0);
if (!rc) if (!rc)
...@@ -531,7 +531,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) ...@@ -531,7 +531,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
ctx->elem->common.wed = cpu_to_be64(wed); ctx->elem->common.wed = cpu_to_be64(wed);
/* first guy needs to enable */ /* first guy needs to enable */
if ((result = cxl_afu_check_and_enable(ctx->afu))) if ((result = cxl_ops->afu_check_and_enable(ctx->afu)))
return result; return result;
return add_process_element(ctx); return add_process_element(ctx);
...@@ -547,7 +547,7 @@ static int deactivate_afu_directed(struct cxl_afu *afu) ...@@ -547,7 +547,7 @@ static int deactivate_afu_directed(struct cxl_afu *afu)
cxl_sysfs_afu_m_remove(afu); cxl_sysfs_afu_m_remove(afu);
cxl_chardev_afu_remove(afu); cxl_chardev_afu_remove(afu);
__cxl_afu_reset(afu); cxl_ops->afu_reset(afu);
cxl_afu_disable(afu); cxl_afu_disable(afu);
cxl_psl_purge(afu); cxl_psl_purge(afu);
...@@ -611,7 +611,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr) ...@@ -611,7 +611,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
/* master only context for dedicated */ /* master only context for dedicated */
cxl_assign_psn_space(ctx); cxl_assign_psn_space(ctx);
if ((rc = __cxl_afu_reset(afu))) if ((rc = cxl_ops->afu_reset(afu)))
return rc; return rc;
cxl_p2n_write(afu, CXL_PSL_WED_An, wed); cxl_p2n_write(afu, CXL_PSL_WED_An, wed);
...@@ -631,7 +631,7 @@ static int deactivate_dedicated_process(struct cxl_afu *afu) ...@@ -631,7 +631,7 @@ static int deactivate_dedicated_process(struct cxl_afu *afu)
return 0; return 0;
} }
int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode) static int cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode)
{ {
if (mode == CXL_MODE_DIRECTED) if (mode == CXL_MODE_DIRECTED)
return deactivate_afu_directed(afu); return deactivate_afu_directed(afu);
...@@ -640,19 +640,14 @@ int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode) ...@@ -640,19 +640,14 @@ int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode)
return 0; return 0;
} }
int cxl_afu_deactivate_mode(struct cxl_afu *afu) static int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
{
return _cxl_afu_deactivate_mode(afu, afu->current_mode);
}
int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
{ {
if (!mode) if (!mode)
return 0; return 0;
if (!(mode & afu->modes_supported)) if (!(mode & afu->modes_supported))
return -EINVAL; return -EINVAL;
if (!cxl_adapter_link_ok(afu->adapter)) { if (!cxl_ops->link_ok(afu->adapter)) {
WARN(1, "Device link is down, refusing to activate!\n"); WARN(1, "Device link is down, refusing to activate!\n");
return -EIO; return -EIO;
} }
...@@ -665,9 +660,9 @@ int cxl_afu_activate_mode(struct cxl_afu *afu, int mode) ...@@ -665,9 +660,9 @@ int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
return -EINVAL; return -EINVAL;
} }
int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr) static int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
{ {
if (!cxl_adapter_link_ok(ctx->afu->adapter)) { if (!cxl_ops->link_ok(ctx->afu->adapter)) {
WARN(1, "Device link is down, refusing to attach process!\n"); WARN(1, "Device link is down, refusing to attach process!\n");
return -EIO; return -EIO;
} }
...@@ -684,7 +679,7 @@ int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr) ...@@ -684,7 +679,7 @@ int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
static inline int detach_process_native_dedicated(struct cxl_context *ctx) static inline int detach_process_native_dedicated(struct cxl_context *ctx)
{ {
__cxl_afu_reset(ctx->afu); cxl_ops->afu_reset(ctx->afu);
cxl_afu_disable(ctx->afu); cxl_afu_disable(ctx->afu);
cxl_psl_purge(ctx->afu); cxl_psl_purge(ctx->afu);
return 0; return 0;
...@@ -702,7 +697,7 @@ static inline int detach_process_native_afu_directed(struct cxl_context *ctx) ...@@ -702,7 +697,7 @@ static inline int detach_process_native_afu_directed(struct cxl_context *ctx)
return 0; return 0;
} }
int cxl_detach_process(struct cxl_context *ctx) static int cxl_detach_process(struct cxl_context *ctx)
{ {
trace_cxl_detach(ctx); trace_cxl_detach(ctx);
...@@ -719,7 +714,7 @@ static int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info) ...@@ -719,7 +714,7 @@ static int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info)
/* If the adapter has gone away, we can't get any meaningful /* If the adapter has gone away, we can't get any meaningful
* information. * information.
*/ */
if (!cxl_adapter_link_ok(afu->adapter)) if (!cxl_ops->link_ok(afu->adapter))
return -EIO; return -EIO;
info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
...@@ -734,7 +729,7 @@ static int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info) ...@@ -734,7 +729,7 @@ static int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info)
return 0; return 0;
} }
irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errstat) static irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errstat)
{ {
u64 fir1, fir2, fir_slice, serr, afu_debug; u64 fir1, fir2, fir_slice, serr, afu_debug;
...@@ -754,7 +749,7 @@ irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errst ...@@ -754,7 +749,7 @@ irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errst
dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n"); dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
cxl_stop_trace(ctx->afu->adapter); cxl_stop_trace(ctx->afu->adapter);
return cxl_ack_irq(ctx, 0, errstat); return cxl_ops->ack_irq(ctx, 0, errstat);
} }
static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info) static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info)
...@@ -868,7 +863,7 @@ void cxl_release_psl_err_irq(struct cxl *adapter) ...@@ -868,7 +863,7 @@ void cxl_release_psl_err_irq(struct cxl *adapter)
cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000); cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
cxl_unmap_irq(adapter->err_virq, adapter); cxl_unmap_irq(adapter->err_virq, adapter);
cxl_release_one_irq(adapter, adapter->err_hwirq); cxl_ops->release_one_irq(adapter, adapter->err_hwirq);
kfree(adapter->irq_name); kfree(adapter->irq_name);
} }
...@@ -904,7 +899,7 @@ void cxl_release_serr_irq(struct cxl_afu *afu) ...@@ -904,7 +899,7 @@ void cxl_release_serr_irq(struct cxl_afu *afu)
cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000); cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
cxl_unmap_irq(afu->serr_virq, afu); cxl_unmap_irq(afu->serr_virq, afu);
cxl_release_one_irq(afu->adapter, afu->serr_hwirq); cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
kfree(afu->err_irq_name); kfree(afu->err_irq_name);
} }
...@@ -932,7 +927,7 @@ void cxl_release_psl_irq(struct cxl_afu *afu) ...@@ -932,7 +927,7 @@ void cxl_release_psl_irq(struct cxl_afu *afu)
return; return;
cxl_unmap_irq(afu->psl_virq, afu); cxl_unmap_irq(afu->psl_virq, afu);
cxl_release_one_irq(afu->adapter, afu->psl_hwirq); cxl_ops->release_one_irq(afu->adapter, afu->psl_hwirq);
kfree(afu->psl_irq_name); kfree(afu->psl_irq_name);
} }
...@@ -950,7 +945,7 @@ static void recover_psl_err(struct cxl_afu *afu, u64 errstat) ...@@ -950,7 +945,7 @@ static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat); cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat);
} }
int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask) static int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
{ {
trace_cxl_psl_irq_ack(ctx, tfc); trace_cxl_psl_irq_ack(ctx, tfc);
if (tfc) if (tfc)
...@@ -966,38 +961,74 @@ int cxl_check_error(struct cxl_afu *afu) ...@@ -966,38 +961,74 @@ int cxl_check_error(struct cxl_afu *afu)
return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL); return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL);
} }
u64 cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off) static int cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out)
{ {
if (likely(cxl_adapter_link_ok(afu->adapter))) if (unlikely(!cxl_ops->link_ok(afu->adapter)))
return in_le64((afu)->afu_desc_mmio + (afu)->crs_offset + return -EIO;
((cr) * (afu)->crs_len) + (off)); if (unlikely(off >= afu->crs_len))
else return -ERANGE;
return ~0ULL; *out = in_le64(afu->afu_desc_mmio + afu->crs_offset +
(cr * afu->crs_len) + off);
return 0;
} }
u32 cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off) static int cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off, u32 *out)
{ {
if (likely(cxl_adapter_link_ok(afu->adapter))) if (unlikely(!cxl_ops->link_ok(afu->adapter)))
return in_le32((afu)->afu_desc_mmio + (afu)->crs_offset + return -EIO;
((cr) * (afu)->crs_len) + (off)); if (unlikely(off >= afu->crs_len))
else return -ERANGE;
return 0xffffffff; *out = in_le32(afu->afu_desc_mmio + afu->crs_offset +
(cr * afu->crs_len) + off);
return 0;
} }
u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off) static int cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off, u16 *out)
{ {
u64 aligned_off = off & ~0x3L; u64 aligned_off = off & ~0x3L;
u32 val; u32 val;
int rc;
val = cxl_afu_cr_read32(afu, cr, aligned_off); rc = cxl_afu_cr_read32(afu, cr, aligned_off, &val);
return (val >> ((off & 0x2) * 8)) & 0xffff; if (!rc)
*out = (val >> ((off & 0x3) * 8)) & 0xffff;
return rc;
} }
u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off) static int cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off, u8 *out)
{ {
u64 aligned_off = off & ~0x3L; u64 aligned_off = off & ~0x3L;
u32 val; u32 val;
int rc;
val = cxl_afu_cr_read32(afu, cr, aligned_off); rc = cxl_afu_cr_read32(afu, cr, aligned_off, &val);
return (val >> ((off & 0x3) * 8)) & 0xff; if (!rc)
*out = (val >> ((off & 0x3) * 8)) & 0xff;
return rc;
} }
const struct cxl_backend_ops cxl_native_ops = {
.module = THIS_MODULE,
.adapter_reset = cxl_reset,
.alloc_one_irq = cxl_alloc_one_irq,
.release_one_irq = cxl_release_one_irq,
.alloc_irq_ranges = cxl_alloc_irq_ranges,
.release_irq_ranges = cxl_release_irq_ranges,
.setup_irq = cxl_setup_irq,
.handle_psl_slice_error = handle_psl_slice_error,
.psl_interrupt = NULL,
.ack_irq = cxl_ack_irq,
.attach_process = cxl_attach_process,
.detach_process = cxl_detach_process,
.link_ok = cxl_adapter_link_ok,
.release_afu = cxl_release_afu,
.afu_read_err_buffer = cxl_afu_read_err_buffer,
.afu_check_and_enable = cxl_afu_check_and_enable,
.afu_activate_mode = cxl_afu_activate_mode,
.afu_deactivate_mode = cxl_afu_deactivate_mode,
.afu_reset = __cxl_afu_reset,
.afu_cr_read8 = cxl_afu_cr_read8,
.afu_cr_read16 = cxl_afu_cr_read16,
.afu_cr_read32 = cxl_afu_cr_read32,
.afu_cr_read64 = cxl_afu_cr_read64,
};
...@@ -646,7 +646,8 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu) ...@@ -646,7 +646,8 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu)
static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu) static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu)
{ {
int i; int i, rc;
u32 val;
if (afu->psa && afu->adapter->ps_size < if (afu->psa && afu->adapter->ps_size <
(afu->pp_offset + afu->pp_size*afu->max_procs_virtualised)) { (afu->pp_offset + afu->pp_size*afu->max_procs_virtualised)) {
...@@ -658,7 +659,8 @@ static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu) ...@@ -658,7 +659,8 @@ static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu)
dev_warn(&afu->dev, "AFU uses < PAGE_SIZE per-process PSA!"); dev_warn(&afu->dev, "AFU uses < PAGE_SIZE per-process PSA!");
for (i = 0; i < afu->crs_num; i++) { for (i = 0; i < afu->crs_num; i++) {
if ((cxl_afu_cr_read32(afu, i, 0) == 0)) { rc = cxl_ops->afu_cr_read32(afu, i, 0, &val);
if (rc || val == 0) {
dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i); dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i);
return -EINVAL; return -EINVAL;
} }
...@@ -679,7 +681,7 @@ static int sanitise_afu_regs(struct cxl_afu *afu) ...@@ -679,7 +681,7 @@ static int sanitise_afu_regs(struct cxl_afu *afu)
reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An); reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) { if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg); dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg);
if (__cxl_afu_reset(afu)) if (cxl_ops->afu_reset(afu))
return -EIO; return -EIO;
if (cxl_afu_disable(afu)) if (cxl_afu_disable(afu))
return -EIO; return -EIO;
...@@ -775,7 +777,7 @@ static int cxl_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc ...@@ -775,7 +777,7 @@ static int cxl_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc
goto err1; goto err1;
/* We need to reset the AFU before we can read the AFU descriptor */ /* We need to reset the AFU before we can read the AFU descriptor */
if ((rc = __cxl_afu_reset(afu))) if ((rc = cxl_ops->afu_reset(afu)))
goto err1; goto err1;
if (cxl_verbose) if (cxl_verbose)
...@@ -876,7 +878,7 @@ static void cxl_remove_afu(struct cxl_afu *afu) ...@@ -876,7 +878,7 @@ static void cxl_remove_afu(struct cxl_afu *afu)
spin_unlock(&afu->adapter->afu_list_lock); spin_unlock(&afu->adapter->afu_list_lock);
cxl_context_detach_all(afu); cxl_context_detach_all(afu);
cxl_afu_deactivate_mode(afu); cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
cxl_deconfigure_afu(afu); cxl_deconfigure_afu(afu);
device_unregister(&afu->dev); device_unregister(&afu->dev);
...@@ -1398,7 +1400,7 @@ static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev, ...@@ -1398,7 +1400,7 @@ static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
return result; return result;
cxl_context_detach_all(afu); cxl_context_detach_all(afu);
cxl_afu_deactivate_mode(afu); cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
cxl_deconfigure_afu(afu); cxl_deconfigure_afu(afu);
} }
cxl_deconfigure_adapter(adapter); cxl_deconfigure_adapter(adapter);
...@@ -1445,7 +1447,7 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev) ...@@ -1445,7 +1447,7 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
afu_dev->dev.archdata.cxl_ctx = ctx; afu_dev->dev.archdata.cxl_ctx = ctx;
if (cxl_afu_check_and_enable(afu)) if (cxl_ops->afu_check_and_enable(afu))
goto err; goto err;
afu_dev->error_state = pci_channel_io_normal; afu_dev->error_state = pci_channel_io_normal;
......
...@@ -69,7 +69,7 @@ static ssize_t reset_adapter_store(struct device *device, ...@@ -69,7 +69,7 @@ static ssize_t reset_adapter_store(struct device *device,
if ((rc != 1) || (val != 1)) if ((rc != 1) || (val != 1))
return -EINVAL; return -EINVAL;
if ((rc = cxl_reset(adapter))) if ((rc = cxl_ops->adapter_reset(adapter)))
return rc; return rc;
return count; return count;
} }
...@@ -211,7 +211,7 @@ static ssize_t reset_store_afu(struct device *device, ...@@ -211,7 +211,7 @@ static ssize_t reset_store_afu(struct device *device,
goto err; goto err;
} }
if ((rc = __cxl_afu_reset(afu))) if ((rc = cxl_ops->afu_reset(afu)))
goto err; goto err;
rc = count; rc = count;
...@@ -348,7 +348,7 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr, ...@@ -348,7 +348,7 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr,
} }
/* /*
* cxl_afu_deactivate_mode needs to be done outside the lock, prevent * afu_deactivate_mode needs to be done outside the lock, prevent
* other contexts coming in before we are ready: * other contexts coming in before we are ready:
*/ */
old_mode = afu->current_mode; old_mode = afu->current_mode;
...@@ -357,9 +357,9 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr, ...@@ -357,9 +357,9 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr,
mutex_unlock(&afu->contexts_lock); mutex_unlock(&afu->contexts_lock);
if ((rc = _cxl_afu_deactivate_mode(afu, old_mode))) if ((rc = cxl_ops->afu_deactivate_mode(afu, old_mode)))
return rc; return rc;
if ((rc = cxl_afu_activate_mode(afu, mode))) if ((rc = cxl_ops->afu_activate_mode(afu, mode)))
return rc; return rc;
return count; return count;
...@@ -389,7 +389,7 @@ static ssize_t afu_eb_read(struct file *filp, struct kobject *kobj, ...@@ -389,7 +389,7 @@ static ssize_t afu_eb_read(struct file *filp, struct kobject *kobj,
struct cxl_afu *afu = to_cxl_afu(container_of(kobj, struct cxl_afu *afu = to_cxl_afu(container_of(kobj,
struct device, kobj)); struct device, kobj));
return cxl_afu_read_err_buffer(afu, buf, off, count); return cxl_ops->afu_read_err_buffer(afu, buf, off, count);
} }
static struct device_attribute afu_attrs[] = { static struct device_attribute afu_attrs[] = {
...@@ -469,10 +469,12 @@ static ssize_t afu_read_config(struct file *filp, struct kobject *kobj, ...@@ -469,10 +469,12 @@ static ssize_t afu_read_config(struct file *filp, struct kobject *kobj,
struct afu_config_record *cr = to_cr(kobj); struct afu_config_record *cr = to_cr(kobj);
struct cxl_afu *afu = to_cxl_afu(container_of(kobj->parent, struct device, kobj)); struct cxl_afu *afu = to_cxl_afu(container_of(kobj->parent, struct device, kobj));
u64 i, j, val; u64 i, j, val, rc;
for (i = 0; i < count;) { for (i = 0; i < count;) {
val = cxl_afu_cr_read64(afu, cr->cr, off & ~0x7); rc = cxl_ops->afu_cr_read64(afu, cr->cr, off & ~0x7, &val);
if (rc)
val = ~0ULL;
for (j = off & 0x7; j < 8 && i < count; i++, j++, off++) for (j = off & 0x7; j < 8 && i < count; i++, j++, off++)
buf[i] = (val >> (j * 8)) & 0xff; buf[i] = (val >> (j * 8)) & 0xff;
} }
...@@ -517,9 +519,17 @@ static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int c ...@@ -517,9 +519,17 @@ static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int c
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
cr->cr = cr_idx; cr->cr = cr_idx;
cr->device = cxl_afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID);
cr->vendor = cxl_afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID); rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID, &cr->device);
cr->class = cxl_afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION) >> 8; if (rc)
goto err;
rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID, &cr->vendor);
if (rc)
goto err;
rc = cxl_ops->afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION, &cr->class);
if (rc)
goto err;
cr->class >>= 8;
/* /*
* Export raw AFU PCIe like config record. For now this is read only by * Export raw AFU PCIe like config record. For now this is read only by
......
...@@ -49,7 +49,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev) ...@@ -49,7 +49,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
phb = pci_bus_to_host(dev->bus); phb = pci_bus_to_host(dev->bus);
afu = (struct cxl_afu *)phb->private_data; afu = (struct cxl_afu *)phb->private_data;
if (!cxl_adapter_link_ok(afu->adapter)) { if (!cxl_ops->link_ok(afu->adapter)) {
dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__); dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__);
return false; return false;
} }
...@@ -66,7 +66,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev) ...@@ -66,7 +66,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
return false; return false;
dev->dev.archdata.cxl_ctx = ctx; dev->dev.archdata.cxl_ctx = ctx;
return (cxl_afu_check_and_enable(afu) == 0); return (cxl_ops->afu_check_and_enable(afu) == 0);
} }
static void cxl_pci_disable_device(struct pci_dev *dev) static void cxl_pci_disable_device(struct pci_dev *dev)
...@@ -161,7 +161,7 @@ static inline bool cxl_config_link_ok(struct pci_bus *bus) ...@@ -161,7 +161,7 @@ static inline bool cxl_config_link_ok(struct pci_bus *bus)
if (phb == NULL) if (phb == NULL)
return false; return false;
afu = (struct cxl_afu *)phb->private_data; afu = (struct cxl_afu *)phb->private_data;
return cxl_adapter_link_ok(afu->adapter); return cxl_ops->link_ok(afu->adapter);
} }
static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn, static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment