From: Weili Qian <qianweili@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@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