From: Weili Qian <qianweili(a)huawei.com>
UADK adds the ability to obtain device usage. When the device
is not bound to a driver, it retrieves the usage through sysfs
files. When the device is bound to a driver, it directly reads the
hardware registers to obtain the usage.
Upstream: Yes
AR: AR20230722287656
Feature or Bugfix: Feature
Signed-off-by: Weili Qian <qianweili(a)huawei.com>
---
drv/hisi_comp.c | 39 +++++++++
drv/hisi_dae.c | 5 --
drv/hisi_dae.h | 1 +
drv/hisi_dae_common.c | 38 +++++++++
drv/hisi_dae_join_gather.c | 1 +
drv/hisi_hpre.c | 69 ++++++++++++++--
drv/hisi_qm_udrv.c | 36 +++++++++
drv/hisi_qm_udrv.h | 1 +
drv/hisi_sec.c | 35 +++++++-
drv/hisi_udma.c | 35 +++++++-
include/wd.h | 8 ++
include/wd_alg.h | 9 +++
libwd.map | 3 +
wd.c | 162 +++++++++++++++++++++++++++++++++++++
wd_alg.c | 124 ++++++++++++++++++++++++++++
wd_util.c | 93 ++-------------------
16 files changed, 560 insertions(+), 99 deletions(-)
diff --git a/drv/hisi_comp.c b/drv/hisi_comp.c
index 65dcf8e..cad21fa 100644
--- a/drv/hisi_comp.c
+++ b/drv/hisi_comp.c
@@ -1755,6 +1755,44 @@ static int hisi_zip_comp_recv(struct wd_alg_driver *drv, handle_t ctx, void *com
return 0;
}
+static int hisi_zip_get_usage(void *param)
+{
+ struct hisi_dev_usage *zip_usage = (struct hisi_dev_usage *)param;
+ struct wd_alg_driver *drv = zip_usage->drv;
+ struct wd_ctx_config_internal *config;
+ struct hisi_zip_ctx *priv;
+ char *ctx_dev_name;
+ handle_t ctx = 0;
+ handle_t qp = 0;
+ __u32 i;
+
+ if (zip_usage->alg_op_type >= drv->op_type_num) {
+ WD_ERR("invalid: alg_op_type %u is error!\n", zip_usage->alg_op_type);
+ return -WD_EINVAL;
+ }
+
+ priv = (struct hisi_zip_ctx *)drv->priv;
+ if (!priv)
+ return -WD_EACCES;
+
+ config = &priv->config;
+ for (i = 0; i < config->ctx_num; i++) {
+ ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx);
+ if (!strcmp(zip_usage->dev_name, ctx_dev_name)) {
+ ctx = config->ctxs[i].ctx;
+ break;
+ }
+ }
+
+ if (ctx)
+ qp = (handle_t)wd_ctx_get_priv(ctx);
+
+ if (qp)
+ return hisi_qm_get_usage(qp, zip_usage->alg_op_type);
+
+ return -WD_EACCES;
+}
+
#define GEN_ZIP_ALG_DRIVER(zip_alg_name) \
{\
.drv_name = "hisi_zip",\
@@ -1768,6 +1806,7 @@ static int hisi_zip_comp_recv(struct wd_alg_driver *drv, handle_t ctx, void *com
.exit = hisi_zip_exit,\
.send = hisi_zip_comp_send,\
.recv = hisi_zip_comp_recv,\
+ .get_usage = hisi_zip_get_usage, \
}
static struct wd_alg_driver zip_alg_driver[] = {
diff --git a/drv/hisi_dae.c b/drv/hisi_dae.c
index 49387aa..d7b34c2 100644
--- a/drv/hisi_dae.c
+++ b/drv/hisi_dae.c
@@ -1283,11 +1283,6 @@ static int agg_hash_table_init(struct wd_alg_driver *drv,
hash_table, agg_ctx->row_size);
}
-static int dae_get_usage(void *param)
-{
- return 0;
-}
-
static int dae_get_extend_ops(void *ops)
{
struct wd_agg_ops *agg_ops = (struct wd_agg_ops *)ops;
diff --git a/drv/hisi_dae.h b/drv/hisi_dae.h
index 050b872..f82b13c 100644
--- a/drv/hisi_dae.h
+++ b/drv/hisi_dae.h
@@ -220,6 +220,7 @@ int get_free_ext_addr(struct dae_extend_addr *ext_addr);
void put_ext_addr(struct dae_extend_addr *ext_addr, int idx);
__u32 get_data_type_size(enum dae_data_type type, __u16 data_info);
int dae_decimal_precision_check(__u16 data_info, bool longdecimal);
+int dae_get_usage(void *param);
#ifdef __cplusplus
}
diff --git a/drv/hisi_dae_common.c b/drv/hisi_dae_common.c
index 5cfc105..c077d1d 100644
--- a/drv/hisi_dae_common.c
+++ b/drv/hisi_dae_common.c
@@ -389,3 +389,41 @@ void dae_exit(struct wd_alg_driver *drv)
free(priv);
drv->priv = NULL;
}
+
+int dae_get_usage(void *param)
+{
+ struct hisi_dev_usage *dae_usage = (struct hisi_dev_usage *)param;
+ struct wd_alg_driver *drv = dae_usage->drv;
+ struct wd_ctx_config_internal *config;
+ struct hisi_dae_ctx *priv;
+ char *ctx_dev_name;
+ handle_t ctx = 0;
+ handle_t qp = 0;
+ __u32 i;
+
+ if (dae_usage->alg_op_type >= drv->op_type_num) {
+ WD_ERR("invalid: alg_op_type %u is error!\n", dae_usage->alg_op_type);
+ return -WD_EINVAL;
+ }
+
+ priv = (struct hisi_dae_ctx *)drv->priv;
+ if (!priv)
+ return -WD_EACCES;
+
+ config = &priv->config;
+ for (i = 0; i < config->ctx_num; i++) {
+ ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx);
+ if (!strcmp(dae_usage->dev_name, ctx_dev_name)) {
+ ctx = config->ctxs[i].ctx;
+ break;
+ }
+ }
+
+ if (ctx)
+ qp = (handle_t)wd_ctx_get_priv(ctx);
+
+ if (qp)
+ return hisi_qm_get_usage(qp, DAE_SQC_ALG_TYPE);
+
+ return -WD_EACCES;
+}
diff --git a/drv/hisi_dae_join_gather.c b/drv/hisi_dae_join_gather.c
index 63c7670..92fae1a 100644
--- a/drv/hisi_dae_join_gather.c
+++ b/drv/hisi_dae_join_gather.c
@@ -1007,6 +1007,7 @@ static int join_gather_get_extend_ops(void *ops)
.send = join_gather_send,\
.recv = join_gather_recv,\
.get_extend_ops = join_gather_get_extend_ops,\
+ .get_usage = dae_get_usage,\
}
static struct wd_alg_driver join_gather_driver[] = {
diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c
index f3f2451..3c41826 100644
--- a/drv/hisi_hpre.c
+++ b/drv/hisi_hpre.c
@@ -2777,9 +2777,68 @@ static int ecc_recv(struct wd_alg_driver *drv, handle_t ctx, void *ecc_msg)
return ecc_sqe_parse((struct hisi_qp *)h_qp, msg, &hw_msg);
}
-static int hpre_get_usage(void *param)
+static handle_t hpre_find_dev_qp(struct wd_alg_driver *drv, const char *dev_name)
{
- return WD_SUCCESS;
+ struct wd_ctx_config_internal *config;
+ struct hisi_hpre_ctx *priv;
+ char *ctx_dev_name;
+ handle_t ctx = 0;
+ handle_t qp = 0;
+ __u32 i;
+
+ priv = (struct hisi_hpre_ctx *)drv->priv;
+ if (!priv)
+ return 0;
+
+ config = &priv->config;
+ for (i = 0; i < config->ctx_num; i++) {
+ ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx);
+ if (!strcmp(ctx_dev_name, dev_name)) {
+ ctx = config->ctxs[i].ctx;
+ break;
+ }
+ }
+
+ if (ctx)
+ qp = (handle_t)wd_ctx_get_priv(ctx);
+
+ return qp;
+}
+
+static int hpre_ecc_get_usage(void *param)
+{
+ struct hisi_dev_usage *hpre_usage = (struct hisi_dev_usage *)param;
+ struct wd_alg_driver *drv = hpre_usage->drv;
+ handle_t qp;
+
+ if (hpre_usage->alg_op_type >= drv->op_type_num) {
+ WD_ERR("invalid: alg_op_type %u is error!\n", hpre_usage->alg_op_type);
+ return -WD_EINVAL;
+ }
+
+ qp = hpre_find_dev_qp(drv, hpre_usage->dev_name);
+ if (qp)
+ return hisi_qm_get_usage(qp, HPRE_HW_V3_ECC_ALG_TYPE);
+
+ return -WD_EACCES;
+}
+
+static int hpre_rsa_get_usage(void *param)
+{
+ struct hisi_dev_usage *hpre_usage = (struct hisi_dev_usage *)param;
+ struct wd_alg_driver *drv = hpre_usage->drv;
+ handle_t qp;
+
+ if (hpre_usage->alg_op_type >= drv->op_type_num) {
+ WD_ERR("invalid: alg_op_type %u is error!\n", hpre_usage->alg_op_type);
+ return -WD_EINVAL;
+ }
+
+ qp = hpre_find_dev_qp(drv, hpre_usage->dev_name);
+ if (qp)
+ return hisi_qm_get_usage(qp, HPRE_HW_V2_ALG_TYPE);
+
+ return -WD_EACCES;
}
static int ecc_sess_eops_init(struct wd_alg_driver *drv, void **params)
@@ -2886,7 +2945,7 @@ static int hpre_ecc_get_extend_ops(void *ops)
.exit = hpre_exit,\
.send = ecc_send,\
.recv = ecc_recv,\
- .get_usage = hpre_get_usage,\
+ .get_usage = hpre_ecc_get_usage,\
.get_extend_ops = hpre_ecc_get_extend_ops,\
}
@@ -2910,7 +2969,7 @@ static struct wd_alg_driver hpre_rsa_driver = {
.exit = hpre_exit,
.send = rsa_send,
.recv = rsa_recv,
- .get_usage = hpre_get_usage,
+ .get_usage = hpre_rsa_get_usage,
};
static struct wd_alg_driver hpre_dh_driver = {
@@ -2925,7 +2984,7 @@ static struct wd_alg_driver hpre_dh_driver = {
.exit = hpre_exit,
.send = dh_send,
.recv = dh_recv,
- .get_usage = hpre_get_usage,
+ .get_usage = hpre_rsa_get_usage,
};
#ifdef WD_STATIC_DRV
diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c
index 216b80a..4ddf8a8 100644
--- a/drv/hisi_qm_udrv.c
+++ b/drv/hisi_qm_udrv.c
@@ -42,6 +42,12 @@
#define ADDR_ALIGN_64(addr) ((((uintptr_t)(addr) >> 6) + 1) << 6)
+#define QM_TYPE_USAGE_OFFSET 0x1100
+#define QM_DEV_USAGE_OFFSET 16
+#define QM_CHANNEL_ADDR_INTRVL 0x4
+#define QM_MAX_DEV_USAGE 100
+#define QM_DEV_USAGE_RATE 100
+
struct hisi_qm_type {
__u16 qm_ver;
int qm_db_offs;
@@ -154,6 +160,36 @@ static struct hisi_qm_type qm_type[] = {
}
};
+int hisi_qm_get_usage(handle_t h_qp, __u8 type)
+{
+ struct hisi_qp *qp = (struct hisi_qp *)h_qp;
+ struct hisi_qm_queue_info *q_info;
+ __u16 count, usage;
+ __u32 val;
+
+ if (!qp)
+ return -WD_EINVAL;
+
+ q_info = &qp->q_info;
+ if (q_info->hw_type < HISI_QM_API_VER5_BASE) {
+ WD_ERR("invalid: device not support get usage!\n");
+ return -WD_EINVAL;
+ }
+
+ val = wd_ioread32(q_info->mmio_base + QM_TYPE_USAGE_OFFSET +
+ type * QM_CHANNEL_ADDR_INTRVL);
+ count = val >> QM_DEV_USAGE_OFFSET;
+ if (!count) {
+ WD_ERR("failed to get dev count usage!\n");
+ return -WD_EINVAL;
+ }
+
+ usage = (__u16)val * QM_DEV_USAGE_RATE / count;
+ usage = usage > QM_MAX_DEV_USAGE ? QM_MAX_DEV_USAGE : usage;
+
+ return usage;
+}
+
static void hisi_qm_fill_sqe(const void *sqe, struct hisi_qm_queue_info *info,
__u16 tail, __u16 num)
{
diff --git a/drv/hisi_qm_udrv.h b/drv/hisi_qm_udrv.h
index f066881..a7222ce 100644
--- a/drv/hisi_qm_udrv.h
+++ b/drv/hisi_qm_udrv.h
@@ -210,6 +210,7 @@ int hisi_qm_get_free_sqe_num(handle_t h_qp);
*/
__u32 hisi_qm_get_list_size(struct wd_datalist *start_node,
struct wd_datalist *end_node);
+int hisi_qm_get_usage(handle_t h_qp, __u8 type);
#ifdef __cplusplus
}
diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c
index e64fd5c..53bf334 100644
--- a/drv/hisi_sec.c
+++ b/drv/hisi_sec.c
@@ -600,7 +600,40 @@ static int aead_recv(struct wd_alg_driver *drv, handle_t ctx, void *msg)
static int hisi_sec_get_usage(void *param)
{
- return 0;
+ struct hisi_dev_usage *sec_usage = (struct hisi_dev_usage *)param;
+ struct wd_alg_driver *drv = sec_usage->drv;
+ struct wd_ctx_config_internal *config;
+ struct hisi_sec_ctx *priv;
+ char *ctx_dev_name;
+ handle_t ctx = 0;
+ handle_t qp = 0;
+ __u32 i;
+
+ if (sec_usage->alg_op_type >= drv->op_type_num) {
+ WD_ERR("invalid: alg_op_type %u is error!\n", sec_usage->alg_op_type);
+ return -WD_EINVAL;
+ }
+
+ priv = (struct hisi_sec_ctx *)drv->priv;
+ if (!priv)
+ return -WD_EACCES;
+
+ config = &priv->config;
+ for (i = 0; i < config->ctx_num; i++) {
+ ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx);
+ if (!strcmp(sec_usage->dev_name, ctx_dev_name)) {
+ ctx = config->ctxs[i].ctx;
+ break;
+ }
+ }
+
+ if (ctx)
+ qp = (handle_t)wd_ctx_get_priv(ctx);
+
+ if (qp)
+ return hisi_qm_get_usage(qp, 0);
+
+ return -WD_EACCES;
}
static int eops_param_check(struct wd_alg_driver *drv, struct wd_mm_ops *mm_ops)
diff --git a/drv/hisi_udma.c b/drv/hisi_udma.c
index 37f0550..a9f5607 100644
--- a/drv/hisi_udma.c
+++ b/drv/hisi_udma.c
@@ -521,7 +521,40 @@ static void udma_exit(struct wd_alg_driver *drv)
static int udma_get_usage(void *param)
{
- return 0;
+ struct hisi_dev_usage *udma_usage = (struct hisi_dev_usage *)param;
+ struct wd_alg_driver *drv = udma_usage->drv;
+ struct wd_ctx_config_internal *config;
+ struct hisi_udma_ctx *priv;
+ char *ctx_dev_name;
+ handle_t ctx = 0;
+ handle_t qp = 0;
+ __u32 i;
+
+ if (udma_usage->alg_op_type >= drv->op_type_num) {
+ WD_ERR("invalid: alg_op_type %u is error!\n", udma_usage->alg_op_type);
+ return -WD_EINVAL;
+ }
+
+ priv = (struct hisi_udma_ctx *)drv->priv;
+ if (!priv)
+ return -WD_EACCES;
+
+ config = &priv->config;
+ for (i = 0; i < config->ctx_num; i++) {
+ ctx_dev_name = wd_ctx_get_dev_name(config->ctxs[i].ctx);
+ if (!strcmp(udma_usage->dev_name, ctx_dev_name)) {
+ ctx = config->ctxs[i].ctx;
+ break;
+ }
+ }
+
+ if (ctx)
+ qp = (handle_t)wd_ctx_get_priv(ctx);
+
+ if (qp)
+ return hisi_qm_get_usage(qp, UDMA_ALG_TYPE);
+
+ return -WD_EACCES;
}
static struct wd_alg_driver udma_driver = {
diff --git a/include/wd.h b/include/wd.h
index b97e5c7..abc745d 100644
--- a/include/wd.h
+++ b/include/wd.h
@@ -627,6 +627,14 @@ struct wd_capability {
struct wd_capability *wd_get_alg_cap(void);
void wd_release_alg_cap(struct wd_capability *head);
+/**
+ * wd_get_dev_usage() - Get the device bandwidth usage.
+ * @dev: Indicate device.
+ * @alg_name: Indicates the intention to query the bandwidth usage of the algorithm on the device.
+ * @alg_op_type: algorithm type.
+ */
+int wd_get_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 alg_op_type);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/wd_alg.h b/include/wd_alg.h
index 5ff73ca..878c595 100644
--- a/include/wd_alg.h
+++ b/include/wd_alg.h
@@ -115,6 +115,12 @@ struct wd_alg_driver {
int (*get_extend_ops)(void *ops);
};
+struct hisi_dev_usage {
+ struct wd_alg_driver *drv;
+ char *dev_name;
+ __u8 alg_op_type;
+};
+
/*
* wd_alg_driver_register() - Register a device driver.
* @wd_alg_driver: a device driver that supports an algorithm.
@@ -145,6 +151,7 @@ struct wd_alg_list {
struct wd_alg_driver *drv;
struct wd_alg_list *next;
+ char alg_type[ALG_NAME_SIZE];
};
/*
@@ -178,6 +185,8 @@ int wd_alg_driver_init(struct wd_alg_driver *drv, void *conf);
void wd_alg_driver_exit(struct wd_alg_driver *drv);
int wd_alg_driver_send(struct wd_alg_driver *drv, handle_t ctx, void *msg);
int wd_alg_driver_recv(struct wd_alg_driver *drv, handle_t ctx, void *msg);
+int wd_alg_get_dev_usage(const char *dev_name, const char *alg_type, __u8 op_type);
+int wd_get_alg_type(const char *alg_name, char *alg_type);
struct wd_alg_list *wd_get_alg_head(void);
diff --git a/libwd.map b/libwd.map
index 90eb5c5..1267a8d 100644
--- a/libwd.map
+++ b/libwd.map
@@ -22,6 +22,7 @@ global:
wd_ctx_set_io_cmd;
wd_ctx_get_region_size;
wd_ctx_get_dev_name;
+ wd_get_dev_usage;
wd_block_alloc;
wd_block_free;
@@ -53,6 +54,8 @@ global:
wd_alg_driver_exit;
wd_alg_driver_send;
wd_alg_driver_recv;
+ wd_alg_get_dev_usage;
+ wd_get_alg_type;
wd_find_ctx;
wd_get_dev_id;
diff --git a/wd.c b/wd.c
index 657fbae..7f26f84 100644
--- a/wd.c
+++ b/wd.c
@@ -23,6 +23,7 @@
#include "wd_internal.h"
#define SYS_CLASS_DIR "/sys/class/uacce"
#define FILE_MAX_SIZE (8 << 20)
+#define WD_DEV_USAGE_SIZE 256
enum UADK_LOG_LEVEL {
WD_LOG_NONE = 0,
@@ -34,6 +35,27 @@ enum UADK_LOG_LEVEL {
static int uadk_log_level = WD_LOG_INVALID;
+struct dev_usage_info {
+ char *dev_name;
+ __u8 alg_op_type;
+ int (*usage_parse_fn)(char *buf, const char *alg_name, __u8 alg_op_type);
+};
+
+static const char * const hpre_ecc_algs[] = {
+ "sm2",
+ "ecdh",
+ "x448",
+ "x25519",
+ "ecdsa"
+};
+
+static const char * const zip_dae_algs[] = {
+ "udma",
+ "hashagg",
+ "hashjoin",
+ "gather",
+};
+
static int wd_check_ctx_type(handle_t h_ctx)
{
struct wd_ctx_h *ctx = (struct wd_ctx_h *)h_ctx;
@@ -986,3 +1008,143 @@ alloc_err:
return NULL;
}
+static int wd_parse_usage_value(char *buf, const char *type_name)
+{
+ char *str;
+ int ret;
+
+ str = strstr(buf, type_name);
+ if (!str)
+ return -WD_EINVAL;
+
+ str += strlen(type_name);
+ ret = strtol(str, NULL, 10);
+ if (ret < 0)
+ WD_ERR("fail to get device usage value, ret %d!\n", ret);
+
+ return ret;
+}
+
+/*
+ * The format of the string obtained from sysfs is fixed
+ * and does not need to consider other scenarios.
+ */
+static int wd_zip_usage_parse_fn(char *buf, const char *alg_name, __u8 alg_op_type)
+{
+ size_t size = ARRAY_SIZE(zip_dae_algs);
+ size_t i;
+
+ for (i = 0; i < size; i++) {
+ if (!strcmp(alg_name, zip_dae_algs[i])) {
+ if (alg_op_type != 0) {
+ WD_ERR("invalid: alg_name %s alg_op_type error!\n", alg_name);
+ return -WD_EINVAL;
+ }
+ return wd_parse_usage_value(buf, "DAE: ");
+ }
+ }
+
+ if (alg_op_type == 0)
+ return wd_parse_usage_value(buf, "COMPRESS: ");
+
+ return wd_parse_usage_value(buf, "DECOMPRESS: ");
+}
+
+static int wd_sec_usage_parse_fn(char *buf, const char *alg_name, __u8 alg_op_type)
+{
+ return wd_parse_usage_value(buf, "SEC: ");
+}
+
+static int wd_hpre_usage_parse_fn(char *buf, const char *alg_name, __u8 alg_op_type)
+{
+ size_t size = ARRAY_SIZE(hpre_ecc_algs);
+ size_t i;
+
+ for (i = 0; i < size; i++) {
+ if (!strcmp(alg_name, hpre_ecc_algs[i]))
+ return wd_parse_usage_value(buf, "ECC: ");
+ }
+
+ return wd_parse_usage_value(buf, "RSA: ");
+}
+
+static const struct dev_usage_info dev_usage_parse[] = {
+ {
+ .dev_name = "hisi_zip",
+ .alg_op_type = 2,
+ .usage_parse_fn = wd_zip_usage_parse_fn
+ }, {
+ .dev_name = "hisi_sec",
+ .alg_op_type = 1,
+ .usage_parse_fn = wd_sec_usage_parse_fn
+ }, {
+ .dev_name = "hisi_hpre",
+ .alg_op_type = 1,
+ .usage_parse_fn = wd_hpre_usage_parse_fn
+ },
+};
+
+static int wd_parse_dev_usage(struct uacce_dev *dev, char *buf,
+ const char *alg_name, __u8 alg_op_type)
+{
+ size_t size = ARRAY_SIZE(dev_usage_parse);
+ size_t i;
+
+ for (i = 0; i < size; i++) {
+ if (strstr(dev->dev_root, dev_usage_parse[i].dev_name))
+ break;
+ }
+
+ if (i == size) {
+ WD_ERR("failed to find parse function!\n");
+ return -WD_EINVAL;
+ }
+
+ if (alg_op_type >= dev_usage_parse[i].alg_op_type) {
+ WD_ERR("invalid: alg_op_type %u is error!\n", alg_op_type);
+ return -WD_EINVAL;
+ }
+
+ return dev_usage_parse[i].usage_parse_fn(buf, alg_name, alg_op_type);
+}
+
+static int wd_read_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 alg_op_type)
+{
+ char buf[WD_DEV_USAGE_SIZE];
+ int ret;
+
+ ret = access_attr(dev->dev_root, "dev_usage", F_OK);
+ if (ret) {
+ WD_ERR("failed to access dev_usage!\n");
+ return ret;
+ }
+
+ ret = get_str_attr(dev, "dev_usage", buf, WD_DEV_USAGE_SIZE);
+ if (ret < 0)
+ return ret;
+
+ return wd_parse_dev_usage(dev, buf, alg_name, alg_op_type);
+}
+
+int wd_get_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 alg_op_type)
+{
+ char *dev_name;
+ int ret;
+
+ if (!dev || !alg_name) {
+ WD_ERR("invalid: dev or alg name is NULL!\n");
+ return -WD_EINVAL;
+ }
+
+ if (!dev_has_alg(dev->algs, alg_name)) {
+ WD_ERR("invalid: dev does not support alg %s!\n", alg_name);
+ return -WD_EINVAL;
+ }
+
+ dev_name = wd_get_accel_name(dev->char_dev_path, 0);
+ ret = wd_alg_get_dev_usage(dev_name, alg_name, alg_op_type);
+ if (ret == -WD_EACCES)
+ return wd_read_dev_usage(dev, alg_name, alg_op_type);
+
+ return ret;
+}
diff --git a/wd_alg.c b/wd_alg.c
index 9c7c0fd..c819d32 100644
--- a/wd_alg.c
+++ b/wd_alg.c
@@ -24,6 +24,97 @@ static struct wd_alg_list *alg_list_tail = &alg_list_head;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+struct acc_alg_item {
+ const char *name;
+ const char *algtype;
+};
+
+static struct acc_alg_item alg_options[] = {
+ {"zlib", "zlib"},
+ {"gzip", "gzip"},
+ {"deflate", "deflate"},
+ {"lz77_zstd", "lz77_zstd"},
+ {"lz4", "lz4"},
+ {"lz77_only", "lz77_only"},
+ {"hashagg", "hashagg"},
+ {"udma", "udma"},
+ {"hashjoin", "hashjoin"},
+ {"gather", "gather"},
+ {"join-gather", "hashjoin"},
+
+ {"rsa", "rsa"},
+ {"dh", "dh"},
+ {"ecdh", "ecdh"},
+ {"x25519", "x25519"},
+ {"x448", "x448"},
+ {"ecdsa", "ecdsa"},
+ {"sm2", "sm2"},
+
+ {"ecb(aes)", "cipher"},
+ {"cbc(aes)", "cipher"},
+ {"xts(aes)", "cipher"},
+ {"ofb(aes)", "cipher"},
+ {"cfb(aes)", "cipher"},
+ {"ctr(aes)", "cipher"},
+ {"cbc-cs1(aes)", "cipher"},
+ {"cbc-cs2(aes)", "cipher"},
+ {"cbc-cs3(aes)", "cipher"},
+ {"ecb(sm4)", "cipher"},
+ {"xts(sm4)", "cipher"},
+ {"cbc(sm4)", "cipher"},
+ {"ofb(sm4)", "cipher"},
+ {"cfb(sm4)", "cipher"},
+ {"ctr(sm4)", "cipher"},
+ {"cbc-cs1(sm4)", "cipher"},
+ {"cbc-cs2(sm4)", "cipher"},
+ {"cbc-cs3(sm4)", "cipher"},
+ {"ecb(des)", "cipher"},
+ {"cbc(des)", "cipher"},
+ {"ecb(des3_ede)", "cipher"},
+ {"cbc(des3_ede)", "cipher"},
+
+ {"ccm(aes)", "aead"},
+ {"gcm(aes)", "aead"},
+ {"ccm(sm4)", "aead"},
+ {"gcm(sm4)", "aead"},
+ {"authenc(generic,cbc(aes))", "aead"},
+ {"authenc(generic,cbc(sm4))", "aead"},
+
+ {"sm3", "digest"},
+ {"md5", "digest"},
+ {"sha1", "digest"},
+ {"sha256", "digest"},
+ {"sha224", "digest"},
+ {"sha384", "digest"},
+ {"sha512", "digest"},
+ {"sha512-224", "digest"},
+ {"sha512-256", "digest"},
+ {"cmac(aes)", "digest"},
+ {"gmac(aes)", "digest"},
+ {"xcbc-mac-96(aes)", "digest"},
+ {"xcbc-prf-128(aes)", "digest"},
+ {"", ""}
+};
+
+int wd_get_alg_type(const char *alg_name, char *alg_type)
+{
+ __u64 i;
+
+ if (!alg_name || !alg_type) {
+ WD_ERR("invalid: alg_name or alg_type is NULL!\n");
+ return -WD_EINVAL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(alg_options); i++) {
+ if (strcmp(alg_name, alg_options[i].name) == 0) {
+ (void)strcpy(alg_type, alg_options[i].algtype);
+ return 0;
+ }
+ }
+
+ return -WD_EINVAL;
+}
+
static bool wd_check_accel_dev(const char *dev_name)
{
struct dirent *dev_dir;
@@ -182,6 +273,7 @@ int wd_alg_driver_register(struct wd_alg_driver *drv)
return -WD_ENOMEM;
}
+ (void)wd_get_alg_type(drv->alg_name, new_alg->alg_type);
strncpy(new_alg->alg_name, drv->alg_name, ALG_NAME_SIZE - 1);
strncpy(new_alg->drv_name, drv->drv_name, DEV_NAME_LEN - 1);
new_alg->priority = drv->priority;
@@ -393,3 +485,35 @@ int wd_alg_driver_recv(struct wd_alg_driver *drv, handle_t ctx, void *msg)
return drv->recv(drv, ctx, msg);
}
+int wd_alg_get_dev_usage(const char *dev_name, const char *alg_type, __u8 alg_op_type)
+{
+ struct wd_alg_list *pnext = alg_list_head.next;
+ struct hisi_dev_usage dev_usage;
+ struct wd_alg_driver *drv;
+
+ if (!dev_name || !alg_type) {
+ WD_ERR("dev_name or alg_type is NULL!\n");
+ return -WD_EINVAL;
+ }
+
+ while (pnext) {
+ if (strstr(dev_name, pnext->drv_name) &&
+ !strcmp(alg_type, pnext->alg_type))
+ break;
+
+ pnext = pnext->next;
+ }
+
+ if (!pnext)
+ return -WD_EACCES;
+
+ drv = pnext->drv;
+ if (!drv->get_usage)
+ return -WD_EINVAL;
+
+ dev_usage.drv = drv;
+ dev_usage.alg_op_type = alg_op_type;
+ dev_usage.dev_name = dev_name;
+
+ return drv->get_usage(&dev_usage);
+}
diff --git a/wd_util.c b/wd_util.c
index daa7309..bec23f5 100644
--- a/wd_util.c
+++ b/wd_util.c
@@ -98,78 +98,6 @@ struct drv_lib_list {
struct drv_lib_list *next;
};
-struct acc_alg_item {
- const char *name;
- const char *algtype;
-};
-
-static struct acc_alg_item alg_options[] = {
- {"zlib", "zlib"},
- {"gzip", "gzip"},
- {"deflate", "deflate"},
- {"lz77_zstd", "lz77_zstd"},
- {"lz4", "lz4"},
- {"lz77_only", "lz77_only"},
- {"hashagg", "hashagg"},
- {"udma", "udma"},
- {"hashjoin", "hashjoin"},
- {"gather", "gather"},
- {"join-gather", "hashjoin"},
-
- {"rsa", "rsa"},
- {"dh", "dh"},
- {"ecdh", "ecdh"},
- {"x25519", "x25519"},
- {"x448", "x448"},
- {"ecdsa", "ecdsa"},
- {"sm2", "sm2"},
-
- {"ecb(aes)", "cipher"},
- {"cbc(aes)", "cipher"},
- {"xts(aes)", "cipher"},
- {"ofb(aes)", "cipher"},
- {"cfb(aes)", "cipher"},
- {"ctr(aes)", "cipher"},
- {"cbc-cs1(aes)", "cipher"},
- {"cbc-cs2(aes)", "cipher"},
- {"cbc-cs3(aes)", "cipher"},
- {"ecb(sm4)", "cipher"},
- {"xts(sm4)", "cipher"},
- {"cbc(sm4)", "cipher"},
- {"ofb(sm4)", "cipher"},
- {"cfb(sm4)", "cipher"},
- {"ctr(sm4)", "cipher"},
- {"cbc-cs1(sm4)", "cipher"},
- {"cbc-cs2(sm4)", "cipher"},
- {"cbc-cs3(sm4)", "cipher"},
- {"ecb(des)", "cipher"},
- {"cbc(des)", "cipher"},
- {"ecb(des3_ede)", "cipher"},
- {"cbc(des3_ede)", "cipher"},
-
- {"ccm(aes)", "aead"},
- {"gcm(aes)", "aead"},
- {"ccm(sm4)", "aead"},
- {"gcm(sm4)", "aead"},
- {"authenc(generic,cbc(aes))", "aead"},
- {"authenc(generic,cbc(sm4))", "aead"},
-
- {"sm3", "digest"},
- {"md5", "digest"},
- {"sha1", "digest"},
- {"sha256", "digest"},
- {"sha224", "digest"},
- {"sha384", "digest"},
- {"sha512", "digest"},
- {"sha512-224", "digest"},
- {"sha512-256", "digest"},
- {"cmac(aes)", "digest"},
- {"gmac(aes)", "digest"},
- {"xcbc-mac-96(aes)", "digest"},
- {"xcbc-prf-128(aes)", "digest"},
- {"", ""}
-};
-
static void *wd_internal_alloc(void *usr, size_t size)
{
if (size != 0)
@@ -2013,18 +1941,6 @@ int wd_init_param_check(struct wd_ctx_config *config, struct wd_sched *sched)
return 0;
}
-static void wd_get_alg_type(const char *alg_name, char *alg_type)
-{
- __u64 i;
-
- for (i = 0; i < ARRAY_SIZE(alg_options); i++) {
- if (strcmp(alg_name, alg_options[i].name) == 0) {
- (void)strcpy(alg_type, alg_options[i].algtype);
- break;
- }
- }
-}
-
static int wd_alg_init_fallback(struct wd_alg_driver *fb_driver)
{
if (!fb_driver->init) {
@@ -2175,7 +2091,7 @@ static int wd_env_set_ctx_nums(const char *alg_name, const char *name, const cha
char *left, *section, *start;
struct uacce_dev_list *list;
int is_comp;
- int ret = 0;
+ int ret;
/* COMP environment variable's format is different, mark it */
is_comp = strncmp(name, "WD_COMP_CTX_NUM", strlen(name)) ? 0 : 1;
@@ -2186,7 +2102,9 @@ static int wd_env_set_ctx_nums(const char *alg_name, const char *name, const cha
if (!start)
return -WD_ENOMEM;
- wd_get_alg_type(alg_name, alg_type);
+ ret = wd_get_alg_type(alg_name, alg_type);
+ if (ret)
+ return ret;
list = wd_get_accel_list(alg_type);
if (!list) {
WD_ERR("failed to get devices!\n");
@@ -3098,7 +3016,8 @@ int wd_alg_attrs_init(struct wd_init_attrs *attrs)
}
break;
case UADK_ALG_HW:
- wd_get_alg_type(alg, alg_type);
+ if (wd_get_alg_type(alg, alg_type))
+ return -WD_EINVAL;
(void)strcpy(attrs->alg, alg_type);
ctx_config = calloc(1, sizeof(*ctx_config));
--
2.33.0