Path: blob/master/drivers/crypto/hisilicon/sec2/sec_main.c
51261 views
// SPDX-License-Identifier: GPL-2.01/* Copyright (c) 2019 HiSilicon Limited. */23#include <linux/acpi.h>4#include <linux/bitops.h>5#include <linux/debugfs.h>6#include <linux/init.h>7#include <linux/io.h>8#include <linux/iommu.h>9#include <linux/kernel.h>10#include <linux/module.h>11#include <linux/pci.h>12#include <linux/pm_runtime.h>13#include <linux/seq_file.h>14#include <linux/topology.h>15#include <linux/uacce.h>16#include "sec.h"1718#define CAP_FILE_PERMISSION 044419#define SEC_VF_NUM 6320#define SEC_QUEUE_NUM_V1 409621#define PCI_DEVICE_ID_HUAWEI_SEC_PF 0xa2552223#define SEC_BD_ERR_CHK_EN0 0xEFFFFFFF24#define SEC_BD_ERR_CHK_EN1 0x7ffff7fd25#define SEC_BD_ERR_CHK_EN3 0xffffbfff2627#define SEC_SQE_SIZE 12828#define SEC_PF_DEF_Q_NUM 25629#define SEC_PF_DEF_Q_BASE 030#define SEC_CTX_Q_NUM_DEF 231#define SEC_CTX_Q_NUM_MAX 323233#define SEC_CTRL_CNT_CLR_CE 0x30112034#define SEC_CTRL_CNT_CLR_CE_BIT BIT(0)35#define SEC_CORE_INT_SOURCE 0x30101036#define SEC_CORE_INT_MASK 0x30100037#define SEC_CORE_INT_STATUS 0x30100838#define SEC_CORE_SRAM_ECC_ERR_INFO 0x301C1439#define SEC_ECC_NUM 1640#define SEC_ECC_MASH 0xFF41#define SEC_CORE_INT_DISABLE 0x04243#define SEC_RAS_CE_REG 0x30105044#define SEC_RAS_FE_REG 0x30105445#define SEC_RAS_NFE_REG 0x30105846#define SEC_RAS_FE_ENB_MSK 0x047#define SEC_OOO_SHUTDOWN_SEL 0x30101448#define SEC_RAS_DISABLE 0x049#define SEC_AXI_ERROR_MASK (BIT(0) | BIT(1))5051#define SEC_MEM_START_INIT_REG 0x30110052#define SEC_MEM_INIT_DONE_REG 0x3011045354/* clock gating */55#define SEC_CONTROL_REG 0x30120056#define SEC_DYNAMIC_GATE_REG 0x30121c57#define SEC_CORE_AUTO_GATE 0x30212c58#define SEC_DYNAMIC_GATE_EN 0x7fff59#define SEC_CORE_AUTO_GATE_EN GENMASK(3, 0)60#define SEC_CLK_GATE_ENABLE BIT(3)61#define SEC_CLK_GATE_DISABLE (~BIT(3))6263#define SEC_TRNG_EN_SHIFT 864#define SEC_AXI_SHUTDOWN_ENABLE BIT(12)65#define SEC_AXI_SHUTDOWN_DISABLE 0xFFFFEFFF6667#define SEC_INTERFACE_USER_CTRL0_REG 0x30122068#define SEC_INTERFACE_USER_CTRL1_REG 0x30122469#define SEC_SAA_EN_REG 0x30127070#define SEC_BD_ERR_CHK_EN_REG0 0x30138071#define SEC_BD_ERR_CHK_EN_REG1 0x30138472#define SEC_BD_ERR_CHK_EN_REG3 0x30138c7374#define SEC_USER0_SMMU_NORMAL (BIT(23) | BIT(15))75#define SEC_USER1_SMMU_NORMAL (BIT(31) | BIT(23) | BIT(15) | BIT(7))76#define SEC_USER1_ENABLE_CONTEXT_SSV BIT(24)77#define SEC_USER1_ENABLE_DATA_SSV BIT(16)78#define SEC_USER1_WB_CONTEXT_SSV BIT(8)79#define SEC_USER1_WB_DATA_SSV BIT(0)80#define SEC_USER1_SVA_SET (SEC_USER1_ENABLE_CONTEXT_SSV | \81SEC_USER1_ENABLE_DATA_SSV | \82SEC_USER1_WB_CONTEXT_SSV | \83SEC_USER1_WB_DATA_SSV)84#define SEC_USER1_SMMU_SVA (SEC_USER1_SMMU_NORMAL | SEC_USER1_SVA_SET)85#define SEC_USER1_SMMU_MASK (~SEC_USER1_SVA_SET)86#define SEC_INTERFACE_USER_CTRL0_REG_V3 0x30222087#define SEC_INTERFACE_USER_CTRL1_REG_V3 0x30222488#define SEC_USER1_SMMU_NORMAL_V3 (BIT(23) | BIT(17) | BIT(11) | BIT(5))89#define SEC_USER1_SMMU_MASK_V3 0xFF79E79E90#define SEC_CORE_INT_STATUS_M_ECC BIT(2)9192#define SEC_PREFETCH_CFG 0x30113093#define SEC_SVA_TRANS 0x301EC494#define SEC_PREFETCH_ENABLE (~(BIT(0) | BIT(1) | BIT(11)))95#define SEC_PREFETCH_DISABLE BIT(1)96#define SEC_SVA_DISABLE_READY (BIT(7) | BIT(11))97#define SEC_SVA_PREFETCH_INFO 0x301ED498#define SEC_SVA_STALL_NUM GENMASK(23, 8)99#define SEC_SVA_PREFETCH_NUM GENMASK(2, 0)100#define SEC_WAIT_SVA_READY 500000101#define SEC_READ_SVA_STATUS_TIMES 3102#define SEC_WAIT_US_MIN 10103#define SEC_WAIT_US_MAX 20104#define SEC_WAIT_QP_US_MIN 1000105#define SEC_WAIT_QP_US_MAX 2000106#define SEC_MAX_WAIT_TIMES 2000107108#define SEC_DELAY_10_US 10109#define SEC_POLL_TIMEOUT_US 1000110#define SEC_DBGFS_VAL_MAX_LEN 20111#define SEC_SINGLE_PORT_MAX_TRANS 0x2060112113#define SEC_SQE_MASK_OFFSET 16114#define SEC_SQE_MASK_LEN 108115#define SEC_SHAPER_TYPE_RATE 400116117#define SEC_DFX_BASE 0x301000118#define SEC_DFX_CORE 0x302100119#define SEC_DFX_COMMON1 0x301600120#define SEC_DFX_COMMON2 0x301C00121#define SEC_DFX_BASE_LEN 0x9D122#define SEC_DFX_CORE_LEN 0x32B123#define SEC_DFX_COMMON1_LEN 0x45124#define SEC_DFX_COMMON2_LEN 0xBA125126#define SEC_ALG_BITMAP_SHIFT 32127128#define SEC_CIPHER_BITMAP (GENMASK_ULL(5, 0) | GENMASK_ULL(16, 12) | \129GENMASK(24, 21))130#define SEC_DIGEST_BITMAP (GENMASK_ULL(11, 8) | GENMASK_ULL(20, 19) | \131GENMASK_ULL(42, 25))132#define SEC_AEAD_BITMAP (GENMASK_ULL(7, 6) | GENMASK_ULL(18, 17) | \133GENMASK_ULL(45, 43))134135struct sec_hw_error {136u32 int_msk;137const char *msg;138};139140struct sec_dfx_item {141const char *name;142u32 offset;143};144145static const char sec_name[] = "hisi_sec2";146static struct dentry *sec_debugfs_root;147148static struct hisi_qm_list sec_devices = {149.register_to_crypto = sec_register_to_crypto,150.unregister_from_crypto = sec_unregister_from_crypto,151};152153static const struct hisi_qm_cap_info sec_basic_info[] = {154{SEC_QM_NFE_MASK_CAP, 0x3124, 0, GENMASK(31, 0), 0x0, 0x1C77, 0x7C77},155{SEC_QM_RESET_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0xC77, 0x6C77},156{SEC_QM_OOO_SHUTDOWN_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0x4, 0x6C77},157{SEC_QM_CE_MASK_CAP, 0x312C, 0, GENMASK(31, 0), 0x0, 0x8, 0x8},158{SEC_NFE_MASK_CAP, 0x3130, 0, GENMASK(31, 0), 0x0, 0x177, 0x60177},159{SEC_RESET_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x177, 0x177},160{SEC_OOO_SHUTDOWN_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x4, 0x177},161{SEC_CE_MASK_CAP, 0x3138, 0, GENMASK(31, 0), 0x0, 0x88, 0xC088},162{SEC_CLUSTER_NUM_CAP, 0x313c, 20, GENMASK(3, 0), 0x1, 0x1, 0x1},163{SEC_CORE_TYPE_NUM_CAP, 0x313c, 16, GENMASK(3, 0), 0x1, 0x1, 0x1},164{SEC_CORE_NUM_CAP, 0x313c, 8, GENMASK(7, 0), 0x4, 0x4, 0x4},165{SEC_CORES_PER_CLUSTER_NUM_CAP, 0x313c, 0, GENMASK(7, 0), 0x4, 0x4, 0x4},166{SEC_CORE_ENABLE_BITMAP, 0x3140, 0, GENMASK(31, 0), 0x17F, 0x17F, 0xF},167{SEC_DRV_ALG_BITMAP_LOW, 0x3144, 0, GENMASK(31, 0), 0x18050CB, 0x18050CB, 0x18670CF},168{SEC_DRV_ALG_BITMAP_HIGH, 0x3148, 0, GENMASK(31, 0), 0x395C, 0x395C, 0x395C},169{SEC_DEV_ALG_BITMAP_LOW, 0x314c, 0, GENMASK(31, 0), 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},170{SEC_DEV_ALG_BITMAP_HIGH, 0x3150, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF},171{SEC_CORE1_ALG_BITMAP_LOW, 0x3154, 0, GENMASK(31, 0), 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},172{SEC_CORE1_ALG_BITMAP_HIGH, 0x3158, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF},173{SEC_CORE2_ALG_BITMAP_LOW, 0x315c, 0, GENMASK(31, 0), 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},174{SEC_CORE2_ALG_BITMAP_HIGH, 0x3160, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF},175{SEC_CORE3_ALG_BITMAP_LOW, 0x3164, 0, GENMASK(31, 0), 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},176{SEC_CORE3_ALG_BITMAP_HIGH, 0x3168, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF},177{SEC_CORE4_ALG_BITMAP_LOW, 0x316c, 0, GENMASK(31, 0), 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},178{SEC_CORE4_ALG_BITMAP_HIGH, 0x3170, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF},179};180181static const struct hisi_qm_cap_query_info sec_cap_query_info[] = {182{QM_RAS_NFE_TYPE, "QM_RAS_NFE_TYPE ", 0x3124, 0x0, 0x1C77, 0x7C77},183{QM_RAS_NFE_RESET, "QM_RAS_NFE_RESET ", 0x3128, 0x0, 0xC77, 0x6C77},184{QM_RAS_CE_TYPE, "QM_RAS_CE_TYPE ", 0x312C, 0x0, 0x8, 0x8},185{SEC_RAS_NFE_TYPE, "SEC_RAS_NFE_TYPE ", 0x3130, 0x0, 0x177, 0x60177},186{SEC_RAS_NFE_RESET, "SEC_RAS_NFE_RESET ", 0x3134, 0x0, 0x177, 0x177},187{SEC_RAS_CE_TYPE, "SEC_RAS_CE_TYPE ", 0x3138, 0x0, 0x88, 0xC088},188{SEC_CORE_INFO, "SEC_CORE_INFO ", 0x313c, 0x110404, 0x110404, 0x110404},189{SEC_CORE_EN, "SEC_CORE_EN ", 0x3140, 0x17F, 0x17F, 0xF},190{SEC_DRV_ALG_BITMAP_LOW_TB, "SEC_DRV_ALG_BITMAP_LOW ",1910x3144, 0x18050CB, 0x18050CB, 0x18670CF},192{SEC_DRV_ALG_BITMAP_HIGH_TB, "SEC_DRV_ALG_BITMAP_HIGH ",1930x3148, 0x395C, 0x395C, 0x395C},194{SEC_ALG_BITMAP_LOW, "SEC_ALG_BITMAP_LOW ",1950x314c, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},196{SEC_ALG_BITMAP_HIGH, "SEC_ALG_BITMAP_HIGH ", 0x3150, 0x3FFF, 0x3FFF, 0x3FFF},197{SEC_CORE1_BITMAP_LOW, "SEC_CORE1_BITMAP_LOW ",1980x3154, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},199{SEC_CORE1_BITMAP_HIGH, "SEC_CORE1_BITMAP_HIGH ", 0x3158, 0x3FFF, 0x3FFF, 0x3FFF},200{SEC_CORE2_BITMAP_LOW, "SEC_CORE2_BITMAP_LOW ",2010x315c, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},202{SEC_CORE2_BITMAP_HIGH, "SEC_CORE2_BITMAP_HIGH ", 0x3160, 0x3FFF, 0x3FFF, 0x3FFF},203{SEC_CORE3_BITMAP_LOW, "SEC_CORE3_BITMAP_LOW ",2040x3164, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},205{SEC_CORE3_BITMAP_HIGH, "SEC_CORE3_BITMAP_HIGH ", 0x3168, 0x3FFF, 0x3FFF, 0x3FFF},206{SEC_CORE4_BITMAP_LOW, "SEC_CORE4_BITMAP_LOW ",2070x316c, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},208{SEC_CORE4_BITMAP_HIGH, "SEC_CORE4_BITMAP_HIGH ", 0x3170, 0x3FFF, 0x3FFF, 0x3FFF},209};210211static const struct qm_dev_alg sec_dev_algs[] = { {212.alg_msk = SEC_CIPHER_BITMAP,213.alg = "cipher\n",214}, {215.alg_msk = SEC_DIGEST_BITMAP,216.alg = "digest\n",217}, {218.alg_msk = SEC_AEAD_BITMAP,219.alg = "aead\n",220},221};222223static const struct sec_hw_error sec_hw_errors[] = {224{225.int_msk = BIT(0),226.msg = "sec_axi_rresp_err_rint"227},228{229.int_msk = BIT(1),230.msg = "sec_axi_bresp_err_rint"231},232{233.int_msk = BIT(2),234.msg = "sec_ecc_2bit_err_rint"235},236{237.int_msk = BIT(3),238.msg = "sec_ecc_1bit_err_rint"239},240{241.int_msk = BIT(4),242.msg = "sec_req_trng_timeout_rint"243},244{245.int_msk = BIT(5),246.msg = "sec_fsm_hbeat_rint"247},248{249.int_msk = BIT(6),250.msg = "sec_channel_req_rng_timeout_rint"251},252{253.int_msk = BIT(7),254.msg = "sec_bd_err_rint"255},256{257.int_msk = BIT(8),258.msg = "sec_chain_buff_err_rint"259},260{261.int_msk = BIT(14),262.msg = "sec_no_secure_access"263},264{265.int_msk = BIT(15),266.msg = "sec_wrapping_key_auth_err"267},268{269.int_msk = BIT(16),270.msg = "sec_km_key_crc_fail"271},272{273.int_msk = BIT(17),274.msg = "sec_axi_poison_err"275},276{277.int_msk = BIT(18),278.msg = "sec_sva_err"279},280{}281};282283static const char * const sec_dbg_file_name[] = {284[SEC_CLEAR_ENABLE] = "clear_enable",285};286287static struct sec_dfx_item sec_dfx_labels[] = {288{"send_cnt", offsetof(struct sec_dfx, send_cnt)},289{"recv_cnt", offsetof(struct sec_dfx, recv_cnt)},290{"send_busy_cnt", offsetof(struct sec_dfx, send_busy_cnt)},291{"recv_busy_cnt", offsetof(struct sec_dfx, recv_busy_cnt)},292{"err_bd_cnt", offsetof(struct sec_dfx, err_bd_cnt)},293{"invalid_req_cnt", offsetof(struct sec_dfx, invalid_req_cnt)},294{"done_flag_cnt", offsetof(struct sec_dfx, done_flag_cnt)},295};296297static const struct debugfs_reg32 sec_dfx_regs[] = {298{"SEC_PF_ABNORMAL_INT_SOURCE ", 0x301010},299{"SEC_SAA_EN ", 0x301270},300{"SEC_BD_LATENCY_MIN ", 0x301600},301{"SEC_BD_LATENCY_MAX ", 0x301608},302{"SEC_BD_LATENCY_AVG ", 0x30160C},303{"SEC_BD_NUM_IN_SAA0 ", 0x301670},304{"SEC_BD_NUM_IN_SAA1 ", 0x301674},305{"SEC_BD_NUM_IN_SEC ", 0x301680},306{"SEC_ECC_1BIT_CNT ", 0x301C00},307{"SEC_ECC_1BIT_INFO ", 0x301C04},308{"SEC_ECC_2BIT_CNT ", 0x301C10},309{"SEC_ECC_2BIT_INFO ", 0x301C14},310{"SEC_BD_SAA0 ", 0x301C20},311{"SEC_BD_SAA1 ", 0x301C24},312{"SEC_BD_SAA2 ", 0x301C28},313{"SEC_BD_SAA3 ", 0x301C2C},314{"SEC_BD_SAA4 ", 0x301C30},315{"SEC_BD_SAA5 ", 0x301C34},316{"SEC_BD_SAA6 ", 0x301C38},317{"SEC_BD_SAA7 ", 0x301C3C},318{"SEC_BD_SAA8 ", 0x301C40},319{"SEC_RAS_CE_ENABLE ", 0x301050},320{"SEC_RAS_FE_ENABLE ", 0x301054},321{"SEC_RAS_NFE_ENABLE ", 0x301058},322{"SEC_REQ_TRNG_TIME_TH ", 0x30112C},323{"SEC_CHANNEL_RNG_REQ_THLD ", 0x302110},324};325326/* define the SEC's dfx regs region and region length */327static struct dfx_diff_registers sec_diff_regs[] = {328{329.reg_offset = SEC_DFX_BASE,330.reg_len = SEC_DFX_BASE_LEN,331}, {332.reg_offset = SEC_DFX_COMMON1,333.reg_len = SEC_DFX_COMMON1_LEN,334}, {335.reg_offset = SEC_DFX_COMMON2,336.reg_len = SEC_DFX_COMMON2_LEN,337}, {338.reg_offset = SEC_DFX_CORE,339.reg_len = SEC_DFX_CORE_LEN,340},341};342343static int sec_diff_regs_show(struct seq_file *s, void *unused)344{345struct hisi_qm *qm = s->private;346347hisi_qm_acc_diff_regs_dump(qm, s, qm->debug.acc_diff_regs,348ARRAY_SIZE(sec_diff_regs));349350return 0;351}352DEFINE_SHOW_ATTRIBUTE(sec_diff_regs);353354static bool pf_q_num_flag;355static int sec_pf_q_num_set(const char *val, const struct kernel_param *kp)356{357pf_q_num_flag = true;358359return hisi_qm_q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_SEC_PF);360}361362static const struct kernel_param_ops sec_pf_q_num_ops = {363.set = sec_pf_q_num_set,364.get = param_get_int,365};366367static u32 pf_q_num = SEC_PF_DEF_Q_NUM;368module_param_cb(pf_q_num, &sec_pf_q_num_ops, &pf_q_num, 0444);369MODULE_PARM_DESC(pf_q_num, "Number of queues in PF(v1 2-4096, v2 2-1024)");370371static int sec_ctx_q_num_set(const char *val, const struct kernel_param *kp)372{373u32 ctx_q_num;374int ret;375376if (!val)377return -EINVAL;378379ret = kstrtou32(val, 10, &ctx_q_num);380if (ret)381return -EINVAL;382383if (!ctx_q_num || ctx_q_num > SEC_CTX_Q_NUM_MAX || ctx_q_num & 0x1) {384pr_err("ctx queue num[%u] is invalid!\n", ctx_q_num);385return -EINVAL;386}387388return param_set_int(val, kp);389}390391static const struct kernel_param_ops sec_ctx_q_num_ops = {392.set = sec_ctx_q_num_set,393.get = param_get_int,394};395static u32 ctx_q_num = SEC_CTX_Q_NUM_DEF;396module_param_cb(ctx_q_num, &sec_ctx_q_num_ops, &ctx_q_num, 0444);397MODULE_PARM_DESC(ctx_q_num, "Queue num in ctx (2 default, 2, 4, ..., 32)");398399static const struct kernel_param_ops vfs_num_ops = {400.set = vfs_num_set,401.get = param_get_int,402};403404static u32 vfs_num;405module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);406MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)");407408void sec_destroy_qps(struct hisi_qp **qps, int qp_num)409{410hisi_qm_free_qps(qps, qp_num);411kfree(qps);412}413414struct hisi_qp **sec_create_qps(void)415{416int node = cpu_to_node(raw_smp_processor_id());417u32 ctx_num = ctx_q_num;418struct hisi_qp **qps;419u8 *type;420int ret;421422qps = kcalloc(ctx_num, sizeof(struct hisi_qp *), GFP_KERNEL);423if (!qps)424return NULL;425426/* The type of SEC is all 0, so just allocated by kcalloc */427type = kcalloc(ctx_num, sizeof(u8), GFP_KERNEL);428if (!type) {429kfree(qps);430return NULL;431}432433ret = hisi_qm_alloc_qps_node(&sec_devices, ctx_num, type, node, qps);434if (ret) {435kfree(type);436kfree(qps);437return NULL;438}439440kfree(type);441return qps;442}443444u64 sec_get_alg_bitmap(struct hisi_qm *qm, u32 high, u32 low)445{446u32 cap_val_h, cap_val_l;447448cap_val_h = qm->cap_tables.dev_cap_table[high].cap_val;449cap_val_l = qm->cap_tables.dev_cap_table[low].cap_val;450451return ((u64)cap_val_h << SEC_ALG_BITMAP_SHIFT) | (u64)cap_val_l;452}453454static const struct kernel_param_ops sec_uacce_mode_ops = {455.set = uacce_mode_set,456.get = param_get_int,457};458459/*460* uacce_mode = 0 means sec only register to crypto,461* uacce_mode = 1 means sec both register to crypto and uacce.462*/463static u32 uacce_mode = UACCE_MODE_NOUACCE;464module_param_cb(uacce_mode, &sec_uacce_mode_ops, &uacce_mode, 0444);465MODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC);466467static const struct pci_device_id sec_dev_ids[] = {468{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_SEC_PF) },469{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_SEC_VF) },470{ 0, }471};472MODULE_DEVICE_TABLE(pci, sec_dev_ids);473474static void sec_set_endian(struct hisi_qm *qm)475{476u32 reg;477478reg = readl_relaxed(qm->io_base + SEC_CONTROL_REG);479reg &= ~(BIT(1) | BIT(0));480if (!IS_ENABLED(CONFIG_64BIT))481reg |= BIT(1);482483if (!IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN))484reg |= BIT(0);485486writel_relaxed(reg, qm->io_base + SEC_CONTROL_REG);487}488489static int sec_wait_sva_ready(struct hisi_qm *qm, __u32 offset, __u32 mask)490{491u32 val, try_times = 0;492u8 count = 0;493494/*495* Read the register value every 10-20us. If the value is 0 for three496* consecutive times, the SVA module is ready.497*/498do {499val = readl(qm->io_base + offset);500if (val & mask)501count = 0;502else if (++count == SEC_READ_SVA_STATUS_TIMES)503break;504505usleep_range(SEC_WAIT_US_MIN, SEC_WAIT_US_MAX);506} while (++try_times < SEC_WAIT_SVA_READY);507508if (try_times == SEC_WAIT_SVA_READY) {509pci_err(qm->pdev, "failed to wait sva prefetch ready\n");510return -ETIMEDOUT;511}512513return 0;514}515516static void sec_close_sva_prefetch(struct hisi_qm *qm)517{518u32 val;519int ret;520521if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))522return;523524val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG);525val |= SEC_PREFETCH_DISABLE;526writel(val, qm->io_base + SEC_PREFETCH_CFG);527528ret = readl_relaxed_poll_timeout(qm->io_base + SEC_SVA_TRANS,529val, !(val & SEC_SVA_DISABLE_READY),530SEC_DELAY_10_US, SEC_POLL_TIMEOUT_US);531if (ret)532pci_err(qm->pdev, "failed to close sva prefetch\n");533534(void)sec_wait_sva_ready(qm, SEC_SVA_PREFETCH_INFO, SEC_SVA_STALL_NUM);535}536537static void sec_open_sva_prefetch(struct hisi_qm *qm)538{539u32 val;540int ret;541542if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))543return;544545/* Enable prefetch */546val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG);547val &= SEC_PREFETCH_ENABLE;548writel(val, qm->io_base + SEC_PREFETCH_CFG);549550ret = readl_relaxed_poll_timeout(qm->io_base + SEC_PREFETCH_CFG,551val, !(val & SEC_PREFETCH_DISABLE),552SEC_DELAY_10_US, SEC_POLL_TIMEOUT_US);553if (ret) {554pci_err(qm->pdev, "failed to open sva prefetch\n");555sec_close_sva_prefetch(qm);556return;557}558559ret = sec_wait_sva_ready(qm, SEC_SVA_TRANS, SEC_SVA_PREFETCH_NUM);560if (ret)561sec_close_sva_prefetch(qm);562}563564static void sec_engine_sva_config(struct hisi_qm *qm)565{566u32 reg;567568if (qm->ver > QM_HW_V2) {569reg = readl_relaxed(qm->io_base +570SEC_INTERFACE_USER_CTRL0_REG_V3);571reg |= SEC_USER0_SMMU_NORMAL;572writel_relaxed(reg, qm->io_base +573SEC_INTERFACE_USER_CTRL0_REG_V3);574575reg = readl_relaxed(qm->io_base +576SEC_INTERFACE_USER_CTRL1_REG_V3);577reg &= SEC_USER1_SMMU_MASK_V3;578reg |= SEC_USER1_SMMU_NORMAL_V3;579writel_relaxed(reg, qm->io_base +580SEC_INTERFACE_USER_CTRL1_REG_V3);581} else {582reg = readl_relaxed(qm->io_base +583SEC_INTERFACE_USER_CTRL0_REG);584reg |= SEC_USER0_SMMU_NORMAL;585writel_relaxed(reg, qm->io_base +586SEC_INTERFACE_USER_CTRL0_REG);587reg = readl_relaxed(qm->io_base +588SEC_INTERFACE_USER_CTRL1_REG);589reg &= SEC_USER1_SMMU_MASK;590if (qm->use_sva)591reg |= SEC_USER1_SMMU_SVA;592else593reg |= SEC_USER1_SMMU_NORMAL;594writel_relaxed(reg, qm->io_base +595SEC_INTERFACE_USER_CTRL1_REG);596}597sec_open_sva_prefetch(qm);598}599600static void sec_enable_clock_gate(struct hisi_qm *qm)601{602u32 val;603604if (qm->ver < QM_HW_V3)605return;606607val = readl_relaxed(qm->io_base + SEC_CONTROL_REG);608val |= SEC_CLK_GATE_ENABLE;609writel_relaxed(val, qm->io_base + SEC_CONTROL_REG);610611val = readl(qm->io_base + SEC_DYNAMIC_GATE_REG);612val |= SEC_DYNAMIC_GATE_EN;613writel(val, qm->io_base + SEC_DYNAMIC_GATE_REG);614615val = readl(qm->io_base + SEC_CORE_AUTO_GATE);616val |= SEC_CORE_AUTO_GATE_EN;617writel(val, qm->io_base + SEC_CORE_AUTO_GATE);618}619620static void sec_disable_clock_gate(struct hisi_qm *qm)621{622u32 val;623624/* Kunpeng920 needs to close clock gating */625val = readl_relaxed(qm->io_base + SEC_CONTROL_REG);626val &= SEC_CLK_GATE_DISABLE;627writel_relaxed(val, qm->io_base + SEC_CONTROL_REG);628}629630static int sec_engine_init(struct hisi_qm *qm)631{632int ret;633u32 reg;634635/* disable clock gate control before mem init */636sec_disable_clock_gate(qm);637638writel_relaxed(0x1, qm->io_base + SEC_MEM_START_INIT_REG);639640ret = readl_relaxed_poll_timeout(qm->io_base + SEC_MEM_INIT_DONE_REG,641reg, reg & 0x1, SEC_DELAY_10_US,642SEC_POLL_TIMEOUT_US);643if (ret) {644pci_err(qm->pdev, "fail to init sec mem\n");645return ret;646}647648reg = readl_relaxed(qm->io_base + SEC_CONTROL_REG);649reg |= (0x1 << SEC_TRNG_EN_SHIFT);650writel_relaxed(reg, qm->io_base + SEC_CONTROL_REG);651652sec_engine_sva_config(qm);653654writel(SEC_SINGLE_PORT_MAX_TRANS,655qm->io_base + AM_CFG_SINGLE_PORT_MAX_TRANS);656657reg = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_CORE_ENABLE_BITMAP, qm->cap_ver);658writel(reg, qm->io_base + SEC_SAA_EN_REG);659660if (qm->ver < QM_HW_V3) {661/* HW V2 enable sm4 extra mode, as ctr/ecb */662writel_relaxed(SEC_BD_ERR_CHK_EN0,663qm->io_base + SEC_BD_ERR_CHK_EN_REG0);664665/* HW V2 enable sm4 xts mode multiple iv */666writel_relaxed(SEC_BD_ERR_CHK_EN1,667qm->io_base + SEC_BD_ERR_CHK_EN_REG1);668writel_relaxed(SEC_BD_ERR_CHK_EN3,669qm->io_base + SEC_BD_ERR_CHK_EN_REG3);670}671672/* config endian */673sec_set_endian(qm);674675sec_enable_clock_gate(qm);676677return 0;678}679680static int sec_set_user_domain_and_cache(struct hisi_qm *qm)681{682/* qm user domain */683writel(AXUSER_BASE, qm->io_base + QM_ARUSER_M_CFG_1);684writel(ARUSER_M_CFG_ENABLE, qm->io_base + QM_ARUSER_M_CFG_ENABLE);685writel(AXUSER_BASE, qm->io_base + QM_AWUSER_M_CFG_1);686writel(AWUSER_M_CFG_ENABLE, qm->io_base + QM_AWUSER_M_CFG_ENABLE);687writel(WUSER_M_CFG_ENABLE, qm->io_base + QM_WUSER_M_CFG_ENABLE);688689/* qm cache */690writel(AXI_M_CFG, qm->io_base + QM_AXI_M_CFG);691writel(AXI_M_CFG_ENABLE, qm->io_base + QM_AXI_M_CFG_ENABLE);692693/* disable FLR triggered by BME(bus master enable) */694writel(PEH_AXUSER_CFG, qm->io_base + QM_PEH_AXUSER_CFG);695writel(PEH_AXUSER_CFG_ENABLE, qm->io_base + QM_PEH_AXUSER_CFG_ENABLE);696697/* enable sqc,cqc writeback */698writel(SQC_CACHE_ENABLE | CQC_CACHE_ENABLE | SQC_CACHE_WB_ENABLE |699CQC_CACHE_WB_ENABLE | FIELD_PREP(SQC_CACHE_WB_THRD, 1) |700FIELD_PREP(CQC_CACHE_WB_THRD, 1), qm->io_base + QM_CACHE_CTL);701702return sec_engine_init(qm);703}704705/* sec_debug_regs_clear() - clear the sec debug regs */706static void sec_debug_regs_clear(struct hisi_qm *qm)707{708int i;709710/* clear sec dfx regs */711writel(0x1, qm->io_base + SEC_CTRL_CNT_CLR_CE);712for (i = 0; i < ARRAY_SIZE(sec_dfx_regs); i++)713readl(qm->io_base + sec_dfx_regs[i].offset);714715/* clear rdclr_en */716writel(0x0, qm->io_base + SEC_CTRL_CNT_CLR_CE);717718hisi_qm_debug_regs_clear(qm);719}720721static void sec_master_ooo_ctrl(struct hisi_qm *qm, bool enable)722{723u32 val1, val2;724725val1 = readl(qm->io_base + SEC_CONTROL_REG);726if (enable) {727val1 |= SEC_AXI_SHUTDOWN_ENABLE;728val2 = qm->err_info.dev_err.shutdown_mask;729} else {730val1 &= SEC_AXI_SHUTDOWN_DISABLE;731val2 = 0x0;732}733734if (qm->ver > QM_HW_V2)735writel(val2, qm->io_base + SEC_OOO_SHUTDOWN_SEL);736737writel(val1, qm->io_base + SEC_CONTROL_REG);738}739740static void sec_hw_error_enable(struct hisi_qm *qm)741{742struct hisi_qm_err_mask *dev_err = &qm->err_info.dev_err;743u32 err_mask = dev_err->ce | dev_err->nfe | dev_err->fe;744745if (qm->ver == QM_HW_V1) {746writel(SEC_CORE_INT_DISABLE, qm->io_base + SEC_CORE_INT_MASK);747pci_info(qm->pdev, "V1 not support hw error handle\n");748return;749}750751/* clear SEC hw error source if having */752writel(err_mask, qm->io_base + SEC_CORE_INT_SOURCE);753754/* enable RAS int */755writel(dev_err->ce, qm->io_base + SEC_RAS_CE_REG);756writel(dev_err->fe, qm->io_base + SEC_RAS_FE_REG);757writel(dev_err->nfe, qm->io_base + SEC_RAS_NFE_REG);758759/* enable SEC block master OOO when nfe occurs on Kunpeng930 */760sec_master_ooo_ctrl(qm, true);761762/* enable SEC hw error interrupts */763writel(err_mask, qm->io_base + SEC_CORE_INT_MASK);764}765766static void sec_hw_error_disable(struct hisi_qm *qm)767{768/* disable SEC hw error interrupts */769writel(SEC_CORE_INT_DISABLE, qm->io_base + SEC_CORE_INT_MASK);770771/* disable SEC block master OOO when nfe occurs on Kunpeng930 */772sec_master_ooo_ctrl(qm, false);773774/* disable RAS int */775writel(SEC_RAS_DISABLE, qm->io_base + SEC_RAS_CE_REG);776writel(SEC_RAS_DISABLE, qm->io_base + SEC_RAS_FE_REG);777writel(SEC_RAS_DISABLE, qm->io_base + SEC_RAS_NFE_REG);778}779780static u32 sec_clear_enable_read(struct hisi_qm *qm)781{782return readl(qm->io_base + SEC_CTRL_CNT_CLR_CE) &783SEC_CTRL_CNT_CLR_CE_BIT;784}785786static int sec_clear_enable_write(struct hisi_qm *qm, u32 val)787{788u32 tmp;789790if (val != 1 && val)791return -EINVAL;792793tmp = (readl(qm->io_base + SEC_CTRL_CNT_CLR_CE) &794~SEC_CTRL_CNT_CLR_CE_BIT) | val;795writel(tmp, qm->io_base + SEC_CTRL_CNT_CLR_CE);796797return 0;798}799800static ssize_t sec_debug_read(struct file *filp, char __user *buf,801size_t count, loff_t *pos)802{803struct sec_debug_file *file = filp->private_data;804char tbuf[SEC_DBGFS_VAL_MAX_LEN];805struct hisi_qm *qm = file->qm;806u32 val;807int ret;808809ret = hisi_qm_get_dfx_access(qm);810if (ret)811return ret;812813spin_lock_irq(&file->lock);814815switch (file->index) {816case SEC_CLEAR_ENABLE:817val = sec_clear_enable_read(qm);818break;819default:820goto err_input;821}822823spin_unlock_irq(&file->lock);824825hisi_qm_put_dfx_access(qm);826ret = snprintf(tbuf, SEC_DBGFS_VAL_MAX_LEN, "%u\n", val);827return simple_read_from_buffer(buf, count, pos, tbuf, ret);828829err_input:830spin_unlock_irq(&file->lock);831hisi_qm_put_dfx_access(qm);832return -EINVAL;833}834835static ssize_t sec_debug_write(struct file *filp, const char __user *buf,836size_t count, loff_t *pos)837{838struct sec_debug_file *file = filp->private_data;839char tbuf[SEC_DBGFS_VAL_MAX_LEN];840struct hisi_qm *qm = file->qm;841unsigned long val;842int len, ret;843844if (*pos != 0)845return 0;846847if (count >= SEC_DBGFS_VAL_MAX_LEN)848return -ENOSPC;849850len = simple_write_to_buffer(tbuf, SEC_DBGFS_VAL_MAX_LEN - 1,851pos, buf, count);852if (len < 0)853return len;854855tbuf[len] = '\0';856if (kstrtoul(tbuf, 0, &val))857return -EFAULT;858859ret = hisi_qm_get_dfx_access(qm);860if (ret)861return ret;862863spin_lock_irq(&file->lock);864865switch (file->index) {866case SEC_CLEAR_ENABLE:867ret = sec_clear_enable_write(qm, val);868if (ret)869goto err_input;870break;871default:872ret = -EINVAL;873goto err_input;874}875876ret = count;877878err_input:879spin_unlock_irq(&file->lock);880hisi_qm_put_dfx_access(qm);881return ret;882}883884static const struct file_operations sec_dbg_fops = {885.owner = THIS_MODULE,886.open = simple_open,887.read = sec_debug_read,888.write = sec_debug_write,889};890891static int sec_debugfs_atomic64_get(void *data, u64 *val)892{893*val = atomic64_read((atomic64_t *)data);894895return 0;896}897898static int sec_debugfs_atomic64_set(void *data, u64 val)899{900if (val)901return -EINVAL;902903atomic64_set((atomic64_t *)data, 0);904905return 0;906}907908DEFINE_DEBUGFS_ATTRIBUTE(sec_atomic64_ops, sec_debugfs_atomic64_get,909sec_debugfs_atomic64_set, "%lld\n");910911static int sec_regs_show(struct seq_file *s, void *unused)912{913hisi_qm_regs_dump(s, s->private);914915return 0;916}917918DEFINE_SHOW_ATTRIBUTE(sec_regs);919920static int sec_cap_regs_show(struct seq_file *s, void *unused)921{922struct hisi_qm *qm = s->private;923u32 i, size;924925size = qm->cap_tables.qm_cap_size;926for (i = 0; i < size; i++)927seq_printf(s, "%s= 0x%08x\n", qm->cap_tables.qm_cap_table[i].name,928qm->cap_tables.qm_cap_table[i].cap_val);929930size = qm->cap_tables.dev_cap_size;931for (i = 0; i < size; i++)932seq_printf(s, "%s= 0x%08x\n", qm->cap_tables.dev_cap_table[i].name,933qm->cap_tables.dev_cap_table[i].cap_val);934935return 0;936}937938DEFINE_SHOW_ATTRIBUTE(sec_cap_regs);939940static int sec_core_debug_init(struct hisi_qm *qm)941{942struct dfx_diff_registers *sec_regs = qm->debug.acc_diff_regs;943struct sec_dev *sec = container_of(qm, struct sec_dev, qm);944struct device *dev = &qm->pdev->dev;945struct sec_dfx *dfx = &sec->debug.dfx;946struct debugfs_regset32 *regset;947struct dentry *tmp_d;948int i;949950tmp_d = debugfs_create_dir("sec_dfx", qm->debug.debug_root);951952regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);953if (!regset)954return -ENOMEM;955956regset->regs = sec_dfx_regs;957regset->nregs = ARRAY_SIZE(sec_dfx_regs);958regset->base = qm->io_base;959regset->dev = dev;960961if (qm->pdev->device == PCI_DEVICE_ID_HUAWEI_SEC_PF)962debugfs_create_file("regs", 0444, tmp_d, regset, &sec_regs_fops);963if (qm->fun_type == QM_HW_PF && sec_regs)964debugfs_create_file("diff_regs", 0444, tmp_d,965qm, &sec_diff_regs_fops);966967for (i = 0; i < ARRAY_SIZE(sec_dfx_labels); i++) {968atomic64_t *data = (atomic64_t *)((uintptr_t)dfx +969sec_dfx_labels[i].offset);970debugfs_create_file(sec_dfx_labels[i].name, 0644,971tmp_d, data, &sec_atomic64_ops);972}973974debugfs_create_file("cap_regs", CAP_FILE_PERMISSION,975qm->debug.debug_root, qm, &sec_cap_regs_fops);976977return 0;978}979980static int sec_debug_init(struct hisi_qm *qm)981{982struct sec_dev *sec = container_of(qm, struct sec_dev, qm);983int i;984985if (qm->pdev->device == PCI_DEVICE_ID_HUAWEI_SEC_PF) {986for (i = SEC_CLEAR_ENABLE; i < SEC_DEBUG_FILE_NUM; i++) {987spin_lock_init(&sec->debug.files[i].lock);988sec->debug.files[i].index = i;989sec->debug.files[i].qm = qm;990991debugfs_create_file(sec_dbg_file_name[i], 0600,992qm->debug.debug_root,993sec->debug.files + i,994&sec_dbg_fops);995}996}997998return sec_core_debug_init(qm);999}10001001static int sec_debugfs_init(struct hisi_qm *qm)1002{1003struct device *dev = &qm->pdev->dev;1004int ret;10051006ret = hisi_qm_regs_debugfs_init(qm, sec_diff_regs, ARRAY_SIZE(sec_diff_regs));1007if (ret) {1008dev_warn(dev, "Failed to init SEC diff regs!\n");1009return ret;1010}10111012qm->debug.debug_root = debugfs_create_dir(dev_name(dev),1013sec_debugfs_root);1014qm->debug.sqe_mask_offset = SEC_SQE_MASK_OFFSET;1015qm->debug.sqe_mask_len = SEC_SQE_MASK_LEN;10161017hisi_qm_debug_init(qm);10181019ret = sec_debug_init(qm);1020if (ret)1021goto debugfs_remove;10221023return 0;10241025debugfs_remove:1026debugfs_remove_recursive(qm->debug.debug_root);1027hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(sec_diff_regs));1028return ret;1029}10301031static void sec_debugfs_exit(struct hisi_qm *qm)1032{1033debugfs_remove_recursive(qm->debug.debug_root);10341035hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(sec_diff_regs));1036}10371038static int sec_show_last_regs_init(struct hisi_qm *qm)1039{1040struct qm_debug *debug = &qm->debug;1041int i;10421043debug->last_words = kcalloc(ARRAY_SIZE(sec_dfx_regs),1044sizeof(unsigned int), GFP_KERNEL);1045if (!debug->last_words)1046return -ENOMEM;10471048for (i = 0; i < ARRAY_SIZE(sec_dfx_regs); i++)1049debug->last_words[i] = readl_relaxed(qm->io_base +1050sec_dfx_regs[i].offset);10511052return 0;1053}10541055static void sec_show_last_regs_uninit(struct hisi_qm *qm)1056{1057struct qm_debug *debug = &qm->debug;10581059if (qm->fun_type == QM_HW_VF || !debug->last_words)1060return;10611062kfree(debug->last_words);1063debug->last_words = NULL;1064}10651066static void sec_show_last_dfx_regs(struct hisi_qm *qm)1067{1068struct qm_debug *debug = &qm->debug;1069struct pci_dev *pdev = qm->pdev;1070u32 val;1071int i;10721073if (qm->fun_type == QM_HW_VF || !debug->last_words)1074return;10751076/* dumps last word of the debugging registers during controller reset */1077for (i = 0; i < ARRAY_SIZE(sec_dfx_regs); i++) {1078val = readl_relaxed(qm->io_base + sec_dfx_regs[i].offset);1079if (val != debug->last_words[i])1080pci_info(pdev, "%s \t= 0x%08x => 0x%08x\n",1081sec_dfx_regs[i].name, debug->last_words[i], val);1082}1083}10841085static void sec_log_hw_error(struct hisi_qm *qm, u32 err_sts)1086{1087const struct sec_hw_error *errs = sec_hw_errors;1088struct device *dev = &qm->pdev->dev;1089u32 err_val;10901091while (errs->msg) {1092if (errs->int_msk & err_sts) {1093dev_err(dev, "%s [error status=0x%x] found\n",1094errs->msg, errs->int_msk);10951096if (SEC_CORE_INT_STATUS_M_ECC & errs->int_msk) {1097err_val = readl(qm->io_base +1098SEC_CORE_SRAM_ECC_ERR_INFO);1099dev_err(dev, "multi ecc sram num=0x%x\n",1100((err_val) >> SEC_ECC_NUM) &1101SEC_ECC_MASH);1102}1103}1104errs++;1105}1106}11071108static u32 sec_get_hw_err_status(struct hisi_qm *qm)1109{1110return readl(qm->io_base + SEC_CORE_INT_STATUS);1111}11121113static void sec_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)1114{1115writel(err_sts, qm->io_base + SEC_CORE_INT_SOURCE);1116}11171118static void sec_disable_error_report(struct hisi_qm *qm, u32 err_type)1119{1120u32 nfe_mask = qm->err_info.dev_err.nfe;11211122writel(nfe_mask & (~err_type), qm->io_base + SEC_RAS_NFE_REG);1123}11241125static void sec_enable_error_report(struct hisi_qm *qm)1126{1127u32 nfe_mask = qm->err_info.dev_err.nfe;1128u32 ce_mask = qm->err_info.dev_err.ce;11291130writel(nfe_mask, qm->io_base + SEC_RAS_NFE_REG);1131writel(ce_mask, qm->io_base + SEC_RAS_CE_REG);1132}11331134static void sec_open_axi_master_ooo(struct hisi_qm *qm)1135{1136u32 val;11371138val = readl(qm->io_base + SEC_CONTROL_REG);1139writel(val & SEC_AXI_SHUTDOWN_DISABLE, qm->io_base + SEC_CONTROL_REG);1140writel(val | SEC_AXI_SHUTDOWN_ENABLE, qm->io_base + SEC_CONTROL_REG);1141}11421143static enum acc_err_result sec_get_err_result(struct hisi_qm *qm)1144{1145u32 err_status;11461147err_status = sec_get_hw_err_status(qm);1148if (err_status) {1149if (err_status & qm->err_info.dev_err.ecc_2bits_mask)1150qm->err_status.is_dev_ecc_mbit = true;1151sec_log_hw_error(qm, err_status);11521153if (err_status & qm->err_info.dev_err.reset_mask) {1154/* Disable the same error reporting until device is recovered. */1155sec_disable_error_report(qm, err_status);1156return ACC_ERR_NEED_RESET;1157}1158sec_clear_hw_err_status(qm, err_status);1159/* Avoid firmware disable error report, re-enable. */1160sec_enable_error_report(qm);1161}11621163return ACC_ERR_RECOVERED;1164}11651166static bool sec_dev_is_abnormal(struct hisi_qm *qm)1167{1168u32 err_status;11691170err_status = sec_get_hw_err_status(qm);1171if (err_status & qm->err_info.dev_err.shutdown_mask)1172return true;11731174return false;1175}11761177static void sec_disable_axi_error(struct hisi_qm *qm)1178{1179struct hisi_qm_err_mask *dev_err = &qm->err_info.dev_err;1180u32 err_mask = dev_err->ce | dev_err->nfe | dev_err->fe;11811182writel(err_mask & ~SEC_AXI_ERROR_MASK, qm->io_base + SEC_CORE_INT_MASK);11831184if (qm->ver > QM_HW_V2)1185writel(dev_err->shutdown_mask & (~SEC_AXI_ERROR_MASK),1186qm->io_base + SEC_OOO_SHUTDOWN_SEL);1187}11881189static void sec_enable_axi_error(struct hisi_qm *qm)1190{1191struct hisi_qm_err_mask *dev_err = &qm->err_info.dev_err;1192u32 err_mask = dev_err->ce | dev_err->nfe | dev_err->fe;11931194/* clear axi error source */1195writel(SEC_AXI_ERROR_MASK, qm->io_base + SEC_CORE_INT_SOURCE);11961197writel(err_mask, qm->io_base + SEC_CORE_INT_MASK);11981199if (qm->ver > QM_HW_V2)1200writel(dev_err->shutdown_mask, qm->io_base + SEC_OOO_SHUTDOWN_SEL);1201}12021203static void sec_err_info_init(struct hisi_qm *qm)1204{1205struct hisi_qm_err_info *err_info = &qm->err_info;1206struct hisi_qm_err_mask *qm_err = &err_info->qm_err;1207struct hisi_qm_err_mask *dev_err = &err_info->dev_err;12081209qm_err->fe = SEC_RAS_FE_ENB_MSK;1210qm_err->ce = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_QM_CE_MASK_CAP, qm->cap_ver);1211qm_err->nfe = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_QM_NFE_MASK_CAP, qm->cap_ver);1212qm_err->shutdown_mask = hisi_qm_get_hw_info(qm, sec_basic_info,1213SEC_QM_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver);1214qm_err->reset_mask = hisi_qm_get_hw_info(qm, sec_basic_info,1215SEC_QM_RESET_MASK_CAP, qm->cap_ver);1216qm_err->ecc_2bits_mask = QM_ECC_MBIT;12171218dev_err->fe = SEC_RAS_FE_ENB_MSK;1219dev_err->ce = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_CE_MASK_CAP, qm->cap_ver);1220dev_err->nfe = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_NFE_MASK_CAP, qm->cap_ver);1221dev_err->shutdown_mask = hisi_qm_get_hw_info(qm, sec_basic_info,1222SEC_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver);1223dev_err->reset_mask = hisi_qm_get_hw_info(qm, sec_basic_info,1224SEC_RESET_MASK_CAP, qm->cap_ver);1225dev_err->ecc_2bits_mask = SEC_CORE_INT_STATUS_M_ECC;12261227err_info->msi_wr_port = BIT(0);1228err_info->acpi_rst = "SRST";1229}12301231static const struct hisi_qm_err_ini sec_err_ini = {1232.hw_init = sec_set_user_domain_and_cache,1233.hw_err_enable = sec_hw_error_enable,1234.hw_err_disable = sec_hw_error_disable,1235.get_dev_hw_err_status = sec_get_hw_err_status,1236.clear_dev_hw_err_status = sec_clear_hw_err_status,1237.open_axi_master_ooo = sec_open_axi_master_ooo,1238.open_sva_prefetch = sec_open_sva_prefetch,1239.close_sva_prefetch = sec_close_sva_prefetch,1240.show_last_dfx_regs = sec_show_last_dfx_regs,1241.err_info_init = sec_err_info_init,1242.get_err_result = sec_get_err_result,1243.dev_is_abnormal = sec_dev_is_abnormal,1244.disable_axi_error = sec_disable_axi_error,1245.enable_axi_error = sec_enable_axi_error,1246};12471248static int sec_pf_probe_init(struct sec_dev *sec)1249{1250struct hisi_qm *qm = &sec->qm;1251int ret;12521253ret = sec_set_user_domain_and_cache(qm);1254if (ret)1255return ret;12561257hisi_qm_dev_err_init(qm);1258sec_debug_regs_clear(qm);1259ret = sec_show_last_regs_init(qm);1260if (ret)1261pci_err(qm->pdev, "Failed to init last word regs!\n");12621263return ret;1264}12651266static int sec_pre_store_cap_reg(struct hisi_qm *qm)1267{1268struct hisi_qm_cap_record *sec_cap;1269struct pci_dev *pdev = qm->pdev;1270size_t i, size;12711272size = ARRAY_SIZE(sec_cap_query_info);1273sec_cap = devm_kcalloc(&pdev->dev, size, sizeof(*sec_cap), GFP_KERNEL);1274if (!sec_cap)1275return -ENOMEM;12761277for (i = 0; i < size; i++) {1278sec_cap[i].type = sec_cap_query_info[i].type;1279sec_cap[i].name = sec_cap_query_info[i].name;1280sec_cap[i].cap_val = hisi_qm_get_cap_value(qm, sec_cap_query_info,1281i, qm->cap_ver);1282}12831284qm->cap_tables.dev_cap_table = sec_cap;1285qm->cap_tables.dev_cap_size = size;12861287return 0;1288}12891290static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)1291{1292u64 alg_msk;1293int ret;12941295qm->pdev = pdev;1296qm->mode = uacce_mode;1297qm->sqe_size = SEC_SQE_SIZE;1298qm->dev_name = sec_name;12991300qm->fun_type = (pdev->device == PCI_DEVICE_ID_HUAWEI_SEC_PF) ?1301QM_HW_PF : QM_HW_VF;1302if (qm->fun_type == QM_HW_PF) {1303qm->qp_base = SEC_PF_DEF_Q_BASE;1304qm->qp_num = pf_q_num;1305qm->debug.curr_qm_qp_num = pf_q_num;1306qm->qm_list = &sec_devices;1307qm->err_ini = &sec_err_ini;1308if (pf_q_num_flag)1309set_bit(QM_MODULE_PARAM, &qm->misc_ctl);1310} else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {1311/*1312* have no way to get qm configure in VM in v1 hardware,1313* so currently force PF to uses SEC_PF_DEF_Q_NUM, and force1314* to trigger only one VF in v1 hardware.1315* v2 hardware has no such problem.1316*/1317qm->qp_base = SEC_PF_DEF_Q_NUM;1318qm->qp_num = SEC_QUEUE_NUM_V1 - SEC_PF_DEF_Q_NUM;1319}13201321ret = hisi_qm_init(qm);1322if (ret) {1323pci_err(qm->pdev, "Failed to init sec qm configures!\n");1324return ret;1325}13261327/* Fetch and save the value of capability registers */1328ret = sec_pre_store_cap_reg(qm);1329if (ret) {1330pci_err(qm->pdev, "Failed to pre-store capability registers!\n");1331hisi_qm_uninit(qm);1332return ret;1333}1334alg_msk = sec_get_alg_bitmap(qm, SEC_ALG_BITMAP_HIGH, SEC_ALG_BITMAP_LOW);1335ret = hisi_qm_set_algs(qm, alg_msk, sec_dev_algs, ARRAY_SIZE(sec_dev_algs));1336if (ret) {1337pci_err(qm->pdev, "Failed to set sec algs!\n");1338hisi_qm_uninit(qm);1339}13401341return ret;1342}13431344static void sec_qm_uninit(struct hisi_qm *qm)1345{1346hisi_qm_uninit(qm);1347}13481349static int sec_probe_init(struct sec_dev *sec)1350{1351u32 type_rate = SEC_SHAPER_TYPE_RATE;1352struct hisi_qm *qm = &sec->qm;1353int ret;13541355if (qm->fun_type == QM_HW_PF) {1356ret = sec_pf_probe_init(sec);1357if (ret)1358return ret;1359/* enable shaper type 0 */1360if (qm->ver >= QM_HW_V3) {1361type_rate |= QM_SHAPER_ENABLE;1362qm->type_rate = type_rate;1363}1364}13651366return 0;1367}13681369static void sec_probe_uninit(struct hisi_qm *qm)1370{1371if (qm->fun_type == QM_HW_VF)1372return;13731374sec_debug_regs_clear(qm);1375sec_show_last_regs_uninit(qm);1376sec_close_sva_prefetch(qm);1377hisi_qm_dev_err_uninit(qm);1378}13791380static void sec_iommu_used_check(struct sec_dev *sec)1381{1382struct iommu_domain *domain;1383struct device *dev = &sec->qm.pdev->dev;13841385domain = iommu_get_domain_for_dev(dev);13861387/* Check if iommu is used */1388sec->iommu_used = false;1389if (domain) {1390if (domain->type & __IOMMU_DOMAIN_PAGING)1391sec->iommu_used = true;1392dev_info(dev, "SMMU Opened, the iommu type = %u\n",1393domain->type);1394}1395}13961397static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id)1398{1399struct sec_dev *sec;1400struct hisi_qm *qm;1401int ret;14021403sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL);1404if (!sec)1405return -ENOMEM;14061407qm = &sec->qm;1408ret = sec_qm_init(qm, pdev);1409if (ret) {1410pci_err(pdev, "Failed to init SEC QM (%d)!\n", ret);1411return ret;1412}14131414sec->ctx_q_num = ctx_q_num;1415sec_iommu_used_check(sec);14161417ret = sec_probe_init(sec);1418if (ret) {1419pci_err(pdev, "Failed to probe!\n");1420goto err_qm_uninit;1421}14221423ret = hisi_qm_start(qm);1424if (ret) {1425pci_err(pdev, "Failed to start sec qm!\n");1426goto err_probe_uninit;1427}14281429ret = sec_debugfs_init(qm);1430if (ret)1431pci_warn(pdev, "Failed to init debugfs!\n");14321433hisi_qm_add_list(qm, &sec_devices);1434ret = hisi_qm_alg_register(qm, &sec_devices, ctx_q_num);1435if (ret < 0) {1436pr_err("Failed to register driver to crypto.\n");1437goto err_qm_del_list;1438}14391440if (qm->uacce) {1441ret = uacce_register(qm->uacce);1442if (ret) {1443pci_err(pdev, "failed to register uacce (%d)!\n", ret);1444goto err_alg_unregister;1445}1446}14471448if (qm->fun_type == QM_HW_PF && vfs_num) {1449ret = hisi_qm_sriov_enable(pdev, vfs_num);1450if (ret < 0)1451goto err_alg_unregister;1452}14531454hisi_qm_pm_init(qm);14551456return 0;14571458err_alg_unregister:1459hisi_qm_alg_unregister(qm, &sec_devices, ctx_q_num);1460err_qm_del_list:1461hisi_qm_del_list(qm, &sec_devices);1462sec_debugfs_exit(qm);1463hisi_qm_stop(qm, QM_NORMAL);1464err_probe_uninit:1465sec_probe_uninit(qm);1466err_qm_uninit:1467sec_qm_uninit(qm);1468return ret;1469}14701471static void sec_remove(struct pci_dev *pdev)1472{1473struct hisi_qm *qm = pci_get_drvdata(pdev);14741475hisi_qm_pm_uninit(qm);1476hisi_qm_wait_task_finish(qm, &sec_devices);1477hisi_qm_alg_unregister(qm, &sec_devices, ctx_q_num);1478hisi_qm_del_list(qm, &sec_devices);14791480if (qm->fun_type == QM_HW_PF && qm->vfs_num)1481hisi_qm_sriov_disable(pdev, true);14821483sec_debugfs_exit(qm);14841485(void)hisi_qm_stop(qm, QM_NORMAL);1486sec_probe_uninit(qm);14871488sec_qm_uninit(qm);1489}14901491static const struct dev_pm_ops sec_pm_ops = {1492SET_RUNTIME_PM_OPS(hisi_qm_suspend, hisi_qm_resume, NULL)1493};14941495static const struct pci_error_handlers sec_err_handler = {1496.error_detected = hisi_qm_dev_err_detected,1497.slot_reset = hisi_qm_dev_slot_reset,1498.reset_prepare = hisi_qm_reset_prepare,1499.reset_done = hisi_qm_reset_done,1500};15011502static struct pci_driver sec_pci_driver = {1503.name = "hisi_sec2",1504.id_table = sec_dev_ids,1505.probe = sec_probe,1506.remove = sec_remove,1507.err_handler = &sec_err_handler,1508.sriov_configure = IS_ENABLED(CONFIG_PCI_IOV) ?1509hisi_qm_sriov_configure : NULL,1510.shutdown = hisi_qm_dev_shutdown,1511.driver.pm = &sec_pm_ops,1512};15131514struct pci_driver *hisi_sec_get_pf_driver(void)1515{1516return &sec_pci_driver;1517}1518EXPORT_SYMBOL_GPL(hisi_sec_get_pf_driver);15191520static void sec_register_debugfs(void)1521{1522if (!debugfs_initialized())1523return;15241525sec_debugfs_root = debugfs_create_dir("hisi_sec2", NULL);1526}15271528static void sec_unregister_debugfs(void)1529{1530debugfs_remove_recursive(sec_debugfs_root);1531}15321533static int __init sec_init(void)1534{1535int ret;15361537hisi_qm_init_list(&sec_devices);1538sec_register_debugfs();15391540ret = pci_register_driver(&sec_pci_driver);1541if (ret < 0) {1542sec_unregister_debugfs();1543pr_err("Failed to register pci driver.\n");1544return ret;1545}15461547return 0;1548}15491550static void __exit sec_exit(void)1551{1552pci_unregister_driver(&sec_pci_driver);1553sec_unregister_debugfs();1554}15551556module_init(sec_init);1557module_exit(sec_exit);15581559MODULE_LICENSE("GPL v2");1560MODULE_AUTHOR("Zaibo Xu <[email protected]>");1561MODULE_AUTHOR("Longfang Liu <[email protected]>");1562MODULE_AUTHOR("Kai Ye <[email protected]>");1563MODULE_AUTHOR("Wei Zhang <[email protected]>");1564MODULE_DESCRIPTION("Driver for HiSilicon SEC accelerator");156515661567