summaryrefslogtreecommitdiff
path: root/drivers/dma/idxd/idxd.h
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@linux.intel.com>2023-12-05 15:25:22 -0600
committerHerbert Xu <herbert@gondor.apana.org.au>2023-12-15 17:52:53 +0800
commitaa8d18becc0c14aa3eb46d6d1b81450446e11b87 (patch)
tree6d1151732bff0c0174e27a1d209d3dbeb002daad /drivers/dma/idxd/idxd.h
parent786d0e7f183ac1c1aef1801c2110f7582f0a6a83 (diff)
downloadlwn-aa8d18becc0c14aa3eb46d6d1b81450446e11b87.tar.gz
lwn-aa8d18becc0c14aa3eb46d6d1b81450446e11b87.zip
dmaengine: idxd: add callback support for iaa crypto
Create a lightweight callback interface to allow idxd sub-drivers to be notified when work sent to idxd wqs has completed. For a sub-driver to be notified of work completion, it needs to: - Set the descriptor's 'Request Completion Interrupt' (IDXD_OP_FLAG_RCI) - Set the sub-driver desc_complete() callback when registering the sub-driver e.g.: struct idxd_device_driver my_drv = { .probe = my_probe, .desc_complete = my_complete, } - Set the sub-driver-specific context in the sub-driver's descriptor e.g: idxd_desc->crypto.req = req; idxd_desc->crypto.tfm = tfm; idxd_desc->crypto.src_addr = src_addr; idxd_desc->crypto.dst_addr = dst_addr; When the work completes and the completion irq fires, idxd will invoke the desc_complete() callback with pointers to the descriptor, context, and completion_type. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Reviewed-by: Fenghua Yu <fenghua.yu@intel.com> Acked-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/dma/idxd/idxd.h')
-rw-r--r--drivers/dma/idxd/idxd.h62
1 files changed, 52 insertions, 10 deletions
diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
index 4b67181f4396..62ea21b25906 100644
--- a/drivers/dma/idxd/idxd.h
+++ b/drivers/dma/idxd/idxd.h
@@ -13,6 +13,7 @@
#include <linux/bitmap.h>
#include <linux/perf_event.h>
#include <linux/iommu.h>
+#include <linux/crypto.h>
#include <uapi/linux/idxd.h>
#include "registers.h"
@@ -57,11 +58,23 @@ enum idxd_type {
#define IDXD_ENQCMDS_RETRIES 32
#define IDXD_ENQCMDS_MAX_RETRIES 64
+enum idxd_complete_type {
+ IDXD_COMPLETE_NORMAL = 0,
+ IDXD_COMPLETE_ABORT,
+ IDXD_COMPLETE_DEV_FAIL,
+};
+
+struct idxd_desc;
+
struct idxd_device_driver {
const char *name;
enum idxd_dev_type *type;
int (*probe)(struct idxd_dev *idxd_dev);
void (*remove)(struct idxd_dev *idxd_dev);
+ void (*desc_complete)(struct idxd_desc *desc,
+ enum idxd_complete_type comp_type,
+ bool free_desc,
+ void *ctx, u32 *status);
struct device_driver drv;
};
@@ -174,12 +187,6 @@ enum idxd_op_type {
IDXD_OP_NONBLOCK = 1,
};
-enum idxd_complete_type {
- IDXD_COMPLETE_NORMAL = 0,
- IDXD_COMPLETE_ABORT,
- IDXD_COMPLETE_DEV_FAIL,
-};
-
struct idxd_dma_chan {
struct dma_chan chan;
struct idxd_wq *wq;
@@ -378,6 +385,14 @@ static inline unsigned int evl_size(struct idxd_device *idxd)
return idxd->evl->size * evl_ent_size(idxd);
}
+struct crypto_ctx {
+ struct acomp_req *req;
+ struct crypto_tfm *tfm;
+ dma_addr_t src_addr;
+ dma_addr_t dst_addr;
+ bool compress;
+};
+
/* IDXD software descriptor */
struct idxd_desc {
union {
@@ -390,7 +405,10 @@ struct idxd_desc {
struct iax_completion_record *iax_completion;
};
dma_addr_t compl_dma;
- struct dma_async_tx_descriptor txd;
+ union {
+ struct dma_async_tx_descriptor txd;
+ struct crypto_ctx crypto;
+ };
struct llist_node llnode;
struct list_head list;
int id;
@@ -417,6 +435,15 @@ enum idxd_completion_status {
#define idxd_dev_to_idxd(idxd_dev) container_of(idxd_dev, struct idxd_device, idxd_dev)
#define idxd_dev_to_wq(idxd_dev) container_of(idxd_dev, struct idxd_wq, idxd_dev)
+static inline struct idxd_device_driver *wq_to_idxd_drv(struct idxd_wq *wq)
+{
+ struct device *dev = wq_confdev(wq);
+ struct idxd_device_driver *idxd_drv =
+ container_of(dev->driver, struct idxd_device_driver, drv);
+
+ return idxd_drv;
+}
+
static inline struct idxd_device *confdev_to_idxd(struct device *dev)
{
struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);
@@ -678,6 +705,24 @@ void idxd_driver_unregister(struct idxd_device_driver *idxd_drv);
#define module_idxd_driver(__idxd_driver) \
module_driver(__idxd_driver, idxd_driver_register, idxd_driver_unregister)
+void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc);
+void idxd_dma_complete_txd(struct idxd_desc *desc,
+ enum idxd_complete_type comp_type,
+ bool free_desc, void *ctx, u32 *status);
+
+static inline void idxd_desc_complete(struct idxd_desc *desc,
+ enum idxd_complete_type comp_type,
+ bool free_desc)
+{
+ struct idxd_device_driver *drv;
+ u32 status;
+
+ drv = wq_to_idxd_drv(desc->wq);
+ if (drv->desc_complete)
+ drv->desc_complete(desc, comp_type, free_desc,
+ &desc->txd, &status);
+}
+
int idxd_register_bus_type(void);
void idxd_unregister_bus_type(void);
int idxd_register_devices(struct idxd_device *idxd);
@@ -731,14 +776,11 @@ int idxd_wq_request_irq(struct idxd_wq *wq);
/* submission */
int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);
struct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype);
-void idxd_free_desc(struct idxd_wq *wq, struct idxd_desc *desc);
int idxd_enqcmds(struct idxd_wq *wq, void __iomem *portal, const void *desc);
/* dmaengine */
int idxd_register_dma_device(struct idxd_device *idxd);
void idxd_unregister_dma_device(struct idxd_device *idxd);
-void idxd_dma_complete_txd(struct idxd_desc *desc,
- enum idxd_complete_type comp_type, bool free_desc);
/* cdev */
int idxd_cdev_register(void);