From a4182c8b40556c5f60e446fec183143d9d00a52a Mon Sep 17 00:00:00 2001 From: Sivaprakash Murugesan Date: Thu, 23 Apr 2020 14:11:18 +0530 Subject: [PATCH] crypto: qce: add debug fs support Add debug fs support for qcrypto. Signed-off-by: Sivaprakash Murugesan Change-Id: I6ee814bcb72eebe1fde159f592b9fc38adb18451 --- drivers/crypto/qce/core.c | 252 ++++++++++++++++++++++++++++++++++++++ drivers/crypto/qce/core.h | 48 ++++++++ 2 files changed, 300 insertions(+) diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c index d3780be44a76..8edfef08b791 100644 --- a/drivers/crypto/qce/core.c +++ b/drivers/crypto/qce/core.c @@ -14,6 +14,7 @@ #include #include +#include #include "core.h" #include "cipher.h" #include "sha.h" @@ -34,6 +35,199 @@ static const struct qce_algo_ops *qce_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, + "\nQualcomm 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; @@ -140,12 +334,63 @@ static void qce_tasklet_req_done(unsigned long data) 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); } @@ -250,8 +495,14 @@ static int qce_crypto_probe(struct platform_device *pdev) if (ret) goto err_dma; + ret = qce_debug_init(qce); + if (ret) + goto unregister_algs; + return 0; +unregister_algs: + qce_unregister_algs(qce); err_dma: qce_dma_release(&qce->dma); err_clks: @@ -273,6 +524,7 @@ static int qce_crypto_remove(struct platform_device *pdev) clk_disable_unprepare(qce->bus); clk_disable_unprepare(qce->iface); clk_disable_unprepare(qce->core); + debugfs_remove_recursive(qce->qce_debug_dent); return 0; } diff --git a/drivers/crypto/qce/core.h b/drivers/crypto/qce/core.h index 085774cdf641..77c701657711 100644 --- a/drivers/crypto/qce/core.h +++ b/drivers/crypto/qce/core.h @@ -8,6 +8,48 @@ #include "dma.h" +#define DEBUG_MAX_RW_BUF 2048 +#define DEBUG_MAX_FNAME 16 + +/** + * struct qce_stat - statistics of crypto requests per algorithm to qce engine + */ +struct qce_stat { + u64 aead_sha1_aes_enc; + u64 aead_sha1_aes_dec; + u64 aead_sha1_des_enc; + u64 aead_sha1_des_dec; + u64 aead_sha1_3des_enc; + u64 aead_sha1_3des_dec; + u64 aead_sha256_aes_enc; + u64 aead_sha256_aes_dec; + u64 aead_sha256_des_enc; + u64 aead_sha256_des_dec; + u64 aead_sha256_3des_enc; + u64 aead_sha256_3des_dec; + u64 aead_ccm_aes_enc; + u64 aead_ccm_aes_dec; + u64 aead_rfc4309_ccm_aes_enc; + u64 aead_rfc4309_ccm_aes_dec; + u64 aead_op_success; + u64 aead_op_fail; + u64 aead_bad_msg; + u64 ablk_cipher_aes_enc; + u64 ablk_cipher_aes_dec; + u64 ablk_cipher_des_enc; + u64 ablk_cipher_des_dec; + u64 ablk_cipher_3des_enc; + u64 ablk_cipher_3des_dec; + u64 ablk_cipher_op_success; + u64 ablk_cipher_op_fail; + u64 sha1_digest; + u64 sha256_digest; + u64 sha1_hmac_digest; + u64 sha256_hmac_digest; + u64 ahash_op_success; + u64 ahash_op_fail; +}; + /** * struct qce_device - crypto engine device structure * @queue: crypto request queue @@ -23,6 +65,9 @@ * @dma: pointer to dma data * @burst_size: the crypto burst size * @pipe_pair_id: which pipe pair id the device using + * @qce_stat: statistics of requests to qce device + * @qce_debug_dent: dentry to the "qce" debugfs directory + * @qce_debug_read_buf: buffer to store the qce stats * @async_req_enqueue: invoked by every algorithm to enqueue a request * @async_req_done: invoked by every algorithm to finish its request */ @@ -38,6 +83,9 @@ struct qce_device { struct qce_dma_data dma; int burst_size; unsigned int pipe_pair_id; + struct qce_stat qce_stat; + struct dentry *qce_debug_dent; + char qce_debug_read_buf[DEBUG_MAX_RW_BUF]; int (*async_req_enqueue)(struct qce_device *qce, struct crypto_async_request *req); void (*async_req_done)(struct qce_device *qce, int ret); -- 2.34.1