// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019 HiSilicon Limited. */
#include <linux/acpi.h>
#include <linux/aer.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/iommu.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/seq_file.h>
#include <linux/topology.h>
#include "sec.h"
#define SEC_VF_NUM 63
#define SEC_QUEUE_NUM_V1 4096
#define SEC_QUEUE_NUM_V2 1024
#define SEC_PF_PCI_DEVICE_ID 0xa255
#define SEC_VF_PCI_DEVICE_ID 0xa256
#define SEC_XTS_MIV_ENABLE_REG 0x301384
#define SEC_XTS_MIV_ENABLE_MSK 0x7FFFFFFF
#define SEC_XTS_MIV_DISABLE_MSK 0xFFFFFFFF
#define SEC_BD_ERR_CHK_EN1 0xfffff7fd
#define SEC_BD_ERR_CHK_EN2 0xffffbfff
#define SEC_SQE_SIZE 128
#define SEC_SQ_SIZE (SEC_SQE_SIZE * QM_Q_DEPTH)
#define SEC_PF_DEF_Q_NUM 64
#define SEC_PF_DEF_Q_BASE 0
#define SEC_CTX_Q_NUM_DEF 24
#define SEC_CTX_Q_NUM_MAX 32
#define SEC_CTRL_CNT_CLR_CE 0x301120
#define SEC_CTRL_CNT_CLR_CE_BIT BIT(0)
#define SEC_ENGINE_PF_CFG_OFF 0x300000
#define SEC_ACC_COMMON_REG_OFF 0x1000
#define SEC_CORE_INT_SOURCE 0x301010
#define SEC_CORE_INT_MASK 0x301000
#define SEC_CORE_INT_STATUS 0x301008
#define SEC_CORE_SRAM_ECC_ERR_INFO 0x301C14
#define SEC_ECC_NUM(err) (((err) >> 16) & 0xFF)
#define SEC_ECC_ADDR(err) ((err) >> 0)
#define SEC_CORE_INT_DISABLE 0x0
#define SEC_CORE_INT_ENABLE 0x1ff
#define SEC_RAS_CE_REG 0x50
#define SEC_RAS_FE_REG 0x54
#define SEC_RAS_NFE_REG 0x58
#define SEC_RAS_CE_ENB_MSK 0x88
#define SEC_RAS_FE_ENB_MSK 0x0
#define SEC_RAS_NFE_ENB_MSK 0x177
#define SEC_RAS_DISABLE 0x0
#define SEC_MEM_START_INIT_REG 0x0100
#define SEC_MEM_INIT_DONE_REG 0x0104
#define SEC_QM_ABNORMAL_INT_MASK 0x100004
#define SEC_CONTROL_REG 0x0200
#define SEC_TRNG_EN_SHIFT 8
#define SEC_CLK_GATE_ENABLE BIT(3)
#define SEC_CLK_GATE_DISABLE (~BIT(3))
#define SEC_AXI_SHUTDOWN_ENABLE BIT(12)
#define SEC_AXI_SHUTDOWN_DISABLE 0xFFFFEFFF
#define SEC_INTERFACE_USER_CTRL0_REG 0x0220
#define SEC_INTERFACE_USER_CTRL1_REG 0x0224
#define SEC_BD_ERR_CHK_EN_REG1 0x0384
#define SEC_BD_ERR_CHK_EN_REG2 0x038c
#define SEC_USER0_SMMU_NORMAL (BIT(23) | BIT(15))
#define SEC_USER1_SMMU_NORMAL (BIT(31) | BIT(23) | BIT(15) | BIT(7))
#define SEC_CORE_INT_STATUS_M_ECC BIT(2)
#define SEC_DELAY_10_US 10
#define SEC_POLL_TIMEOUT_US 1000
#define SEC_VF_CNT_MASK 0xffffffc0
#define SEC_DBGFS_VAL_MAX_LEN 20
#define SEC_ADDR(qm, offset) ((qm)->io_base + (offset) + \
SEC_ENGINE_PF_CFG_OFF + SEC_ACC_COMMON_REG_OFF)
struct sec_hw_error {
u32 int_msk;
const char *msg;
};
static const char sec_name[] = "hisi_sec2";
static struct dentry *sec_debugfs_root;
static LIST_HEAD(sec_list);
static DEFINE_MUTEX(sec_list_lock);
static const struct sec_hw_error sec_hw_errors[] = {
{.int_msk = BIT(0), .msg = "sec_axi_rresp_err_rint"},
{.int_msk = BIT(1), .msg = "sec_axi_bresp_err_rint"},
{.int_msk = BIT(2), .msg = "sec_ecc_2bit_err_rint"},
{.int_msk = BIT(3), .msg = "sec_ecc_1bit_err_rint"},
{.int_msk = BIT(4), .msg = "sec_req_trng_timeout_rint"},
{.int_msk = BIT(5), .msg = "sec_fsm_hbeat_rint"},
{.int_msk = BIT(6), .msg = "sec_channel_req_rng_timeout_rint"},
{.int_msk = BIT(7), .msg = "sec_bd_err_rint"},
{.int_msk = BIT(8), .msg = "sec_chain_buff_err_rint"},
{ /* sentinel */ }
};
struct sec_dev *sec_find_device(int node)
{
#define SEC_NUMA_MAX_DISTANCE 100
int min_distance = SEC_NUMA_MAX_DISTANCE;
int dev_node = 0, free_qp_num = 0;
struct sec_dev *sec, *ret = NULL;
struct hisi_qm *qm;
struct device *dev;
mutex_lock(&sec_list_lock);
list_for_each_entry(sec, &sec_list, list) {
qm = &sec->qm;
dev = &qm->pdev->dev;
#ifdef CONFIG_NUMA
dev_node = dev->numa_node;
if (dev_node < 0)
dev_node = 0;
#endif
if (node_distance(dev_node, node) < min_distance) {
free_qp_num = hisi_qm_get_free_qp_num(qm);
if (free_qp_num >= sec->ctx_q_num) {
ret = sec;
min_distance = node_distance(dev_node, node);
}
}
}
mutex_unlock(&sec_list_lock);
return ret;
}
static const char * const sec_dbg_file_name[] = {
[SEC_CURRENT_QM] = "current_qm",
[SEC_CLEAR_ENABLE] = "clear_enable",
};
static struct debugfs_reg32 sec_dfx_regs[] = {
{"SEC_PF_ABNORMAL_INT_SOURCE ", 0x301010},
{"SEC_SAA_EN ", 0x301270},
{"SEC_BD_LATENCY_MIN ",