--- zzzz-none-000/linux-5.4.213/drivers/crypto/qce/core.c 2022-09-15 10:04:56.000000000 +0000 +++ alder-5690pro-762/linux-5.4.213/drivers/crypto/qce/core.c 2024-08-14 09:01:38.000000000 +0000 @@ -1,11 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2014, 2021 The Linux Foundation. All rights reserved. */ #include #include #include +#include +#include #include #include #include @@ -14,18 +16,224 @@ #include #include +#if defined(CONFIG_ARCH_IPQ9574) +#include +#endif /* CONFIG_ARCH_IPQ9574 */ + +#include #include "core.h" #include "cipher.h" #include "sha.h" +#include "aead.h" #define QCE_MAJOR_VERSION5 0x05 #define QCE_QUEUE_LENGTH 1 static const struct qce_algo_ops *qce_ops[] = { - &ablkcipher_ops, +#ifdef CONFIG_CRYPTO_DEV_QCE_SKCIPHER + &skcipher_ops, +#endif +#ifdef CONFIG_CRYPTO_DEV_QCE_SHA &ahash_ops, +#endif +#ifdef CONFIG_CRYPTO_DEV_QCE_AEAD + &aead_ops, +#endif +}; + +static int qce_disp_stats(struct qce_device *qce) +{ + struct qce_stat *pstat; + char *read_buf; + int len; + + pstat = &qce->qce_stat; + read_buf = qce->qce_debug_read_buf; + len = scnprintf(read_buf, DEBUG_MAX_RW_BUF - 1, + "\nQTI crypto accelerator Statistics\n"); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " ABLK CIPHER AES encryption : %llu\n", + pstat->ablk_cipher_aes_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " ABLK CIPHER AES decryption : %llu\n", + pstat->ablk_cipher_aes_dec); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " ABLK CIPHER DES encryption : %llu\n", + pstat->ablk_cipher_des_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " ABLK CIPHER DES decryption : %llu\n", + pstat->ablk_cipher_des_dec); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " ABLK CIPHER 3DES encryption : %llu\n", + pstat->ablk_cipher_3des_enc); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " ABLK CIPHER 3DES decryption : %llu\n", + pstat->ablk_cipher_3des_dec); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " ABLK CIPHER operation success : %llu\n", + pstat->ablk_cipher_op_success); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " ABLK CIPHER operation fail : %llu\n", + pstat->ablk_cipher_op_fail); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + "\n"); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA1-AES encryption : %llu\n", + pstat->aead_sha1_aes_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA1-AES decryption : %llu\n", + pstat->aead_sha1_aes_dec); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA1-DES encryption : %llu\n", + pstat->aead_sha1_des_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA1-DES decryption : %llu\n", + pstat->aead_sha1_des_dec); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA1-3DES encryption : %llu\n", + pstat->aead_sha1_3des_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA1-3DES decryption : %llu\n", + pstat->aead_sha1_3des_dec); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA256-AES encryption : %llu\n", + pstat->aead_sha256_aes_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA256-AES decryption : %llu\n", + pstat->aead_sha256_aes_dec); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA256-DES encryption : %llu\n", + pstat->aead_sha256_des_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA256-DES decryption : %llu\n", + pstat->aead_sha256_des_dec); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA256-3DES encryption : %llu\n", + pstat->aead_sha256_3des_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD SHA256-3DES decryption : %llu\n", + pstat->aead_sha256_3des_dec); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD CCM-AES encryption : %llu\n", + pstat->aead_ccm_aes_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD CCM-AES decryption : %llu\n", + pstat->aead_ccm_aes_dec); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD RFC4309-CCM-AES encryption : %llu\n", + pstat->aead_rfc4309_ccm_aes_enc); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD RFC4309-CCM-AES decryption : %llu\n", + pstat->aead_rfc4309_ccm_aes_dec); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD operation success : %llu\n", + pstat->aead_op_success); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD operation fail : %llu\n", + pstat->aead_op_fail); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AEAD bad message : %llu\n", + pstat->aead_bad_msg); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + "\n"); + + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AHASH SHA1 digest : %llu\n", + pstat->sha1_digest); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AHASH SHA256 digest : %llu\n", + pstat->sha256_digest); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AHASH SHA1 HMAC digest : %llu\n", + pstat->sha1_hmac_digest); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AHASH SHA256 HMAC digest : %llu\n", + pstat->sha256_hmac_digest); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AHASH operation success : %llu\n", + pstat->ahash_op_success); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + " AHASH operation fail : %llu\n", + pstat->ahash_op_fail); + len += scnprintf(read_buf + len, DEBUG_MAX_RW_BUF - len - 1, + "\n"); + + return len; +} + +static int qce_debug_stats_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t qce_debug_stats_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct qce_device *qce = (struct qce_device *)file->private_data; + int len; + + if (!qce) + return 0; + len = qce_disp_stats(qce); + + return simple_read_from_buffer((void __user *)buf, count, + ppos, (void *)qce->qce_debug_read_buf, len); +} + +static ssize_t qce_debug_stats_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct qce_device *qce = (struct qce_device *)file->private_data; + + if (!qce) + return 0; + memset((char *)&qce->qce_stat, 0, sizeof(struct qce_stat)); + return count; +} +static const struct file_operations qce_debug_stats_ops = { + .open = qce_debug_stats_open, + .read = qce_debug_stats_read, + .write = qce_debug_stats_write, }; +static int qce_debug_init(struct qce_device *qce) +{ + int rc; + struct dentry *qce_dent; + struct dentry *stats_dent; + + qce_dent = debugfs_create_dir("qce", NULL); + if (IS_ERR(qce_dent)) { + rc = PTR_ERR(qce_dent); + dev_err(qce->dev, "debugfs_create_dir failed %d\n", rc); + return rc; + } + + stats_dent = debugfs_create_file("stats", 0644, qce_dent, + qce, &qce_debug_stats_ops); + if (IS_ERR(stats_dent)) { + rc = PTR_ERR(stats_dent); + dev_err(qce->dev, "debugfs_create_file failed %d\n", rc); + debugfs_remove_recursive(qce_dent); + return rc; + } + qce->qce_debug_dent = qce_dent; + return 0; +} + static void qce_unregister_algs(struct qce_device *qce) { const struct qce_algo_ops *ops; @@ -37,6 +245,76 @@ } } +#define to_qcedev(k) container_of(k, struct qce_device, kobj) + +/* Expose fixed key field so that qce can request key from TZ */ +static ssize_t fixed_sec_key_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct qce_device *qce = to_qcedev(kobj); + + return scnprintf(buf, sizeof(int), "%d\n", qce->use_fixed_key); +} + +/* Store fixed key field from sysfs */ +static ssize_t fixed_sec_key_store(struct kobject *kobj, + struct attribute *attr, const char *buf, size_t count) +{ + int use_fixed_key; + struct qce_device *qce = to_qcedev(kobj); + + sscanf(buf, "%du", &use_fixed_key); + if (use_fixed_key == 1) { + qce->use_fixed_key = true; + } else { + qti_qcekey_release_xpu_prot(); + qce->use_fixed_key = false; + } + return count; +} + +static struct attribute qce_fixed_key_attribute = { + .name = "fixed_sec_key", + .mode = 0660, +}; + +static struct attribute *qce_attrs[] = { + &qce_fixed_key_attribute, + NULL +}; + +static struct sysfs_ops qce_sysfs_ops = { + .show = fixed_sec_key_show, + .store = fixed_sec_key_store, +}; + +static struct kobj_type qce_ktype = { + .sysfs_ops = &qce_sysfs_ops, + .default_attrs = qce_attrs, +}; + +static int qce_sysfs_init(struct qce_device *qce) +{ + int ret; + + qce->kobj_parent = kobject_create_and_add("crypto", kernel_kobj); + if (!qce->kobj_parent) + return -ENOMEM; + + ret = kobject_init_and_add(&qce->kobj, &qce_ktype, qce->kobj_parent, + "%s", "qce"); + if (ret) + kobject_del(qce->kobj_parent); + + return ret; +} + +static void qce_sysfs_deinit(struct qce_device *qce) +{ + kobject_del(&qce->kobj); + kobject_del(qce->kobj_parent); +} + static int qce_register_algs(struct qce_device *qce) { const struct qce_algo_ops *ops; @@ -132,12 +410,63 @@ static int qce_async_request_enqueue(struct qce_device *qce, struct crypto_async_request *req) { + struct qce_stat *pstat; + const char *cra_drv_name; + int ablk_flags = 0; + struct qce_cipher_reqctx *rctx; + + pstat = &qce->qce_stat; + if (req) { + cra_drv_name = crypto_tfm_alg_driver_name(req->tfm); + rctx = ablkcipher_request_ctx((void *)req); + if (rctx) + ablk_flags = rctx->flags; + + if (!strcmp(cra_drv_name, "sha1-qce")) + pstat->sha1_digest++; + else if (!strcmp(cra_drv_name, "sha256-qce")) + pstat->sha256_digest++; + else if (!strcmp(cra_drv_name, "hmac-sha256-qce")) + pstat->sha256_hmac_digest++; + else if (!strcmp(cra_drv_name, "hmac-sha1-qce")) + pstat->sha1_hmac_digest++; + else if (IS_AES(ablk_flags) && (ablk_flags & QCE_ENCRYPT)) + pstat->ablk_cipher_aes_enc++; + else if (IS_AES(ablk_flags) && (ablk_flags & QCE_DECRYPT)) + pstat->ablk_cipher_aes_dec++; + else if (IS_DES(ablk_flags) && (ablk_flags & QCE_ENCRYPT)) + pstat->ablk_cipher_des_enc++; + else if (IS_DES(ablk_flags) && (ablk_flags & QCE_DECRYPT)) + pstat->ablk_cipher_des_dec++; + else if (IS_3DES(ablk_flags) && (ablk_flags & QCE_ENCRYPT)) + pstat->ablk_cipher_3des_enc++; + else if (IS_3DES(ablk_flags) && (ablk_flags & QCE_DECRYPT)) + pstat->ablk_cipher_3des_dec++; + } + return qce_handle_queue(qce, req); } static void qce_async_request_done(struct qce_device *qce, int ret) { + u32 type; + struct qce_stat *pstat; + qce->result = ret; + pstat = &qce->qce_stat; + if (qce->req) { + type = crypto_tfm_alg_type(qce->req->tfm); + + if (ret && (type == CRYPTO_ALG_TYPE_AHASH)) + pstat->ahash_op_fail++; + if (!ret && (type == CRYPTO_ALG_TYPE_AHASH)) + pstat->ahash_op_success++; + + if (ret && (type == CRYPTO_ALG_TYPE_ABLKCIPHER)) + pstat->ablk_cipher_op_fail++; + if (!ret && (type == CRYPTO_ALG_TYPE_ABLKCIPHER)) + pstat->ablk_cipher_op_success++; + } tasklet_schedule(&qce->done_tasklet); } @@ -168,6 +497,18 @@ struct device *dev = &pdev->dev; struct qce_device *qce; int ret; + struct resource *res; + bool skip_clk_init = false; + +#if defined(CONFIG_ARCH_IPQ9574) + if (!(avm_tz_supported_features() & AVM_TZ_FEAT_IPSEC_XPU_ENABLED)) { + /* Print configuration which was finally configured to make + * directly visible if we configured correctly + */ + pr_err("This ATF version does not support QCE\n"); + return -ENODEV; + } +#endif /* CONFIG_ARCH_IPQ9574 */ qce = devm_kzalloc(dev, sizeof(*qce), GFP_KERNEL); if (!qce) @@ -184,17 +525,44 @@ if (ret < 0) return ret; - qce->core = devm_clk_get(qce->dev, "core"); - if (IS_ERR(qce->core)) - return PTR_ERR(qce->core); - - qce->iface = devm_clk_get(qce->dev, "iface"); - if (IS_ERR(qce->iface)) - return PTR_ERR(qce->iface); - - qce->bus = devm_clk_get(qce->dev, "bus"); - if (IS_ERR(qce->bus)) - return PTR_ERR(qce->bus); + if (device_property_read_bool(dev, "qce,cmd_desc_support")){ + qce->qce_cmd_desc_enable = true; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + printk("%s, unable to get resource \n", __func__); + return -ENOMEM; + } + qce->base_dma = dma_map_resource(dev, res->start, + resource_size(res), + DMA_BIDIRECTIONAL, 0); + } + + if (device_property_read_bool(dev, "qce,use_fixed_hw_key")) + qce->use_fixed_key = true; + + if (device_property_read_bool(dev, "qce,no-clock-init")) + skip_clk_init = true; + + qce->core = devm_clk_get_optional(qce->dev, "core"); + if (IS_ERR(qce->core)) { + if (!skip_clk_init) + return PTR_ERR(qce->core); + qce->core = NULL; + } + + qce->iface = devm_clk_get_optional(qce->dev, "iface"); + if (IS_ERR(qce->iface)) { + if (!skip_clk_init) + return PTR_ERR(qce->iface); + qce->iface = NULL; + } + + qce->bus = devm_clk_get_optional(qce->dev, "bus"); + if (IS_ERR(qce->bus)) { + if (!skip_clk_init) + return PTR_ERR(qce->bus); + qce->bus = NULL; + } ret = clk_prepare_enable(qce->core); if (ret) @@ -228,8 +596,20 @@ if (ret) goto err_dma; + ret = qce_debug_init(qce); + if (ret) + goto unregister_algs; + + ret = qce_sysfs_init(qce); + if (ret) + goto remove_debugfs; + return 0; +remove_debugfs: + debugfs_remove_recursive(qce->qce_debug_dent); +unregister_algs: + qce_unregister_algs(qce); err_dma: qce_dma_release(&qce->dma); err_clks: @@ -251,6 +631,8 @@ clk_disable_unprepare(qce->bus); clk_disable_unprepare(qce->iface); clk_disable_unprepare(qce->core); + debugfs_remove_recursive(qce->qce_debug_dent); + qce_sysfs_deinit(qce); return 0; }