From 3b1df238c34043f5a41aff2efc23496f3a5efef8 Mon Sep 17 00:00:00 2001 From: lingmingqiang Date: Thu, 11 Jul 2019 14:41:48 +0800 Subject: [PATCH] ACC: clear the cnt regs of hpre when probe and rmmod hisi_hpre.ko driver inclusion category: bugfix bugzilla: NA CVE: NA clear the cnt regs of hpre, when probe and rmmod hisi_hpre.ko Signed-off-by: yumeng18 Reviewed-by: wangzhou Signed-off-by: lingmingqiang Signed-off-by: Yang Yingliang --- drivers/crypto/hisilicon/hpre/hpre_main.c | 26 ++++++++++++++++ drivers/crypto/hisilicon/qm.c | 38 ++++++++++++++++++++--- drivers/crypto/hisilicon/qm.h | 1 + 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c index 042d0e778d8d..8083f9fb39d8 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_main.c +++ b/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -406,6 +406,28 @@ static int hpre_set_user_domain_and_cache(struct hpre *hpre) return ret; } +/* hpre_cnt_regs_clear() - clear the hpre cnt regs */ +static void hpre_cnt_regs_clear(struct hisi_qm *qm) +{ + unsigned long offset; + int i; + + /* clear current_qm */ + writel(0x0, qm->io_base + QM_DFX_MB_CNT_VF); + writel(0x0, qm->io_base + QM_DFX_DB_CNT_VF); + + /* clear clusterX/cluster_ctrl */ + for (i = 0; i < HPRE_CLUSTERS_NUM; i++) { + offset = HPRE_CLSTR_BASE + i * HPRE_CLSTR_ADDR_INTRVL; + writel(0x0, qm->io_base + offset + HPRE_CLUSTER_INQURY); + } + + /* clear rdclr_en */ + writel(0x0, qm->io_base + HPRE_CTRL_CNT_CLR_CE); + + hisi_qm_cnt_regs_clear(qm); +} + static void hpre_hw_error_set_state(struct hpre *hpre, bool state) { struct hisi_qm *qm = &hpre->qm; @@ -817,6 +839,7 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id) return ret; if (pdev->is_physfn) { + hpre_cnt_regs_clear(qm); ret = hpre_pf_probe_init(hpre); if (ret) goto err_with_qm_init; @@ -1240,6 +1263,9 @@ static void hpre_remove(struct pci_dev *pdev) } } #endif + if (qm->fun_type == QM_HW_PF) + hpre_cnt_regs_clear(qm); + hpre_debugfs_exit(hpre); hisi_qm_stop(qm); if (qm->fun_type == QM_HW_PF) diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index b48fd61a0242..7317853f3695 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -850,11 +850,9 @@ struct qm_dfx_registers { }; static struct qm_dfx_registers qm_dfx_regs[] = { - {"QM_DFX_FUNS_ACTIVE_ST ", 0x200ull}, + /* these regs are read clear */ {"QM_ECC_1BIT_CNT ", 0x104000ull}, - {"QM_ECC_1BIT_INF ", 0x104004ull}, {"QM_ECC_MBIT_CNT ", 0x104008ull}, - {"QM_ECC_MBIT_INF ", 0x10400cull}, {"QM_DFX_MB_CNT ", 0x104018ull}, {"QM_DFX_DB_CNT ", 0x104028ull}, {"QM_DFX_SQE_CNT ", 0x104038ull}, @@ -862,10 +860,14 @@ static struct qm_dfx_registers qm_dfx_regs[] = { {"QM_DFX_SEND_SQE_TO_ACC_CNT ", 0x104050ull}, {"QM_DFX_WB_SQE_FROM_ACC_CNT ", 0x104058ull}, {"QM_DFX_ACC_FINISH_CNT ", 0x104060ull}, + {"QM_DFX_CQE_ERR_CNT ", 0x1040b4ull}, + + {"QM_DFX_FUNS_ACTIVE_ST ", 0x200ull}, + {"QM_ECC_1BIT_INF ", 0x104004ull}, + {"QM_ECC_MBIT_INF ", 0x10400cull}, {"QM_DFX_ACC_RDY_VLD0 ", 0x1040a0ull}, {"QM_DFX_ACC_RDY_VLD1 ", 0x1040a4ull}, {"QM_DFX_AXI_RDY_VLD ", 0x1040a8ull}, - {"QM_DFX_CQE_ERR_CNT ", 0x1040b4ull}, {"QM_DFX_FF_ST0 ", 0x1040c8ull}, {"QM_DFX_FF_ST1 ", 0x1040ccull}, {"QM_DFX_FF_ST2 ", 0x1040d0ull}, @@ -2210,6 +2212,34 @@ int hisi_qm_stop(struct hisi_qm *qm) } EXPORT_SYMBOL_GPL(hisi_qm_stop); +/** + * hisi_qm_cnt_regs_clear() - clear qm cnt regs. + * @qm: The qm for which we want to clear + */ +void hisi_qm_cnt_regs_clear(struct hisi_qm *qm) +{ + struct qm_dfx_registers *regs; + int i; + + /* clear current_q */ + writel(0x0, qm->io_base + QM_DFX_SQE_CNT_VF_SQN); + writel(0x0, qm->io_base + QM_DFX_CQE_CNT_VF_CQN); + + /* clear regs, these cnt regs are read_clear */ + writel(0x1, qm->io_base + QM_DFX_CNT_CLR_CE); + + regs = qm_dfx_regs; +#define CNT_CYC_REGS_NUM 10 + for (i = 0; i < CNT_CYC_REGS_NUM; i++) { + readl(qm->io_base + regs->reg_offset); + regs++; + } + + /* clear clear_enable */ + writel(0x0, qm->io_base + QM_DFX_CNT_CLR_CE); +} +EXPORT_SYMBOL_GPL(hisi_qm_cnt_regs_clear); + /** * hisi_qm_debug_init() - Initialize qm related debugfs files. * @qm: The qm for which we want to add debugfs files. diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h index a488ab7bb924..27fb9c52f1c8 100644 --- a/drivers/crypto/hisilicon/qm.h +++ b/drivers/crypto/hisilicon/qm.h @@ -317,6 +317,7 @@ int hisi_qp_wait(struct hisi_qp *qp); int hisi_qm_get_free_qp_num(struct hisi_qm *qm); int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 *number); int hisi_qm_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base, u32 number); +void hisi_qm_cnt_regs_clear(struct hisi_qm *qm); int hisi_qm_debug_init(struct hisi_qm *qm); void hisi_qm_hw_error_init(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe, u32 msi); -- GitLab