crypto: hisilicon/zip - save capability registers in probe process
authorZhiqi Song <songzhiqi1@huawei.com>
Sat, 2 Dec 2023 09:17:22 +0000 (17:17 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Jan 2024 23:35:17 +0000 (15:35 -0800)
[ Upstream commit 2ff0ad847951d61c2d8b309e1ccefb26c57dcc7b ]

Pre-store the valid value of the zip alg support related capability
register in hisi_zip_qm_init(), which will be called by hisi_zip_probe().
It can reduce the number of capability register queries and avoid
obtaining incorrect values in abnormal scenarios, such as reset failed
and the memory space disabled.

Fixes: db700974b69d ("crypto: hisilicon/zip - support zip capability")
Signed-off-by: Zhiqi Song <songzhiqi1@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/crypto/hisilicon/zip/zip_main.c

index 4d64a43..cd7ecb2 100644 (file)
@@ -248,6 +248,26 @@ static struct hisi_qm_cap_info zip_basic_cap_info[] = {
        {ZIP_CAP_MAX, 0x317c, 0, GENMASK(0, 0), 0x0, 0x0, 0x0}
 };
 
+enum zip_pre_store_cap_idx {
+       ZIP_CORE_NUM_CAP_IDX = 0x0,
+       ZIP_CLUSTER_COMP_NUM_CAP_IDX,
+       ZIP_CLUSTER_DECOMP_NUM_CAP_IDX,
+       ZIP_DECOMP_ENABLE_BITMAP_IDX,
+       ZIP_COMP_ENABLE_BITMAP_IDX,
+       ZIP_DRV_ALG_BITMAP_IDX,
+       ZIP_DEV_ALG_BITMAP_IDX,
+};
+
+static const u32 zip_pre_store_caps[] = {
+       ZIP_CORE_NUM_CAP,
+       ZIP_CLUSTER_COMP_NUM_CAP,
+       ZIP_CLUSTER_DECOMP_NUM_CAP,
+       ZIP_DECOMP_ENABLE_BITMAP,
+       ZIP_COMP_ENABLE_BITMAP,
+       ZIP_DRV_ALG_BITMAP,
+       ZIP_DEV_ALG_BITMAP,
+};
+
 enum {
        HZIP_COMP_CORE0,
        HZIP_COMP_CORE1,
@@ -442,7 +462,7 @@ bool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg)
 {
        u32 cap_val;
 
-       cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DRV_ALG_BITMAP, qm->cap_ver);
+       cap_val = qm->cap_tables.dev_cap_table[ZIP_DRV_ALG_BITMAP_IDX].cap_val;
        if ((alg & cap_val) == alg)
                return true;
 
@@ -567,10 +587,8 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm)
        }
 
        /* let's open all compression/decompression cores */
-       dcomp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
-                                      ZIP_DECOMP_ENABLE_BITMAP, qm->cap_ver);
-       comp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
-                                     ZIP_COMP_ENABLE_BITMAP, qm->cap_ver);
+       dcomp_bm = qm->cap_tables.dev_cap_table[ZIP_DECOMP_ENABLE_BITMAP_IDX].cap_val;
+       comp_bm = qm->cap_tables.dev_cap_table[ZIP_COMP_ENABLE_BITMAP_IDX].cap_val;
        writel(HZIP_DECOMP_CHECK_ENABLE | dcomp_bm | comp_bm, base + HZIP_CLOCK_GATE_CTRL);
 
        /* enable sqc,cqc writeback */
@@ -797,9 +815,8 @@ static int hisi_zip_core_debug_init(struct hisi_qm *qm)
        char buf[HZIP_BUF_SIZE];
        int i;
 
-       zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver);
-       zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP,
-                                               qm->cap_ver);
+       zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val;
+       zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val;
 
        for (i = 0; i < zip_core_num; i++) {
                if (i < zip_comp_core_num)
@@ -941,7 +958,7 @@ static int hisi_zip_show_last_regs_init(struct hisi_qm *qm)
        u32 zip_core_num;
        int i, j, idx;
 
-       zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver);
+       zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val;
 
        debug->last_words = kcalloc(core_dfx_regs_num * zip_core_num + com_dfx_regs_num,
                                    sizeof(unsigned int), GFP_KERNEL);
@@ -997,9 +1014,9 @@ static void hisi_zip_show_last_dfx_regs(struct hisi_qm *qm)
                                 hzip_com_dfx_regs[i].name, debug->last_words[i], val);
        }
 
-       zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver);
-       zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP,
-                                               qm->cap_ver);
+       zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val;
+       zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val;
+
        for (i = 0; i < zip_core_num; i++) {
                if (i < zip_comp_core_num)
                        scnprintf(buf, sizeof(buf), "Comp_core-%d", i);
@@ -1155,6 +1172,28 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
        return ret;
 }
 
+static int zip_pre_store_cap_reg(struct hisi_qm *qm)
+{
+       struct hisi_qm_cap_record *zip_cap;
+       struct pci_dev *pdev = qm->pdev;
+       size_t i, size;
+
+       size = ARRAY_SIZE(zip_pre_store_caps);
+       zip_cap = devm_kzalloc(&pdev->dev, sizeof(*zip_cap) * size, GFP_KERNEL);
+       if (!zip_cap)
+               return -ENOMEM;
+
+       for (i = 0; i < size; i++) {
+               zip_cap[i].type = zip_pre_store_caps[i];
+               zip_cap[i].cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
+                                    zip_pre_store_caps[i], qm->cap_ver);
+       }
+
+       qm->cap_tables.dev_cap_table = zip_cap;
+
+       return 0;
+}
+
 static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
 {
        u64 alg_msk;
@@ -1193,7 +1232,15 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
                return ret;
        }
 
-       alg_msk = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DEV_ALG_BITMAP, qm->cap_ver);
+       /* Fetch and save the value of capability registers */
+       ret = zip_pre_store_cap_reg(qm);
+       if (ret) {
+               pci_err(qm->pdev, "Failed to pre-store capability registers!\n");
+               hisi_qm_uninit(qm);
+               return ret;
+       }
+
+       alg_msk = qm->cap_tables.dev_cap_table[ZIP_DEV_ALG_BITMAP_IDX].cap_val;
        ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs));
        if (ret) {
                pci_err(qm->pdev, "Failed to set zip algs!\n");