driver: update hisilicon hardware crypto engine
keep the hisilicon crypto driver up to 1.3.11, autoprobe the modules when hardware enabled. Signed-off-by: sumiyawang <sumiyawang@tencent.com>
This commit is contained in:
parent
fa3c010699
commit
a0fc351741
|
@ -1,39 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
config CRYPTO_DEV_HISI_SEC
|
||||
tristate "Support for Hisilicon SEC crypto block cipher accelerator"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_LIB_DES
|
||||
select SG_SPLIT
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
Support for Hisilicon SEC Engine in Hip06 and Hip07
|
||||
|
||||
To compile this as a module, choose M here: the module
|
||||
will be called hisi_sec.
|
||||
|
||||
config CRYPTO_DEV_HISI_QM
|
||||
tristate
|
||||
depends on ARM64 && PCI && PCI_MSI
|
||||
select NEED_SG_DMA_LENGTH
|
||||
help
|
||||
HiSilicon accelerator engines use a common queue management
|
||||
interface. Specific engine driver may use this module.
|
||||
|
||||
config CRYPTO_HISI_SGL
|
||||
tristate
|
||||
depends on ARM64
|
||||
help
|
||||
HiSilicon accelerator engines use a common hardware scatterlist
|
||||
interface for data format. Specific engine driver may use this
|
||||
module.
|
||||
|
||||
config CRYPTO_DEV_HISI_ZIP
|
||||
tristate "Support for HiSilicon ZIP accelerator"
|
||||
depends on ARM64 && PCI && PCI_MSI
|
||||
select CRYPTO_DEV_HISI_QM
|
||||
select CRYPTO_HISI_SGL
|
||||
help
|
||||
Support for HiSilicon ZIP Driver
|
||||
source "drivers/crypto/hisilicon/hisilicon/Kconfig"
|
||||
source "drivers/crypto/hisilicon/uacce/Kconfig"
|
||||
|
|
|
@ -1,5 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += sec/
|
||||
obj-$(CONFIG_CRYPTO_DEV_HISI_QM) += qm.o
|
||||
obj-$(CONFIG_CRYPTO_HISI_SGL) += sgl.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_HISI_ZIP) += zip/
|
||||
obj-m += uacce/
|
||||
obj-m += hisilicon/
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
config CRYPTO_DEV_HISI_QM
|
||||
tristate
|
||||
depends on ARM64 && PCI
|
||||
|
||||
config CRYPTO_QM_UACCE
|
||||
bool "enable UACCE support for all acceleartor with Hisi QM"
|
||||
depends on CRYPTO_DEV_HISI_QM
|
||||
select UACCE
|
||||
help
|
||||
Support UACCE interface in Hisi QM.
|
||||
|
||||
config CRYPTO_DEV_HISI_ZIP
|
||||
tristate "Support for HISI ZIP Driver"
|
||||
depends on ARM64 && ACPI
|
||||
select CRYPTO_DEV_HISI_QM
|
||||
help
|
||||
Support for HiSilicon HIP08 ZIP Driver.
|
||||
|
||||
config CRYPTO_DEV_HISI_HPRE
|
||||
tristate "Support for HISI HPRE accelerator"
|
||||
depends on PCI && PCI_MSI && ACPI
|
||||
depends on ARM64
|
||||
select CRYPTO_DEV_HISI_QM
|
||||
select CRYPTO_DH
|
||||
select CRYPTO_RSA
|
||||
help
|
||||
Support for HiSilicon HPRE(High Performance RSA Engine)
|
||||
accelerator, which can accelerate RSA and DH algorithms.
|
||||
|
||||
config CRYPTO_DEV_HISI_SEC2
|
||||
tristate "Support for HISI SEC Driver"
|
||||
depends on ARM64 && ACPI
|
||||
select CRYPTO_DEV_HISI_QM
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_ALGAPI
|
||||
help
|
||||
Support for HiSilicon HIP09 SEC Driver.
|
||||
|
||||
config CRYPTO_DEV_HISI_RDE
|
||||
tristate "Support for HISI RDE Driver"
|
||||
depends on ARM64 && ACPI
|
||||
select CRYPTO_DEV_HISI_QM
|
||||
help
|
||||
Support for HiSilicon HIP09 RDE Driver.
|
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_CRYPTO_DEV_HISI_QM) += hisi_qm.o
|
||||
hisi_qm-objs = qm.o sgl.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_HISI_ZIP) += zip/
|
||||
obj-$(CONFIG_CRYPTO_DEV_HISI_HPRE) += hpre/
|
||||
obj-$(CONFIG_CRYPTO_DEV_HISI_SEC2) += sec2/
|
||||
obj-$(CONFIG_CRYPTO_DEV_HISI_RDE) += rde/
|
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_CRYPTO_DEV_HISI_HPRE) += hisi_hpre.o
|
||||
hisi_hpre-objs = hpre_main.o hpre_crypto.o
|
|
@ -0,0 +1,96 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/* Copyright (c) 2019 HiSilicon Limited. */
|
||||
#ifndef __HISI_HPRE_H
|
||||
#define __HISI_HPRE_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include "../qm.h"
|
||||
|
||||
#define HPRE_SQE_SIZE sizeof(struct hpre_sqe)
|
||||
#define HPRE_PF_DEF_Q_NUM 256
|
||||
#define HPRE_PF_DEF_Q_BASE 0
|
||||
|
||||
enum {
|
||||
HPRE_CLUSTER0,
|
||||
HPRE_CLUSTER1,
|
||||
HPRE_CLUSTER2,
|
||||
HPRE_CLUSTER3,
|
||||
HPRE_CLUSTERS_NUM,
|
||||
};
|
||||
|
||||
enum hpre_ctrl_dbgfs_file {
|
||||
HPRE_CURRENT_QM,
|
||||
HPRE_CLEAR_ENABLE,
|
||||
HPRE_CLUSTER_CTRL,
|
||||
HPRE_DEBUG_FILE_NUM,
|
||||
};
|
||||
|
||||
enum hpre_dfx_dbgfs_file {
|
||||
HPRE_SEND_CNT,
|
||||
HPRE_RECV_CNT,
|
||||
HPRE_SEND_FAIL_CNT,
|
||||
HPRE_SEND_BUSY_CNT,
|
||||
HPRE_OVER_THRHLD_CNT,
|
||||
HPRE_OVERTIME_THRHLD,
|
||||
HPRE_INVALID_REQ_CNT,
|
||||
HPRE_DFX_FILE_NUM
|
||||
};
|
||||
|
||||
#define HPRE_DEBUGFS_FILE_NUM (HPRE_DEBUG_FILE_NUM + HPRE_CLUSTERS_NUM - 1)
|
||||
|
||||
struct hpre_debugfs_file {
|
||||
int index;
|
||||
enum hpre_ctrl_dbgfs_file type;
|
||||
spinlock_t lock;
|
||||
struct hpre_debug *debug;
|
||||
};
|
||||
|
||||
struct hpre_dfx {
|
||||
atomic64_t value;
|
||||
enum hpre_dfx_dbgfs_file type;
|
||||
};
|
||||
|
||||
/*
|
||||
* One HPRE controller has one PF and multiple VFs, some global configurations
|
||||
* which PF has need this structure.
|
||||
* Just relevant for PF.
|
||||
*/
|
||||
struct hpre_debug {
|
||||
struct hpre_dfx dfx[HPRE_DFX_FILE_NUM];
|
||||
struct hpre_debugfs_file files[HPRE_DEBUGFS_FILE_NUM];
|
||||
};
|
||||
|
||||
struct hpre {
|
||||
struct hisi_qm qm;
|
||||
struct hpre_debug debug;
|
||||
};
|
||||
|
||||
enum hpre_alg_type {
|
||||
HPRE_ALG_NC_NCRT = 0x0,
|
||||
HPRE_ALG_NC_CRT = 0x1,
|
||||
HPRE_ALG_KG_STD = 0x2,
|
||||
HPRE_ALG_KG_CRT = 0x3,
|
||||
HPRE_ALG_DH_G2 = 0x4,
|
||||
HPRE_ALG_DH = 0x5,
|
||||
};
|
||||
|
||||
struct hpre_sqe {
|
||||
__le32 dw0;
|
||||
__u8 task_len1;
|
||||
__u8 task_len2;
|
||||
__u8 mrttest_num;
|
||||
__u8 resv1;
|
||||
__le64 key;
|
||||
__le64 in;
|
||||
__le64 out;
|
||||
__le16 tag;
|
||||
__le16 resv2;
|
||||
#define _HPRE_SQE_ALIGN_EXT 7
|
||||
__le32 rsvd1[_HPRE_SQE_ALIGN_EXT];
|
||||
};
|
||||
|
||||
struct hisi_qp *hpre_create_qp(void);
|
||||
int hpre_algs_register(void);
|
||||
void hpre_algs_unregister(void);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,564 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/* Copyright (c) 2018-2019 HiSilicon Limited. */
|
||||
#ifndef HISI_ACC_QM_H
|
||||
#define HISI_ACC_QM_H
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/dmapool.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include "../include_linux/acc_compat.h"
|
||||
|
||||
#ifdef CONFIG_CRYPTO_QM_UACCE
|
||||
#include "../include_linux/uacce.h"
|
||||
#endif
|
||||
|
||||
#include "qm_usr_if.h"
|
||||
|
||||
#define QNUM_V1 4096
|
||||
#define QNUM_V2 1024
|
||||
#define QM_MAX_VFS_NUM_V2 63
|
||||
/* qm user domain */
|
||||
#define QM_ARUSER_M_CFG_1 0x100088
|
||||
#define AXUSER_SNOOP_ENABLE BIT(30)
|
||||
#define AXUSER_CMD_TYPE GENMASK(14, 12)
|
||||
#define AXUSER_CMD_SMMU_NORMAL 1
|
||||
#define AXUSER_NS BIT(6)
|
||||
#define AXUSER_NO BIT(5)
|
||||
#define AXUSER_FP BIT(4)
|
||||
#define AXUSER_SSV BIT(0)
|
||||
#define AXUSER_BASE (AXUSER_SNOOP_ENABLE | \
|
||||
FIELD_PREP(AXUSER_CMD_TYPE, \
|
||||
AXUSER_CMD_SMMU_NORMAL) | \
|
||||
AXUSER_NS | AXUSER_NO | AXUSER_FP)
|
||||
#define QM_ARUSER_M_CFG_ENABLE 0x100090
|
||||
#define ARUSER_M_CFG_ENABLE 0xfffffffe
|
||||
#define QM_AWUSER_M_CFG_1 0x100098
|
||||
#define QM_AWUSER_M_CFG_ENABLE 0x1000a0
|
||||
#define AWUSER_M_CFG_ENABLE 0xfffffffe
|
||||
#define QM_WUSER_M_CFG_ENABLE 0x1000a8
|
||||
#define WUSER_M_CFG_ENABLE 0xffffffff
|
||||
|
||||
/* qm cache */
|
||||
#define QM_CACHE_CTL 0x100050
|
||||
#define SQC_CACHE_ENABLE BIT(0)
|
||||
#define CQC_CACHE_ENABLE BIT(1)
|
||||
#define SQC_CACHE_WB_ENABLE BIT(4)
|
||||
#define SQC_CACHE_WB_THRD GENMASK(10, 5)
|
||||
#define CQC_CACHE_WB_ENABLE BIT(11)
|
||||
#define CQC_CACHE_WB_THRD GENMASK(17, 12)
|
||||
#define QM_AXI_M_CFG 0x1000ac
|
||||
#define AXI_M_CFG 0xffff
|
||||
#define QM_AXI_M_CFG_ENABLE 0x1000b0
|
||||
#define AM_CFG_SINGLE_PORT_MAX_TRANS 0x300014
|
||||
#define AXI_M_CFG_ENABLE 0xffffffff
|
||||
#define QM_PEH_AXUSER_CFG 0x1000cc
|
||||
#define QM_PEH_AXUSER_CFG_ENABLE 0x1000d0
|
||||
#define PEH_AXUSER_CFG 0x400801
|
||||
#define PEH_AXUSER_CFG_ENABLE 0xffffffff
|
||||
|
||||
#define QM_DFX_MB_CNT_VF 0x104010
|
||||
#define QM_DFX_DB_CNT_VF 0x104020
|
||||
|
||||
#define QM_DFX_SQE_CNT_VF_SQN 0x104030
|
||||
#define QM_DFX_CQE_CNT_VF_CQN 0x104040
|
||||
|
||||
#define QM_AXI_RRESP BIT(0)
|
||||
#define QM_AXI_BRESP BIT(1)
|
||||
#define QM_ECC_MBIT BIT(2)
|
||||
#define QM_ECC_1BIT BIT(3)
|
||||
#define QM_ACC_GET_TASK_TIMEOUT BIT(4)
|
||||
#define QM_ACC_DO_TASK_TIMEOUT BIT(5)
|
||||
#define QM_ACC_WB_NOT_READY_TIMEOUT BIT(6)
|
||||
#define QM_SQ_CQ_VF_INVALID BIT(7)
|
||||
#define QM_CQ_VF_INVALID BIT(8)
|
||||
#define QM_SQ_VF_INVALID BIT(9)
|
||||
#define QM_DB_TIMEOUT BIT(10)
|
||||
#define QM_OF_FIFO_OF BIT(11)
|
||||
#define QM_DB_RANDOM_INVALID BIT(12)
|
||||
|
||||
#define QM_BASE_NFE (QM_AXI_RRESP | QM_AXI_BRESP | QM_ECC_MBIT | \
|
||||
QM_ACC_GET_TASK_TIMEOUT | QM_DB_TIMEOUT | \
|
||||
QM_OF_FIFO_OF)
|
||||
#define QM_BASE_CE QM_ECC_1BIT
|
||||
|
||||
#define HISI_ACC_SGL_SGE_NR_MAX 255
|
||||
#define QM_DFX_QN_SHIFT 16
|
||||
|
||||
#define CURRENT_FUN_MASK GENMASK(5, 0)
|
||||
#define CURRENT_Q_MASK GENMASK(31, 16)
|
||||
|
||||
#define SQE_ADDR_MASK GENMASK(7, 0)
|
||||
|
||||
#define PCI_BAR_2 2
|
||||
|
||||
enum qm_stop_reason {
|
||||
QM_NORMAL,
|
||||
QM_SOFT_RESET,
|
||||
QM_FLR,
|
||||
};
|
||||
enum qm_state {
|
||||
QM_INIT = 0,
|
||||
QM_START,
|
||||
QM_CLOSE,
|
||||
QM_STOP,
|
||||
};
|
||||
|
||||
enum qp_state {
|
||||
QP_INIT = 1,
|
||||
QP_START,
|
||||
QP_STOP,
|
||||
QP_CLOSE,
|
||||
};
|
||||
|
||||
enum qm_hw_ver {
|
||||
QM_HW_UNKNOWN = -1,
|
||||
QM_HW_V1 = 0x20,
|
||||
QM_HW_V2 = 0x21,
|
||||
};
|
||||
|
||||
enum qm_fun_type {
|
||||
QM_HW_PF,
|
||||
QM_HW_VF,
|
||||
};
|
||||
|
||||
enum qm_debug_file {
|
||||
CURRENT_Q,
|
||||
CLEAR_ENABLE,
|
||||
QM_STATE,
|
||||
DEBUG_FILE_NUM,
|
||||
};
|
||||
|
||||
struct qm_dfx {
|
||||
atomic64_t qm_err_irq_cnt;
|
||||
atomic64_t aeq_irq_cnt;
|
||||
atomic64_t abnormal_irq_cnt;
|
||||
atomic64_t qp_err_cnt;
|
||||
atomic64_t mb_err_cnt;
|
||||
};
|
||||
|
||||
struct debugfs_file {
|
||||
enum qm_debug_file index;
|
||||
struct mutex lock;
|
||||
struct qm_debug *debug;
|
||||
};
|
||||
|
||||
struct qm_debug {
|
||||
u32 sqe_mask_len;
|
||||
u32 sqe_mask_offset;
|
||||
u32 curr_qm_qp_num;
|
||||
struct qm_dfx dfx;
|
||||
struct dentry *debug_root;
|
||||
struct dentry *qm_d;
|
||||
struct debugfs_file files[DEBUG_FILE_NUM];
|
||||
};
|
||||
|
||||
struct qm_cqe {
|
||||
__le32 rsvd0;
|
||||
__le16 cmd_id;
|
||||
__le16 rsvd1;
|
||||
__le16 sq_head;
|
||||
__le16 sq_num;
|
||||
__le16 rsvd2;
|
||||
__le16 w7;
|
||||
};
|
||||
|
||||
struct qm_eqe {
|
||||
__le32 dw0;
|
||||
};
|
||||
|
||||
struct qm_aeqe {
|
||||
__le32 dw0;
|
||||
};
|
||||
|
||||
struct qm_sqc {
|
||||
__le16 head;
|
||||
__le16 tail;
|
||||
__le32 base_l;
|
||||
__le32 base_h;
|
||||
__le32 dw3;
|
||||
__le16 w8;
|
||||
__le16 rsvd0;
|
||||
__le16 pasid;
|
||||
__le16 w11;
|
||||
__le16 cq_num;
|
||||
__le16 w13;
|
||||
__le32 rsvd1;
|
||||
};
|
||||
|
||||
struct qm_cqc {
|
||||
__le16 head;
|
||||
__le16 tail;
|
||||
__le32 base_l;
|
||||
__le32 base_h;
|
||||
__le32 dw3;
|
||||
__le16 w8;
|
||||
__le16 rsvd0;
|
||||
__le16 pasid;
|
||||
__le16 w11;
|
||||
__le32 dw6;
|
||||
__le32 rsvd1;
|
||||
};
|
||||
|
||||
struct qm_eqc {
|
||||
__le16 head;
|
||||
__le16 tail;
|
||||
__le32 base_l;
|
||||
__le32 base_h;
|
||||
__le32 dw3;
|
||||
__le32 rsvd[2];
|
||||
__le32 dw6;
|
||||
};
|
||||
|
||||
struct qm_aeqc {
|
||||
__le16 head;
|
||||
__le16 tail;
|
||||
__le32 base_l;
|
||||
__le32 base_h;
|
||||
__le32 dw3;
|
||||
__le32 rsvd[2];
|
||||
__le32 dw6;
|
||||
};
|
||||
|
||||
struct qm_mailbox {
|
||||
__le16 w0;
|
||||
__le16 queue_num;
|
||||
__le32 base_l;
|
||||
__le32 base_h;
|
||||
__le32 rsvd;
|
||||
};
|
||||
|
||||
struct qm_doorbell {
|
||||
__le16 queue_num;
|
||||
__le16 cmd;
|
||||
__le16 index;
|
||||
__le16 priority;
|
||||
};
|
||||
|
||||
struct qm_dma {
|
||||
void *va;
|
||||
dma_addr_t dma;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct hisi_qm_status {
|
||||
u32 eq_head;
|
||||
bool eqc_phase;
|
||||
u32 aeq_head;
|
||||
bool aeqc_phase;
|
||||
atomic_t flags;
|
||||
int stop_reason;
|
||||
};
|
||||
|
||||
struct hisi_qm_hw_error {
|
||||
u32 int_msk;
|
||||
const char *msg;
|
||||
};
|
||||
|
||||
struct hisi_qm;
|
||||
|
||||
struct hisi_qm_err_info {
|
||||
char *acpi_rst;
|
||||
u32 msi_wr_port;
|
||||
u32 ecc_2bits_mask;
|
||||
u32 is_qm_ecc_mbit;
|
||||
u32 is_dev_ecc_mbit;
|
||||
u32 ce;
|
||||
u32 nfe;
|
||||
u32 fe;
|
||||
u32 msi;
|
||||
};
|
||||
|
||||
struct hisi_qm_err_ini {
|
||||
u32 (*get_dev_hw_err_status)(struct hisi_qm *qm);
|
||||
void (*clear_dev_hw_err_status)(struct hisi_qm *qm, u32 err_sts);
|
||||
void (*hw_err_enable)(struct hisi_qm *qm);
|
||||
void (*hw_err_disable)(struct hisi_qm *qm);
|
||||
int (*set_usr_domain_cache)(struct hisi_qm *qm);
|
||||
void (*log_dev_hw_err)(struct hisi_qm *qm, u32 err_sts);
|
||||
void (*open_axi_master_ooo)(struct hisi_qm *qm);
|
||||
void (*close_axi_master_ooo)(struct hisi_qm *qm);
|
||||
struct hisi_qm_err_info err_info;
|
||||
};
|
||||
|
||||
struct hisi_qm_list {
|
||||
struct mutex lock;
|
||||
struct list_head list;
|
||||
bool (*check)(struct hisi_qm *qm);
|
||||
};
|
||||
|
||||
struct hisi_qm {
|
||||
enum qm_hw_ver ver;
|
||||
enum qm_fun_type fun_type;
|
||||
const char *dev_name;
|
||||
struct pci_dev *pdev;
|
||||
void __iomem *io_base;
|
||||
u32 sqe_size;
|
||||
u32 qp_base;
|
||||
u32 qp_num;
|
||||
u32 ctrl_q_num;
|
||||
u32 vfs_num;
|
||||
u32 free_qp_num;
|
||||
struct list_head list;
|
||||
struct hisi_qm_list *qm_list;
|
||||
struct qm_dma qdma;
|
||||
struct qm_sqc *sqc;
|
||||
struct qm_cqc *cqc;
|
||||
struct qm_eqe *eqe;
|
||||
struct qm_aeqe *aeqe;
|
||||
dma_addr_t sqc_dma;
|
||||
dma_addr_t cqc_dma;
|
||||
dma_addr_t eqe_dma;
|
||||
dma_addr_t aeqe_dma;
|
||||
|
||||
struct hisi_qm_status status;
|
||||
struct hisi_qm_err_ini err_ini;
|
||||
struct rw_semaphore qps_lock;
|
||||
struct idr qp_idr;
|
||||
struct hisi_qp *qp_array;
|
||||
|
||||
struct mutex mailbox_lock;
|
||||
|
||||
const struct hisi_qm_hw_ops *ops;
|
||||
|
||||
struct qm_debug debug;
|
||||
|
||||
u32 error_mask;
|
||||
u32 msi_mask;
|
||||
unsigned long hw_status;
|
||||
bool use_uacce; /* register to uacce */
|
||||
bool use_sva;
|
||||
bool is_frozen;
|
||||
|
||||
#ifdef CONFIG_CRYPTO_QM_UACCE
|
||||
resource_size_t phys_base;
|
||||
resource_size_t size;
|
||||
struct uacce uacce;
|
||||
const char *algs;
|
||||
int uacce_mode;
|
||||
#endif
|
||||
struct workqueue_struct *wq;
|
||||
struct work_struct work;
|
||||
/* design for module not support aer, such as rde */
|
||||
int (*abnormal_fix)(struct hisi_qm *qm);
|
||||
};
|
||||
|
||||
struct hisi_qp_status {
|
||||
atomic_t used;
|
||||
u16 sq_tail;
|
||||
u16 sq_head;
|
||||
u16 cq_head;
|
||||
bool cqc_phase;
|
||||
atomic_t flags;
|
||||
};
|
||||
|
||||
struct hisi_qp_ops {
|
||||
int (*fill_sqe)(void *sqe, void *q_parm, void *d_parm);
|
||||
};
|
||||
|
||||
struct hisi_qp {
|
||||
u32 qp_id;
|
||||
u8 alg_type;
|
||||
u8 req_type;
|
||||
u8 c_flag;
|
||||
|
||||
struct qm_dma qdma;
|
||||
void *sqe;
|
||||
struct qm_cqe *cqe;
|
||||
dma_addr_t sqe_dma;
|
||||
dma_addr_t cqe_dma;
|
||||
|
||||
struct hisi_qp_status qp_status;
|
||||
struct completion completion;
|
||||
struct hisi_qp_ops *hw_ops;
|
||||
void *qp_ctx;
|
||||
void (*req_cb)(struct hisi_qp *qp, void *data);
|
||||
void (*event_cb)(struct hisi_qp *qp);
|
||||
|
||||
struct hisi_qm *qm;
|
||||
bool is_resetting;
|
||||
bool is_in_kernel;
|
||||
|
||||
#ifdef CONFIG_CRYPTO_QM_UACCE
|
||||
u16 pasid;
|
||||
struct uacce_queue *uacce_q;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline int q_num_set(const char *val, const struct kernel_param *kp,
|
||||
unsigned int device)
|
||||
{
|
||||
struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI,
|
||||
device, NULL);
|
||||
u32 n, q_num;
|
||||
u8 rev_id;
|
||||
int ret;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pdev) {
|
||||
q_num = min_t(u32, QNUM_V1, QNUM_V2);
|
||||
pr_info("No device found currently, suppose queue number is %d\n",
|
||||
q_num);
|
||||
} else {
|
||||
rev_id = pdev->revision;
|
||||
switch (rev_id) {
|
||||
case QM_HW_V1:
|
||||
q_num = QNUM_V1;
|
||||
break;
|
||||
case QM_HW_V2:
|
||||
q_num = QNUM_V2;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = kstrtou32(val, 10, &n);
|
||||
if (ret || !n || n > q_num)
|
||||
return -EINVAL;
|
||||
|
||||
return param_set_int(val, kp);
|
||||
}
|
||||
|
||||
static inline int vf_num_set(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
u32 n;
|
||||
int ret;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
ret = kstrtou32(val, 10, &n);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (n > QM_MAX_VFS_NUM_V2)
|
||||
return -ERANGE;
|
||||
|
||||
return param_set_int(val, kp);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CRYPTO_QM_UACCE
|
||||
static inline int mode_set(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
u32 n;
|
||||
int ret;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
ret = kstrtou32(val, 10, &n);
|
||||
if (ret != 0 || (n != UACCE_MODE_NOIOMMU &&
|
||||
n != UACCE_MODE_NOUACCE))
|
||||
return -EINVAL;
|
||||
|
||||
return param_set_int(val, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void hisi_qm_add_to_list(struct hisi_qm *qm,
|
||||
struct hisi_qm_list *qm_list)
|
||||
{
|
||||
mutex_lock(&qm_list->lock);
|
||||
list_add_tail(&qm->list, &qm_list->list);
|
||||
mutex_unlock(&qm_list->lock);
|
||||
}
|
||||
|
||||
static inline void hisi_qm_del_from_list(struct hisi_qm *qm,
|
||||
struct hisi_qm_list *qm_list)
|
||||
{
|
||||
mutex_lock(&qm_list->lock);
|
||||
list_del(&qm->list);
|
||||
mutex_unlock(&qm_list->lock);
|
||||
}
|
||||
|
||||
static inline int hisi_qm_pre_init(struct hisi_qm *qm,
|
||||
u32 pf_q_num, u32 def_q_num)
|
||||
{
|
||||
struct pci_dev *pdev = qm->pdev;
|
||||
|
||||
switch (pdev->revision) {
|
||||
case QM_HW_V1:
|
||||
case QM_HW_V2:
|
||||
qm->ver = pdev->revision;
|
||||
break;
|
||||
default:
|
||||
pci_err(pdev, "hardware version err!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, qm);
|
||||
|
||||
#ifdef CONFIG_CRYPTO_QM_UACCE
|
||||
switch (qm->uacce_mode) {
|
||||
case UACCE_MODE_NOUACCE:
|
||||
qm->use_uacce = false;
|
||||
break;
|
||||
case UACCE_MODE_NOIOMMU:
|
||||
qm->use_uacce = true;
|
||||
break;
|
||||
default:
|
||||
pci_err(pdev, "uacce mode error!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
#else
|
||||
qm->use_uacce = false;
|
||||
#endif
|
||||
if (qm->fun_type == QM_HW_PF) {
|
||||
qm->qp_base = def_q_num;
|
||||
qm->qp_num = pf_q_num;
|
||||
qm->debug.curr_qm_qp_num = pf_q_num;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hisi_qm_free_qps(struct hisi_qp **qps, int qp_num);
|
||||
int hisi_qm_alloc_qps_node(int node, struct hisi_qm_list *qm_list,
|
||||
struct hisi_qp **qps, int qp_num, u8 alg_type);
|
||||
int hisi_qm_init(struct hisi_qm *qm);
|
||||
void hisi_qm_uninit(struct hisi_qm *qm);
|
||||
void hisi_qm_dev_shutdown(struct pci_dev *pdev);
|
||||
void hisi_qm_remove_wait_delay(struct hisi_qm *qm,
|
||||
struct hisi_qm_list *qm_list);
|
||||
int hisi_qm_start(struct hisi_qm *qm);
|
||||
int hisi_qm_stop(struct hisi_qm *qm, enum qm_stop_reason r);
|
||||
struct hisi_qp *hisi_qm_create_qp(struct hisi_qm *qm, u8 alg_type);
|
||||
int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long arg);
|
||||
int hisi_qm_stop_qp(struct hisi_qp *qp);
|
||||
void hisi_qm_release_qp(struct hisi_qp *qp);
|
||||
int hisi_qp_send(struct hisi_qp *qp, const void *msg);
|
||||
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);
|
||||
void hisi_qm_debug_regs_clear(struct hisi_qm *qm);
|
||||
int hisi_qm_debug_init(struct hisi_qm *qm);
|
||||
int hisi_qm_restart(struct hisi_qm *qm);
|
||||
int hisi_qm_sriov_enable(struct pci_dev *pdev, int max_vfs);
|
||||
int hisi_qm_sriov_disable(struct pci_dev *pdev, struct hisi_qm_list *qm_list);
|
||||
void hisi_qm_dev_err_init(struct hisi_qm *qm);
|
||||
void hisi_qm_dev_err_uninit(struct hisi_qm *qm);
|
||||
pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
|
||||
pci_channel_state_t state);
|
||||
pci_ers_result_t hisi_qm_dev_slot_reset(struct pci_dev *pdev);
|
||||
void hisi_qm_reset_prepare(struct pci_dev *pdev);
|
||||
void hisi_qm_reset_done(struct pci_dev *pdev);
|
||||
pci_ers_result_t hisi_qm_process_dev_error(struct pci_dev *pdev);
|
||||
int hisi_qm_controller_reset(struct hisi_qm *qm);
|
||||
|
||||
struct hisi_acc_sgl_pool;
|
||||
struct hisi_acc_hw_sgl *hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,
|
||||
struct scatterlist *sgl, struct hisi_acc_sgl_pool *pool,
|
||||
u32 index, dma_addr_t *hw_sgl_dma);
|
||||
void hisi_acc_sg_buf_unmap(struct device *dev, struct scatterlist *sgl,
|
||||
struct hisi_acc_hw_sgl *hw_sgl);
|
||||
struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
|
||||
u32 count, u32 sge_nr);
|
||||
void hisi_acc_free_sgl_pool(struct device *dev,
|
||||
struct hisi_acc_sgl_pool *pool);
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/* Copyright (c) 2018-2019 HiSilicon Limited. */
|
||||
#ifndef HISI_QM_USR_IF_H
|
||||
#define HISI_QM_USR_IF_H
|
||||
|
||||
#define QM_CQE_SIZE 16
|
||||
|
||||
/* default queue depth for sq/cq/eq */
|
||||
#define QM_Q_DEPTH 1024
|
||||
#define QM_EQ_DEPTH (1024 * 2)
|
||||
|
||||
/* page number for queue file region */
|
||||
#define QM_DOORBELL_PAGE_NR 1
|
||||
|
||||
|
||||
#define QM_DOORBELL_OFFSET 0x340
|
||||
#define QM_V2_DOORBELL_OFFSET 0x1000
|
||||
|
||||
struct cqe {
|
||||
__le32 rsvd0;
|
||||
__le16 cmd_id;
|
||||
__le16 rsvd1;
|
||||
__le16 sq_head;
|
||||
__le16 sq_num;
|
||||
__le16 rsvd2;
|
||||
__le16 w7;
|
||||
};
|
||||
|
||||
struct hisi_qp_ctx {
|
||||
__u16 id;
|
||||
__u16 qc_type;
|
||||
};
|
||||
|
||||
#define HISI_QM_API_VER_BASE "hisi_qm_v1"
|
||||
#define HISI_QM_API_VER2_BASE "hisi_qm_v2"
|
||||
|
||||
#define UACCE_CMD_QM_SET_QP_CTX _IOWR('H', 10, struct hisi_qp_ctx)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_CRYPTO_DEV_HISI_RDE) += hisi_rde.o
|
||||
hisi_rde-objs = rde_main.o rde_api.o rde_data.o
|
|
@ -0,0 +1,320 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 HiSilicon Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RDE_H__
|
||||
#define __RDE_H__
|
||||
|
||||
#include <linux/list.h>
|
||||
#include "../qm.h"
|
||||
#include "rde_usr_if.h"
|
||||
#include "rde_api.h"
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "hisi_rde: " fmt
|
||||
|
||||
struct hisi_rde_ctrl;
|
||||
|
||||
struct hisi_rde {
|
||||
struct hisi_qm qm;
|
||||
struct hisi_rde_ctrl *ctrl;
|
||||
struct work_struct reset_work;
|
||||
u32 smmu_state;
|
||||
};
|
||||
|
||||
#define RDE_CM_LOAD_ENABLE 1
|
||||
#define RDE_MPCC_MAX_SRC_NUM 17
|
||||
#define RDE_FLEXEC_MAX_SRC_NUM 32
|
||||
#define RDE_MPCC_CMSIZE 2176
|
||||
#define RDE_FLEXEC_CMSIZE 1024
|
||||
#define RDE_MEM_SAVE_SHIFT 2
|
||||
#define RDE_BUF_TYPE_SHIFT 3
|
||||
#define SGL_DATA_OFFSET_SHIFT 8
|
||||
#define DIF_GEN_PAD_CTRL_SHIFT 32
|
||||
#define DIF_GEN_REF_CTRL_SHIFT 35
|
||||
#define DIF_GEN_APP_CTRL_SHIFT 38
|
||||
#define DIF_GEN_VER_CTRL_SHIFT 41
|
||||
#define DIF_GEN_GRD_CTRL_SHIFT 44
|
||||
#define DIF_APP_TAG_SHIFT 48
|
||||
#define DIF_VERSION_SHIFT 56
|
||||
#define RDE_TASK_DONE_STATUS 0x80
|
||||
#define RDE_CRC16_IV 0x310004
|
||||
#define RDE_PRP_PAGE_SIZE 0x31022c
|
||||
#define RDE_SGL_SGE_OFFSET 0x310228
|
||||
#define RDE_INVLD_REQ_ID (-1)
|
||||
#define RDE_ALG_TYPE_MSK 0x60
|
||||
#define RDE_BUF_TYPE_MSK 0x18
|
||||
#define RDE_MAX_SRC_PLATE_NUM 32
|
||||
#define RDE_MAX_DST_PLATE_NUM 17
|
||||
#define SRC_ADDR_TABLE_NUM 48
|
||||
#define DST_ADDR_TABLE_NUM 26
|
||||
#define SRC_DIF_TABLE_NUM 20
|
||||
#define DST_DIF_TABLE_NUM 17
|
||||
#define RDE_STATUS_MSK 0x7f
|
||||
#define RDE_DONE_MSK 0x1
|
||||
#define RDE_DONE_SHIFT 7
|
||||
#define RDE_PER_SRC_COEF_SIZE 32
|
||||
#define RDE_PER_SRC_COEF_TIMES 4
|
||||
#define RDE_TASK_TMOUT_MS 3000
|
||||
|
||||
|
||||
#define RDE_GN_WITH_MODE(column, mode, parity) \
|
||||
((u8)column + ((ACC_OPT_UPD ^ mode) ? 0 : (0x80 & (parity << 7))))
|
||||
#define RDE_GN_CNT(i) (((i + 1) % 2 == 0) ? ((i + 1) >> 1) : ((i + 2) >> 1))
|
||||
#define RDE_GN_FLAG(i) (((i + 1) % 2 == 0) ? 2 : 1)
|
||||
#define RDE_GN_SHIFT(i) (32 * (i == 1 ? 1 : 0))
|
||||
#define RDE_CHK_CTRL_CNT(i) ((i / 8) * 5)
|
||||
#define RDE_LBA_CNT(i) ((i / 8 + 1) + \
|
||||
((i % 2 == 0) ? (i >> 1) : ((i - 1) >> 1)))
|
||||
#define RDE_CHK_CTRL_VALUE(grd, ref, i) \
|
||||
((u64)(grd << 4 | ref) << (8 * (i % 8)))
|
||||
#define RDE_LBA_SHIFT(i) (32 * ((i % 2) ^ 1))
|
||||
|
||||
struct hisi_rde_hw_error {
|
||||
u8 status;
|
||||
u32 int_msk;
|
||||
const char *msg;
|
||||
};
|
||||
|
||||
/* src data addr table, should be 64byte aligned */
|
||||
struct rde_src_tbl {
|
||||
u64 content[SRC_ADDR_TABLE_NUM];
|
||||
};
|
||||
|
||||
/* src data dif table, should be 64byte aligned */
|
||||
struct rde_src_tag_tbl {
|
||||
u64 content[SRC_DIF_TABLE_NUM];
|
||||
};
|
||||
|
||||
/* dst data addr table, should be 64byte aligned */
|
||||
struct rde_dst_tbl {
|
||||
u64 content[DST_ADDR_TABLE_NUM];
|
||||
};
|
||||
|
||||
/* dst data dif table, should be 64byte aligned */
|
||||
struct rde_dst_tag_tbl {
|
||||
u64 content[DST_DIF_TABLE_NUM];
|
||||
};
|
||||
|
||||
/* inner msg structure, keep addr info */
|
||||
struct hisi_rde_msg {
|
||||
struct rde_src_tbl *src_addr;
|
||||
dma_addr_t src_dma_addr;
|
||||
struct rde_dst_tbl *dst_addr;
|
||||
dma_addr_t dst_dma_addr;
|
||||
struct rde_src_tag_tbl *src_tag_addr;
|
||||
dma_addr_t src_tag_dma_addr;
|
||||
struct rde_dst_tag_tbl *dst_tag_addr;
|
||||
dma_addr_t dst_tag_dma_addr;
|
||||
u64 src_record[RDE_MAX_SRC_PLATE_NUM];
|
||||
u64 dst_record[RDE_MAX_DST_PLATE_NUM];
|
||||
struct hisi_rde_sqe sqe;
|
||||
struct raid_ec_ctrl *udata;
|
||||
struct completion completion;
|
||||
u32 req_id;
|
||||
int result;
|
||||
};
|
||||
|
||||
/* rde ctx structure, acc_init api can alloc and init this structure */
|
||||
struct hisi_rde_ctx {
|
||||
struct device *dev;
|
||||
struct hisi_qp *qp;
|
||||
struct hisi_rde_msg *req_list;
|
||||
unsigned long *req_bitmap;
|
||||
spinlock_t req_lock;
|
||||
u32 smmu_state;
|
||||
u32 session_num;
|
||||
u8 addr_type;
|
||||
};
|
||||
|
||||
/* inner structure, to distinguish diffenernt alg and operation */
|
||||
struct rde_type {
|
||||
u8 alg_mode;
|
||||
u8 mem_mode;
|
||||
u8 buf_mode;
|
||||
u8 alg_type;
|
||||
};
|
||||
|
||||
/* RDE hardware error status */
|
||||
enum {
|
||||
RDE_STATUS_NULL = 0,
|
||||
RDE_BD_ADDR_NO_ALIGN = 0x2,
|
||||
RDE_BD_RD_BUS_ERR = 0x3,
|
||||
RDE_IO_ABORT = 0x4,
|
||||
RDE_BD_ERR = 0x5,
|
||||
RDE_ECC_ERR = 0x6,
|
||||
RDE_SGL_ADDR_ERR = 0x7,
|
||||
RDE_SGL_PARA_ERR = 0x8,
|
||||
RDE_DATA_RD_BUS_ERR = 0x1c,
|
||||
RDE_DATA_WR_BUS_ERR = 0x1d,
|
||||
RDE_CRC_CHK_ERR = 0x1e,
|
||||
RDE_REF_CHK_ERR = 0x1f,
|
||||
RDE_DISK0_VERIFY = 0x20,
|
||||
RDE_DISK1_VERIFY = 0x21,
|
||||
RDE_DISK2_VERIFY = 0x22,
|
||||
RDE_DISK3_VERIFY = 0x23,
|
||||
RDE_DISK4_VERIFY = 0x24,
|
||||
RDE_DISK5_VERIFY = 0x25,
|
||||
RDE_DISK6_VERIFY = 0x26,
|
||||
RDE_DISK7_VERIFY = 0x27,
|
||||
RDE_DISK8_VERIFY = 0x28,
|
||||
RDE_DISK9_VERIFY = 0x29,
|
||||
RDE_DISK10_VERIFY = 0x2a,
|
||||
RDE_DISK11_VERIFY = 0x2b,
|
||||
RDE_DISK12_VERIFY = 0x2c,
|
||||
RDE_DISK13_VERIFY = 0x2d,
|
||||
RDE_DISK14_VERIFY = 0x2e,
|
||||
RDE_DISK15_VERIFY = 0x2f,
|
||||
RDE_DISK16_VERIFY = 0x30,
|
||||
RDE_CHAN_TMOUT = 0x31,
|
||||
};
|
||||
|
||||
/* RDE algorithm types */
|
||||
enum {
|
||||
MPCC = 0x00, /* EC */
|
||||
PQ_FLEXEC = 0x40, /* RAID5/RAID6/FlexEC */
|
||||
XOR = 0x60, /* XOR */
|
||||
};
|
||||
|
||||
/* RDE buffer access types */
|
||||
enum {
|
||||
PBUF = 0x00, /* Direct Access */
|
||||
SGL = 0x08, /* Scatter Gather List */
|
||||
PRP = 0x10, /* Physical Region Page List */
|
||||
REVD = 0x18, /* Reserved */
|
||||
};
|
||||
|
||||
/* RDE DIF GRD types */
|
||||
enum {
|
||||
NO_GRD = 0, /* no GRD domain */
|
||||
GRD = 1, /* GRD domain without checking */
|
||||
GRD_CHECK = 2, /* GRD domain with checking */
|
||||
};
|
||||
|
||||
/* RDE DIF REF types */
|
||||
enum {
|
||||
NO_REF = 0, /* no REF domain */
|
||||
REF = 1, /* REF domain without checking */
|
||||
REF_CHECK_LBA = 2, /* REF domain checking with lab */
|
||||
REF_CHECK_PRI = 3, /* REF domain checking with private infoformation */
|
||||
};
|
||||
|
||||
/* RDE IO abort switch */
|
||||
enum {
|
||||
NO_ABORT = 0, /* don't abort the io */
|
||||
ABORT = 1, /* abort the io */
|
||||
};
|
||||
|
||||
/* RDE coefficient matrix load enable */
|
||||
enum {
|
||||
NO_CM_LOAD = 0, /* don't load matrix */
|
||||
CM_LOAD = 1, /* load matrix */
|
||||
};
|
||||
|
||||
/* RDE coefficient matrix types */
|
||||
enum {
|
||||
CM_ENCODE = 0, /* encode type */
|
||||
CM_DECODE = 1, /* decode type */
|
||||
};
|
||||
|
||||
/* RDE algorithms block size */
|
||||
enum {
|
||||
ALG_BLK_512B = 0, /* 512 bytes */
|
||||
ALG_BLK_4K = 1, /* 4K bytes */
|
||||
};
|
||||
|
||||
/* RDE crc iv enable */
|
||||
enum {
|
||||
NO_CRCIV = 0, /* default IV is 0 */
|
||||
CRCIV = 1, /* IV is register's value */
|
||||
};
|
||||
|
||||
/* RDE crc iv switch */
|
||||
enum {
|
||||
CRCIV0 = 0, /* select crc16_iv0 of register */
|
||||
CRCIV1 = 1, /* select crc16_iv1 of register */
|
||||
};
|
||||
|
||||
/* RDE DIF types */
|
||||
enum {
|
||||
NO_RDE_DIF = 0, /* without DIF */
|
||||
RDE_DIF = 1, /* DIF */
|
||||
};
|
||||
|
||||
/* RDE page padding types */
|
||||
enum {
|
||||
NO_PAD = 0, /* without padding */
|
||||
PRE_PAD = 1, /* padding before DIF */
|
||||
POST_PAD = 2, /* padding after DIF */
|
||||
};
|
||||
|
||||
enum {
|
||||
QNUM_64 = 64,
|
||||
QNUM_128 = 128,
|
||||
QNUM_256 = 256,
|
||||
QNUM_512 = 512,
|
||||
QNUM_1024 = 1024,
|
||||
QNUM_BUTT
|
||||
};
|
||||
|
||||
enum {
|
||||
QDEPTH_64 = 64,
|
||||
QDEPTH_128 = 128,
|
||||
QDEPTH_256 = 256,
|
||||
QDEPTH_512 = 512,
|
||||
QDEPTH_1024 = 1024,
|
||||
QDEPTH_BUTT
|
||||
};
|
||||
|
||||
static inline void rde_bd_dump(struct hisi_rde_sqe *bd)
|
||||
{
|
||||
int i;
|
||||
|
||||
pr_info_ratelimited("====== BD info start======\n");
|
||||
for (i = 0; i < sizeof(struct hisi_rde_sqe) / sizeof(u64); i++)
|
||||
pr_info_ratelimited("sqe-word[%d]: 0x%llx.\n",
|
||||
i, *((u64 *)bd + i));
|
||||
|
||||
pr_info_ratelimited("====== BD info end======\n");
|
||||
}
|
||||
|
||||
static inline void rde_table_dump(const struct hisi_rde_msg *req)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SRC_ADDR_TABLE_NUM; i++) {
|
||||
if (req->src_addr->content[i])
|
||||
pr_info_ratelimited("Table0 info[%d] is 0x%llx.\n",
|
||||
i, req->src_addr->content[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < SRC_DIF_TABLE_NUM; i++) {
|
||||
if (req->src_tag_addr->content[i])
|
||||
pr_info_ratelimited("Table1 info[%d] is 0x%llx.\n",
|
||||
i, req->src_tag_addr->content[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < DST_ADDR_TABLE_NUM; i++) {
|
||||
if (req->dst_addr->content[i])
|
||||
pr_info_ratelimited("Table2 info[%d] is 0x%llx.\n",
|
||||
i, req->dst_addr->content[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < DST_DIF_TABLE_NUM; i++) {
|
||||
if (req->dst_tag_addr->content[i])
|
||||
pr_info_ratelimited("Table3 info[%d] is 0x%llx.\n",
|
||||
i, req->dst_tag_addr->content[i]);
|
||||
}
|
||||
}
|
||||
|
||||
struct hisi_qp *rde_create_qp(void);
|
||||
int hisi_rde_abnormal_fix(struct hisi_qm *qm);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,470 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 HiSilicon Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RDE_API_H__
|
||||
#define __RDE_API_H__
|
||||
|
||||
/**
|
||||
* @brief dif pad type
|
||||
*/
|
||||
enum DIF_PAGE_LAYOUT_PAD_TYPE_E {
|
||||
DIF_PAGE_LAYOUT_PAD_NONE = 0x0,
|
||||
DIF_PAGE_LAYOUT_PAD_AHEAD_DIF = 0x1, /* 4096+56+8 */
|
||||
DIF_PAGE_LAYOUT_PAD_BEHIND_DIF = 0x2, /* 4096+8+56 */
|
||||
DIF_PAGE_LAYOUT_PAD_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif pad gen mode enumeration, rde only support 0,3,5.
|
||||
*/
|
||||
enum DIF_PAGE_LAYOUT_PAD_GEN_CTRL_E {
|
||||
DIF_PAGE_LAYOUT_PAD_GEN_NONE = 0x0,
|
||||
DIF_PAGE_LAYOUT_PAD_GEN_FROM_ZERO = 0x3,
|
||||
DIF_PAGE_LAYOUT_PAD_GEN_FROM_SOURCE_DATA = 0x4,
|
||||
DIF_PAGE_LAYOUT_PAD_GEN_FROM_RAID_OR_EC = 0x5,
|
||||
DIF_PAGE_LAYOUT_PAD_GEN_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif grd gen mode enumeration.
|
||||
*/
|
||||
enum DIF_GRD_GEN_CTRL_E {
|
||||
DIF_GRD_GEN_NONE = 0x0,
|
||||
DIF_GRD_GEN_FROM_T10CRC = 0x1,
|
||||
DIF_GRD_GEN_FROM_RAID_OR_EC = 0x5,
|
||||
DIF_GRD_GEN_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif ver gen mode enumeration, rde only support 0 or 1.
|
||||
*/
|
||||
enum DIF_VER_GEN_CTRL_E {
|
||||
DIF_VER_GEN_NONE = 0x0,
|
||||
DIF_VER_GEN_FROM_INPUT = 0x1,
|
||||
DIF_VER_GEN_FROM_ZERO = 0x3,
|
||||
DIF_VER_GEN_FROM_SOURCE_DATA = 0x4,
|
||||
DIF_VER_GEN_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif app gen mode enumeration, rde only support 0,1,5.
|
||||
*/
|
||||
enum DIF_APP_GEN_CTRL_E {
|
||||
DIF_APP_GEN_NONE = 0x0,
|
||||
DIF_APP_GEN_FROM_INPUT = 0x1,
|
||||
DIF_APP_GEN_FROM_ZERO = 0x3,
|
||||
DIF_APP_GEN_FROM_SOURCE_DATA = 0x4,
|
||||
DIF_APP_GEN_FROM_RAID_OR_EC = 0x5,
|
||||
DIF_APP_GEN_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif ref gen mode enumeration, rde only support 0,1,2,5.
|
||||
*/
|
||||
enum DIF_REF_GEN_CTRL_E {
|
||||
DIF_REF_GEN_NONE = 0x0,
|
||||
DIF_REF_GEN_FROM_INPUT_LBA = 0x1,
|
||||
DIF_REF_GEN_FROM_PRIVATE_INFO = 0x2,
|
||||
DIF_REF_GEN_FROM_ZERO = 0x3,
|
||||
DIF_REF_GEN_FROM_SOURCE_DATA = 0x4,
|
||||
DIF_REF_GEN_FROM_RAID_OR_EC = 0x5,
|
||||
DIF_REF_GEN_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif verify mode enumeration, grd: rde only support 0,1,2.
|
||||
*/
|
||||
enum DIF_VERIFY_CTRL_E {
|
||||
DIF_VERIFY_NONE = 0x0,
|
||||
DIF_VERIFY_DO_NOT_VERIFY = 0x1,
|
||||
DIF_VERIFY_ALL_BLOCK = 0x2,
|
||||
DIF_VERIFY_BY_PRIVATE_INFO = 0x3,
|
||||
DIF_VERIFY_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief data store mode, sdk do not support prp temporarily.
|
||||
*/
|
||||
enum ACC_BUF_TYPE_E {
|
||||
ACC_BUF_TYPE_PBUFFER = 0x0,
|
||||
ACC_BUF_TYPE_SGL = 0x1,
|
||||
ACC_BUF_TYPE_PRP = 0x2,
|
||||
ACC_BUF_TYPE_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief rde operation enumeration.
|
||||
*/
|
||||
enum ACC_OPT_RAID_E {
|
||||
ACC_OPT_GEN = 0x0, /* generate */
|
||||
ACC_OPT_VLD = 0x1, /* validate */
|
||||
ACC_OPT_UPD = 0x2, /* update */
|
||||
ACC_OPT_RCT = 0x3, /* reconstruct */
|
||||
ACC_OPT_RAID_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief input addr type mode
|
||||
* @note
|
||||
* value 0 means input virt addr from
|
||||
* kzalloc/get_free_pages/dma_alloc_coherent
|
||||
* value 1 means input phy addr directly without tranform
|
||||
* value 2 means input virt addr from vmalloc,
|
||||
* and this addr type only supports pbuf data store mode
|
||||
* in smmu bypass mode
|
||||
*/
|
||||
enum ACC_ADDR_TYPE_E {
|
||||
VA_FROM_NORMAL_DMA_ZONE = 0x0,
|
||||
PA_PASS_THROUGH = 0x1,
|
||||
VA_FROM_HIGHMEM_ZONE = 0x2,
|
||||
ACC_ADDR_TYPE_BUTT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief WRR sched, weights is 1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16.
|
||||
*/
|
||||
enum ACC_PRT_E {
|
||||
ACC_PRT_WEIGHTS_1 = 0x0,
|
||||
ACC_PRT_WEIGHTS_2,
|
||||
ACC_PRT_WEIGHTS_3,
|
||||
ACC_PRT_WEIGHTS_4,
|
||||
ACC_PRT_WEIGHTS_5,
|
||||
ACC_PRT_WEIGHTS_6,
|
||||
ACC_PRT_WEIGHTS_7,
|
||||
ACC_PRT_WEIGHTS_8,
|
||||
ACC_PRT_WEIGHTS_9,
|
||||
ACC_PRT_WEIGHTS_10,
|
||||
ACC_PRT_WEIGHTS_11,
|
||||
ACC_PRT_WEIGHTS_12,
|
||||
ACC_PRT_WEIGHTS_13,
|
||||
ACC_PRT_WEIGHTS_14,
|
||||
ACC_PRT_WEIGHTS_15,
|
||||
ACC_PRT_WEIGHTS_16,
|
||||
ACC_PRT_BUTT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief sge structure, should fill buf and len.
|
||||
* @buf: page data start address, 64bit
|
||||
* @len: valid data len, Byte
|
||||
* @note
|
||||
* usually, just need to fill buf and len
|
||||
*/
|
||||
struct sgl_entry_hw {
|
||||
char *buf;
|
||||
void *page_ctrl;
|
||||
uint32_t len;
|
||||
uint32_t pad;
|
||||
uint32_t pad0;
|
||||
uint32_t pad1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief sgl structure.
|
||||
* @next: next sgl point, to make up chain, 64bit
|
||||
* @entry_sum_in_chain: sum of entry_sum_in_sgl in sgl chain
|
||||
* @entry_sum_in_sgl: valid sgl_entry num in this sgl
|
||||
* @entry_num_in_sgl: sgl_entry num in this sgl
|
||||
* @entries: sgl_entry point
|
||||
* @note
|
||||
* usually, just need to fill next, entry_sum_in_chain,
|
||||
* entry_sum_in_sgl, entry_num_in_sgl and entry
|
||||
* entry_sum_in_chain is valid from the first sgl
|
||||
* entry_sum_in_sgl <= entry_num_in_sgl
|
||||
* sgl_entry point is determined by entry_sum_in_sgl
|
||||
*/
|
||||
struct sgl_hw {
|
||||
struct sgl_hw *next;
|
||||
uint16_t entry_sum_in_chain;
|
||||
uint16_t entry_sum_in_sgl;
|
||||
uint16_t entry_num_in_sgl;
|
||||
uint8_t pad0[2];
|
||||
uint64_t serial_num;
|
||||
uint32_t flag;
|
||||
uint32_t cpu_id;
|
||||
uint8_t pad1[8];
|
||||
uint8_t reserved[24];
|
||||
struct sgl_entry_hw entries[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief sgl structure for rde.
|
||||
* @ctrl: source and destination data block SGL address
|
||||
* @buf_offset: offset of per data disk in the SGL chain
|
||||
* @parity: 0 means data disk, 1 means parity disk
|
||||
* @column: the index corresponding to src and dst disk
|
||||
* @note
|
||||
* parity is just valid in update mode
|
||||
*/
|
||||
struct rde_sgl {
|
||||
struct sgl_hw *ctrl;
|
||||
uint32_t buf_offset;
|
||||
uint8_t parity;
|
||||
uint8_t reserve;
|
||||
uint16_t column;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief pbuf structure for rde.
|
||||
* @note
|
||||
* parity is just valid in update mode
|
||||
*/
|
||||
struct rde_pbuf {
|
||||
char *pbuf;
|
||||
uint32_t reserve1;
|
||||
uint8_t parity;
|
||||
uint8_t reserve2;
|
||||
uint16_t column;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif data structure.
|
||||
* @grd: 16bit gurad tag
|
||||
* @ver: 8bit version
|
||||
* @app: 8bit application information field
|
||||
* @ref: 32bit reference tag
|
||||
*/
|
||||
struct dif_data {
|
||||
uint16_t grd;
|
||||
uint8_t ver;
|
||||
uint8_t app;
|
||||
uint32_t ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif gen ctrl structure.
|
||||
* @page_layout_gen_type: denoted by enum DIF_PAGE_LAYOUT_PAD_GEN_CTRL_E
|
||||
* @grd_gen_type: denoted by enum DIF_GRD_GEN_CTRL_E
|
||||
* @ver_gen_type: denoted by enum DIF_VER_GEN_CTRL_E
|
||||
* @app_gen_type: denoted by enum DIF_APP_GEN_CTRL_E
|
||||
* @ref_gen_type: denoted by enum DIF_REF_GEN_CTRL_E
|
||||
* @page_layout_pad_type: denoted by enum DIF_PAGE_LAYOUT_PAD_TYPE_E
|
||||
*/
|
||||
struct dif_gen {
|
||||
uint32_t page_layout_gen_type:4;
|
||||
uint32_t grd_gen_type:4;
|
||||
uint32_t ver_gen_type:4;
|
||||
uint32_t app_gen_type:4;
|
||||
uint32_t ref_gen_type:4;
|
||||
uint32_t page_layout_pad_type:2;
|
||||
uint32_t reserved:10;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif verify ctrl structure.
|
||||
* @grd_verify_type: denoted by enum DIF_VERIFY_CTRL_E
|
||||
* @ref_verify_type: denoted by enum DIF_VERIFY_CTRL_E
|
||||
* @note
|
||||
* just need to fill grd_verify_type and ref_verify_type
|
||||
*/
|
||||
struct dif_verify {
|
||||
uint16_t page_layout_pad_type:2;
|
||||
uint16_t grd_verify_type:4;
|
||||
uint16_t ref_verify_type:4;
|
||||
uint16_t reserved:6;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief dif ctrl structure.
|
||||
*/
|
||||
struct dif_ctrl {
|
||||
struct dif_gen gen;
|
||||
struct dif_verify verify;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief general dif structure.
|
||||
* @lba: lba for dif ref field
|
||||
* @priv: private info for dif ref field
|
||||
* @ver: 8bit version
|
||||
* @app: 8bit application information field
|
||||
* @note
|
||||
* RDE need not to fill lba
|
||||
*/
|
||||
struct acc_dif {
|
||||
uint64_t lba;
|
||||
uint32_t priv;
|
||||
uint8_t ver;
|
||||
uint8_t app;
|
||||
struct dif_ctrl ctrl;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief ctrl information for per request,
|
||||
* user should alloc and init this structure.
|
||||
* @src_data: src data address, reference rde data structure
|
||||
* @dst_data: dst data address, reference rde data structure
|
||||
* @src_num: number of source disks
|
||||
* @dst_num: number of dst disks
|
||||
* @block_size: support 512,520,4096,4104,4160
|
||||
* @input_block: number of sector
|
||||
* @data_len: data len of per disk, block_size (with dif)* input_block
|
||||
* @buf_type: denoted by ACC_BUF_TYPE_E
|
||||
* @src_dif: dif information of source disks
|
||||
* @dst_dif: dif information of dest disks
|
||||
* @cm_load: coe_matrix reload control, 0: do not load, 1: load
|
||||
* @cm_len: length of loaded coe_matrix, equal to src_num
|
||||
* @alg_blk_size: algorithm granularity, 0: 512 gran, 1: 4096 gran
|
||||
* @mem_saving: mem saving or not, default 0
|
||||
* @coe_matrix: coe matrix address, should be 64byte aligned
|
||||
* @priv: design for user
|
||||
* @note
|
||||
* only mpcc support mem_saving mode, no mem_saving is 0x0, mem_saving is 0x1
|
||||
*/
|
||||
struct raid_ec_ctrl {
|
||||
void *src_data;
|
||||
void *dst_data;
|
||||
uint32_t src_num;
|
||||
uint32_t dst_num;
|
||||
uint32_t block_size;
|
||||
uint32_t input_block;
|
||||
uint32_t data_len;
|
||||
uint32_t buf_type;
|
||||
struct acc_dif src_dif;
|
||||
struct acc_dif dst_dif;
|
||||
uint8_t cm_load;
|
||||
uint8_t cm_len;
|
||||
uint8_t alg_blk_size;
|
||||
uint8_t mem_saving;
|
||||
void *coe_matrix;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief acc_callback of user.
|
||||
* @note
|
||||
* ctx means struct acc_ctx
|
||||
* tag means struct raid_ec_ctrl
|
||||
*/
|
||||
typedef void (*acc_callback)(void *ctx, void *tag, int status, size_t len);
|
||||
|
||||
/**
|
||||
* @brief acc ctx structure, acc_init api will init this structure
|
||||
* @inner: reserved for SDK to point to hisi_rde_ctx structure
|
||||
* @cb: callback function for pool and asynchronously api
|
||||
* @priority: denoted by ACC_PRT_E
|
||||
* @addr_type: denoted by ACC_ADDR_TYPE_E
|
||||
*/
|
||||
struct acc_ctx {
|
||||
void *inner;
|
||||
acc_callback cb;
|
||||
uint8_t priority;
|
||||
uint8_t addr_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief return value.
|
||||
*/
|
||||
enum ACC_STATUS_E {
|
||||
ACC_SUCCESS = 0,
|
||||
ACC_INVALID_PARAM = (-103), /*!< parameter error */
|
||||
ACC_RDE_DIF_ERR = (-113), /*!< Input or Output dif check error */
|
||||
ACC_RDE_DISK_VERIFY_ERR = (-114) /*!< Output data verify error */
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief initialization before you call the other api.
|
||||
*
|
||||
* @param [in] ctx is the context which manage the instance.
|
||||
* @retval 0 is success, else is a negative number that is error code.
|
||||
*
|
||||
* @note
|
||||
* Be sure you will fill para cb and addr_type, then call this function.
|
||||
*
|
||||
*/
|
||||
int acc_init(struct acc_ctx *ctx);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief reconfig callback of ctx.
|
||||
*
|
||||
* @param [in] ctx is the context which manage the instance.
|
||||
* @retval 0 is success, else is a negative number that is error code.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*/
|
||||
int acc_setup_callback(struct acc_ctx *ctx, acc_callback cb);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief release resource that alloced by acc_init().
|
||||
*
|
||||
* @param [in] ctx is the context which manage the instance.
|
||||
* @retval 0 is success, else is a negative number that is error code.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*/
|
||||
int acc_clear(struct acc_ctx *ctx);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief flexec/raid5/raid6 operation asynchronously.
|
||||
*
|
||||
* @param [in] ctx is the context which manage the instance.
|
||||
* @param [in] ctrl is the parameter data of current io.
|
||||
* @param [in] op_type is from ACC_OPT_RAID_E
|
||||
* @retval 0 is success, else is a negative number that is error code.
|
||||
*
|
||||
* @note
|
||||
*Multiple concurrent processing is not supported for the same instance.
|
||||
*/
|
||||
int acc_do_flexec_asyn(struct acc_ctx *ctx,
|
||||
struct raid_ec_ctrl *ctrl, uint8_t op_type);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief mpcc operation asynchronously.
|
||||
*
|
||||
* @param [in] ctx is the context which manage the instance.
|
||||
* @param [in] ctrl is the parameter data of current io.
|
||||
* @param [in] op_type is from ACC_OPT_RAID_E
|
||||
* @retval 0 is success, else is a negative number that is error code.
|
||||
*
|
||||
* @note
|
||||
*Multiple concurrent processing is not supported for the same instance.
|
||||
*/
|
||||
int acc_do_mpcc_asyn(struct acc_ctx *ctx,
|
||||
struct raid_ec_ctrl *ctrl, uint8_t op_type);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief flexec/raid5/raid6 operation synchronously.
|
||||
*
|
||||
* @param [in] ctx is the context which manage the instance.
|
||||
* @param [in] ctrl is the parameter data of current io.
|
||||
* @param [in] op_type is from ACC_OPT_RAID_E
|
||||
* @retval 0 is success, else is a negative number that is error code.
|
||||
*
|
||||
* @note
|
||||
*Multiple concurrent processing is not supported for the same instance.
|
||||
*/
|
||||
int acc_do_flexec(struct acc_ctx *ctx,
|
||||
struct raid_ec_ctrl *ctrl, uint8_t op_type);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief mpcc operation synchronously.
|
||||
*
|
||||
* @param [in] ctx is the context which manage the instance.
|
||||
* @param [in] ctrl is the parameter data of current io.
|
||||
* @param [in] op_type is from ACC_OPT_RAID_E
|
||||
* @retval 0 is success, else is a negative number that is error code.
|
||||
*
|
||||
* @note
|
||||
*Multiple concurrent processing is not supported for the same instance.
|
||||
*/
|
||||
int acc_do_mpcc(struct acc_ctx *ctx,
|
||||
struct raid_ec_ctrl *ctrl, uint8_t op_type);
|
||||
|
||||
#endif /* __ACC_API_H__ */
|
|
@ -0,0 +1,216 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2018-2019 HiSilicon Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/types.h>
|
||||
#include "rde_data.h"
|
||||
|
||||
static inline u32 sgl_addr_cnt(struct sgl_hw *sgl)
|
||||
{
|
||||
u32 cnt = 0;
|
||||
struct sgl_hw *cur_sgl = sgl;
|
||||
|
||||
if (!sgl) {
|
||||
pr_err("[%s] Sgl address is NULL.\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (cur_sgl) {
|
||||
cnt += 1;
|
||||
cnt += cur_sgl->entry_sum_in_sgl;
|
||||
cur_sgl = cur_sgl->next;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int acc_sgl_dump(struct sgl_hw *data)
|
||||
{
|
||||
u32 i;
|
||||
u32 cnt_entries;
|
||||
struct sgl_hw *cur_sgl;
|
||||
struct sgl_hw *next_sgl;
|
||||
struct sgl_entry_hw *entry;
|
||||
|
||||
if (unlikely(!data->entry_sum_in_sgl)) {
|
||||
pr_err("Error! The entrysum of sgl is zero.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
cnt_entries = sgl_addr_cnt(data);
|
||||
pr_info("Sgl entries:%d.\n", cnt_entries);
|
||||
|
||||
for (cur_sgl = data; cur_sgl; ) {
|
||||
pr_info("Sgl addr: 0x%pK.\n", cur_sgl);
|
||||
pr_info("NextSgl: 0x%pK.\n", cur_sgl->next);
|
||||
pr_info("EntrySumInChain: %u.\n", cur_sgl->entry_sum_in_chain);
|
||||
pr_info("EntrySumInSgl: %u.\n", cur_sgl->entry_sum_in_sgl);
|
||||
|
||||
entry = cur_sgl->entries;
|
||||
for (i = 0; (i < cur_sgl->entry_sum_in_sgl &&
|
||||
entry->buf); i++) {
|
||||
pr_info("Entries[%d]:addr = 0x%pK.\n", i, entry->buf);
|
||||
entry++;
|
||||
}
|
||||
if (cur_sgl->next)
|
||||
next_sgl = cur_sgl->next;
|
||||
else
|
||||
next_sgl = NULL;
|
||||
|
||||
cur_sgl = next_sgl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acc_sgl_to_scatterlist(struct pci_dev *pdev, struct sgl_hw *data,
|
||||
struct scatterlist *sglist, u32 smmu_state)
|
||||
{
|
||||
u16 i;
|
||||
struct sgl_hw *cur_sgl;
|
||||
struct sgl_hw *next_sgl;
|
||||
struct sgl_entry_hw *entry;
|
||||
dma_addr_t pa;
|
||||
|
||||
cur_sgl = data;
|
||||
while (cur_sgl) {
|
||||
entry = cur_sgl->entries;
|
||||
for (i = 0; (i < cur_sgl->entry_sum_in_sgl &&
|
||||
entry->buf); i++) {
|
||||
sg_set_buf(sglist, (void *)entry->buf, entry->len);
|
||||
pa = acc_virt_to_phys(pdev, sg_virt(sglist),
|
||||
(size_t)sglist->length,
|
||||
smmu_state);
|
||||
sg_dma_address(sglist) = pa;
|
||||
sglist++;
|
||||
entry->buf = (char *)pa;
|
||||
entry++;
|
||||
}
|
||||
if (cur_sgl->next) {
|
||||
next_sgl = cur_sgl->next;
|
||||
sg_set_buf(sglist, (void *)next_sgl,
|
||||
(u32)(sizeof(struct sgl_hw) +
|
||||
sizeof(struct sgl_entry_hw) *
|
||||
(next_sgl->entry_sum_in_sgl)));
|
||||
pa = acc_virt_to_phys(pdev, sg_virt(sglist),
|
||||
(size_t)sglist->length,
|
||||
smmu_state);
|
||||
sg_dma_address(sglist) = pa;
|
||||
sglist++;
|
||||
cur_sgl->next = (struct sgl_hw *)pa;
|
||||
} else {
|
||||
next_sgl = NULL;
|
||||
}
|
||||
cur_sgl = next_sgl;
|
||||
}
|
||||
}
|
||||
|
||||
int acc_sgl_virt_to_phys(struct pci_dev *pdev, struct sgl_hw *data,
|
||||
void **sglist_head, u32 smmu_state)
|
||||
{
|
||||
u32 addr_cnt;
|
||||
struct scatterlist *sglist;
|
||||
|
||||
if (!data) {
|
||||
pr_err("[%s] Para sgl_s is NULL.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(!data->entry_sum_in_sgl) ||
|
||||
data->entry_sum_in_sgl > data->entry_num_in_sgl) {
|
||||
pr_err("[%s] Para sge num is wrong.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
addr_cnt = sgl_addr_cnt(data);
|
||||
sglist = kcalloc(addr_cnt, sizeof(*sglist), GFP_KERNEL);
|
||||
if (unlikely(!sglist)) {
|
||||
pr_err("[%s] Malloc sglist fail.\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*sglist_head = sglist;
|
||||
sg_init_table(sglist, addr_cnt);
|
||||
sg_set_buf(sglist, (void *)data, (u32)(sizeof(struct sgl_hw) +
|
||||
sizeof(struct sgl_entry_hw) * (data->entry_sum_in_sgl)));
|
||||
sg_dma_address(sglist) = acc_virt_to_phys(pdev, sg_virt(sglist),
|
||||
(size_t)sglist->length, smmu_state);
|
||||
sglist++;
|
||||
acc_sgl_to_scatterlist(pdev, data, sglist, smmu_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acc_sgl_phys_to_virt(struct pci_dev *pdev, void *sglist_head,
|
||||
u32 smmu_state)
|
||||
{
|
||||
int i;
|
||||
struct sgl_hw *cur_sgl;
|
||||
struct sgl_hw *next_sgl;
|
||||
struct sgl_entry_hw *entry;
|
||||
struct scatterlist *sglist;
|
||||
struct scatterlist *sg;
|
||||
int ret = -EFAULT;
|
||||
|
||||
if (!sglist_head) {
|
||||
pr_err("[%s] Para sglist_head is NULL.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sglist = (struct scatterlist *)sglist_head;
|
||||
sg = sglist;
|
||||
cur_sgl = (struct sgl_hw *)sg_virt(sg);
|
||||
acc_phys_to_virt(pdev, sg_dma_address(sg),
|
||||
(size_t)sg->length, smmu_state);
|
||||
while (cur_sgl) {
|
||||
entry = cur_sgl->entries;
|
||||
for (i = 0; (i < cur_sgl->entry_sum_in_sgl &&
|
||||
entry->buf); i++) {
|
||||
sg = sg_next(sg);
|
||||
if (unlikely(!sg)) {
|
||||
pr_err("[%s][%d]Scatterlist happens to be NULL.\n",
|
||||
__func__, __LINE__);
|
||||
goto FAIL;
|
||||
}
|
||||
entry->buf = (char *)sg_virt(sg);
|
||||
acc_phys_to_virt(pdev, sg_dma_address(sg),
|
||||
(size_t)sg->length, smmu_state);
|
||||
entry++;
|
||||
}
|
||||
|
||||
if (cur_sgl->next) {
|
||||
sg = sg_next(sg);
|
||||
if (unlikely(!sg)) {
|
||||
pr_err("[%s][%d]Scatterlist happens to be NULL.\n",
|
||||
__func__, __LINE__);
|
||||
goto FAIL;
|
||||
}
|
||||
next_sgl = (struct sgl_hw *)sg_virt(sg);
|
||||
acc_phys_to_virt(pdev, sg_dma_address(sg),
|
||||
(size_t)sg->length, smmu_state);
|
||||
cur_sgl->next = next_sgl;
|
||||
} else {
|
||||
next_sgl = NULL;
|
||||
}
|
||||
|
||||
cur_sgl = next_sgl;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
FAIL:
|
||||
kfree(sglist);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 HiSilicon Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ACC_DATA_H__
|
||||
#define __ACC_DATA_H__
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/mm.h>
|
||||
#include "rde_api.h"
|
||||
|
||||
static inline dma_addr_t acc_virt_to_phys(struct pci_dev *pdev, void *va,
|
||||
size_t size, u32 smmu_state)
|
||||
{
|
||||
dma_addr_t pa;
|
||||
|
||||
if (!smmu_state)
|
||||
pa = (dma_addr_t)virt_to_phys(va);
|
||||
else
|
||||
pa = pci_map_single(pdev, va, size, DMA_BIDIRECTIONAL);
|
||||
|
||||
return pa;
|
||||
}
|
||||
|
||||
static inline dma_addr_t acc_pfn_to_phys(void *va)
|
||||
{
|
||||
unsigned long pfn;
|
||||
unsigned long off;
|
||||
unsigned long pa;
|
||||
|
||||
off = (uintptr_t)va % PAGE_SIZE;
|
||||
pfn = vmalloc_to_pfn(va);
|
||||
pa = (pfn << PAGE_SHIFT) + off;
|
||||
|
||||
return pa;
|
||||
}
|
||||
|
||||
static inline void acc_phys_to_virt(struct pci_dev *pdev, dma_addr_t pa,
|
||||
size_t size, u32 smmu_state)
|
||||
{
|
||||
if (smmu_state)
|
||||
pci_unmap_single(pdev, pa, size, DMA_BIDIRECTIONAL);
|
||||
}
|
||||
|
||||
int acc_sgl_dump(struct sgl_hw *data);
|
||||
int acc_sgl_virt_to_phys(struct pci_dev *pdev, struct sgl_hw *data,
|
||||
void **sglist_head, u32 smmu_state);
|
||||
int acc_sgl_phys_to_virt(struct pci_dev *pdev,
|
||||
void *sglist_head, u32 smmu_state);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,875 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2018-2019 HiSilicon Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/aer.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/topology.h>
|
||||
#include "../../include_linux/uacce.h"
|
||||
#include "rde.h"
|
||||
|
||||
#define HRDE_QUEUE_NUM_V1 4096
|
||||
#define HRDE_QUEUE_NUM_V2 1024
|
||||
#define HRDE_PCI_DEVICE_ID 0xa25a
|
||||
#define HRDE_SQE_SIZE 64
|
||||
#define HRDE_SQ_SIZE (HRDE_SQE_SIZE * QM_Q_DEPTH)
|
||||
#define HRDE_PF_DEF_Q_NUM 256
|
||||
#define HRDE_PF_DEF_Q_BASE 0
|
||||
#define HRDE_RD_INTVRL_US 10
|
||||
#define HRDE_RD_TMOUT_US 1000
|
||||
#define HRDE_RST_TMOUT_MS 400
|
||||
#define HRDE_ENABLE 1
|
||||
#define HRDE_DISABLE 0
|
||||
#define HRDE_PCI_COMMAND_INVALID 0xFFFFFFFF
|
||||
|
||||
#define HRDE_RAS_INT_MSK 0x310290
|
||||
#define HRDE_RAS_CE_MSK BIT(2)
|
||||
#define HRDE_RAS_NFE_MSK BIT(1)
|
||||
#define HRDE_RAS_ENABLE BIT(0)
|
||||
#define HRDE_INT_MSK 0x310314
|
||||
#define HRDE_INT_ENABLE 0x0
|
||||
#define HRDE_INT_DISABLE 0x3ffff
|
||||
#define HRDE_BD_PREFETCH BIT(8)
|
||||
#define HRDE_INT_SOURCE 0x31030c
|
||||
#define HRDE_INT_SOURCE_CLEAR GENMASK(17, 0)
|
||||
#define HRDE_INT_STATUS 0x310318
|
||||
#define HRDE_DFX_CTRL_0 0x310240
|
||||
#define HRDE_ECC_ERR 0x310234
|
||||
#define HRDE_ECC_ERR_CNT 0x310238
|
||||
#define HRDE_OP_DONE_CNT 0x310250
|
||||
#define HRDE_OP_ERR_CNT 0x310254
|
||||
#define HRDE_OP_ABORT_CNT 0x310258
|
||||
#define HRDE_FIFO_STAT_0 0x310200
|
||||
#define HRDE_DFX_STAT_7 0x310334
|
||||
#define HRDE_DFX_STAT_8 0x310338
|
||||
#define DFX_CTRL0 0x3
|
||||
#define WRITE_CLEAR_VAL GENMASK(31, 0)
|
||||
#define HRDE_AWCACHE 0x310154
|
||||
#define HRDE_ARCACHE 0x31015c
|
||||
#define AWCACHE 0xff0
|
||||
#define ARCACHE 0xfff0
|
||||
#define HRDE_CFG 0x310000
|
||||
#define CHN_CFG 0x5010101
|
||||
#define HRDE_AXI_SHUTDOWN_EN BIT(26)
|
||||
#define HRDE_AXI_SHUTDOWN_DIS 0xFBFFFFFF
|
||||
#define HRDE_WR_MSI_PORT BIT(0)
|
||||
#define HRDE_AWUSER_BD_1 0x310104
|
||||
#define HRDE_ARUSER_BD_1 0x310114
|
||||
#define HRDE_ARUSER_SGL_1 0x310124
|
||||
#define HRDE_AWUSER_DAT_1 0x310134
|
||||
#define HRDE_ARUSER_DAT_1 0x310144
|
||||
#define HRDE_USER_SMMU 0x40001070
|
||||
#define HRDE_ERR_CNT 0x310238
|
||||
#define HRDE_ECC_1BIT_ERR BIT(0)
|
||||
#define HRDE_ECC_2BIT_ERR BIT(1)
|
||||
#define HRDE_ECC_1BIT_SHIFT 16
|
||||
#define HRDE_ECC_2BIT_CNT_MSK GENMASK(15, 0)
|
||||
#define HRDE_STATE_INT_ERR GENMASK(11, 2)
|
||||
#define HRDE_AM_CURR_PORT_STS 0x300100
|
||||
#define HRDE_MASTER_TRANS_RET 0x300150
|
||||
#define HRDE_FSM_MAX_CNT 0x310280
|
||||
#define HRDE_QM_IDEL_STATUS 0x1040e4
|
||||
#define HRDE_QM_PEH_DFX_INFO0 0x1000fc
|
||||
#define PEH_MSI_MASK_SHIFT 0x90
|
||||
#define CACHE_CTL 0x1833
|
||||
#define HRDE_DBGFS_VAL_MAX_LEN 20
|
||||
#define HRDE_PROBE_ADDR 0x31025c
|
||||
#define HRDE_PROBE_DATA 0x310260
|
||||
#define HRDE_PROBE_EN BIT(16)
|
||||
#define HRDE_PROBE_DATA_EN BIT(17)
|
||||
#define HRDE_STRB_CS_SHIFT 9
|
||||
|
||||
static const char hisi_rde_name[] = "hisi_rde";
|
||||
static struct dentry *hrde_debugfs_root;
|
||||
static struct hisi_qm_list rde_devices;
|
||||
static void hisi_rde_ras_proc(struct work_struct *work);
|
||||
|
||||
static const struct hisi_rde_hw_error rde_hw_error[] = {
|
||||
{.int_msk = BIT(0), .msg = "Rde_ecc_1bitt_err"},
|
||||
{.int_msk = BIT(1), .msg = "Rde_ecc_2bit_err"},
|
||||
{.int_msk = BIT(2), .msg = "Rde_stat_mgmt_state_timeout_err"},
|
||||
{.int_msk = BIT(3), .msg = "Rde_data_wr_state_timeout_err"},
|
||||
{.int_msk = BIT(4), .msg = "Rde_alg_state_timeout_err"},
|
||||
{.int_msk = BIT(5), .msg = "Rde_data_ar_state_timeout_err"},
|
||||
{.int_msk = BIT(6), .msg = "Rde_bd_mgmt_state_timeout_err"},
|
||||
{.int_msk = BIT(7), .msg = "Rde_list_parse_ar_state_timeout_err"},
|
||||
{.int_msk = BIT(8), .msg = "Rde_bd_prefetch_state_timeout_err"},
|
||||
{.int_msk = BIT(9), .msg = "Rde_dst_buf_parse_state_timeout_err"},
|
||||
{.int_msk = BIT(10), .msg = "Rde_src_buf_parse_state_timeout_err"},
|
||||
{.int_msk = BIT(11), .msg = "Rde_chn_timeout_err"},
|
||||
{.int_msk = BIT(12), .msg = "Rde_bd_bresp_err"},
|
||||
{.int_msk = BIT(13), .msg = "Rde_data_bresp_err"},
|
||||
{.int_msk = BIT(14), .msg = "Rde_data_rresp_err"},
|
||||
{.int_msk = BIT(15), .msg = "Rde_sgl_rresp_err"},
|
||||
{.int_msk = BIT(16), .msg = "Rde_list_rresp_err"},
|
||||
{.int_msk = BIT(17), .msg = "Rde_bd_rresp_err"},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
enum ctrl_debug_file_index {
|
||||
HRDE_CURRENT_FUNCTION,
|
||||
HRDE_CURRENT_BD,
|
||||
HRDE_DEBUG_FILE_NUM,
|
||||
/* RDE not support CNT_CLR_CE config, default enable */
|
||||
};
|
||||
|
||||
static const char *const ctrl_debug_file_name[] = {
|
||||
[HRDE_CURRENT_FUNCTION] = "current_function_id",
|
||||
[HRDE_CURRENT_BD] = "current_bd",
|
||||
};
|
||||
|
||||
struct ctrl_debug_file {
|
||||
enum ctrl_debug_file_index index;
|
||||
spinlock_t lock;
|
||||
struct hisi_rde_ctrl *ctrl;
|
||||
};
|
||||
|
||||
/*
|
||||
* One RDE controller has one PF and multiple VFs, some global configurations
|
||||
* which PF has need this structure.
|
||||
* Just relevant for PF.
|
||||
*/
|
||||
struct hisi_rde_ctrl {
|
||||
struct hisi_rde *hisi_rde;
|
||||
struct ctrl_debug_file files[HRDE_DEBUG_FILE_NUM];
|
||||
};
|
||||
|
||||
static struct debugfs_reg32 hrde_dfx_regs[] = {
|
||||
{"HRDE_DFX_STAT_0", 0x310220ull},
|
||||
{"HRDE_DFX_STAT_1", 0x310224ull},
|
||||
{"HRDE_DFX_STAT_2", 0x310320ull},
|
||||
{"HRDE_DFX_STAT_3", 0x310324ull},
|
||||
{"HRDE_DFX_STAT_4", 0x310328ull},
|
||||
{"HRDE_DFX_STAT_5", 0x31032cull},
|
||||
{"HRDE_DFX_STAT_6", 0x310330ull},
|
||||
{"HRDE_DFX_STAT_7", 0x310334ull},
|
||||
{"HRDE_DFX_STAT_8", 0x310338ull},
|
||||
{"HRDE_FIFO_STAT_0", 0x310200ull},
|
||||
{"HRDE_FIFO_STAT_1", 0x310204ull},
|
||||
{"HRDE_OP_TAG_0", 0x310214ull},
|
||||
{"HRDE_OP_TAG_1", 0x310218ull},
|
||||
{"HRDE_OP_TAG_2", 0x31021cull},
|
||||
{"HRDE_ECC_ERR", 0x310234ull},
|
||||
{"HRDE_ECC_ERR_CNT", 0x310238ull},
|
||||
{"HRDE_OP_DONE_CNT", 0x310250ull},
|
||||
{"HRDE_OP_ERR_CNT", 0x310254ull},
|
||||
{"HRDE_OP_ABORT_CNT", 0x310258ull},
|
||||
{"HRDE_TMP_ADDR_HIGH", 0x310270ull},
|
||||
{"HRDE_TMP_ADDR_LOW", 0x310274ull},
|
||||
{"HRDE_TMP_LENGTH", 0x310278ull},
|
||||
{"HRDE_INT_STATUS", 0x310318ull},
|
||||
};
|
||||
|
||||
static struct debugfs_reg32 hrde_ooo_dfx_regs[] = {
|
||||
{"HRDE_AM_CURR_PORT_STS", 0x300100ull},
|
||||
{"HRDE_AM_ROB_ECC_ERR_ADDR", 0x30010cull},
|
||||
{"HRDE_AM_CURR_TRANS_RETURN", 0x300150ull},
|
||||
{"HRDE_AM_CURR_RD_TXID_STS_0", 0x300160ull},
|
||||
{"HRDE_AM_CURR_RD_TXID_STS_1", 0x300164ull},
|
||||
{"HRDE_AM_CURR_RD_TXID_STS_2", 0x300168ull},
|
||||
{"HRDE_AM_CURR_WR_TXID_STS_0", 0x300170ull},
|
||||
{"HRDE_AM_CURR_WR_TXID_STS_1", 0x300174ull},
|
||||
{"HRDE_AM_CURR_WR_TXID_STS_2", 0x300178ull},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CRYPTO_QM_UACCE
|
||||
static int uacce_mode_set(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
return mode_set(val, kp);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops uacce_mode_ops = {
|
||||
.set = uacce_mode_set,
|
||||
.get = param_get_int,
|
||||
};
|
||||
|
||||
static int uacce_mode = UACCE_MODE_NOIOMMU;
|
||||
module_param_cb(uacce_mode, &uacce_mode_ops, &uacce_mode, 0444);
|
||||
MODULE_PARM_DESC(uacce_mode, "Mode of UACCE can be 0(default), 2");
|
||||
#endif
|
||||
|
||||
static int pf_q_num_set(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
return q_num_set(val, kp, HRDE_PCI_DEVICE_ID);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops pf_q_num_ops = {
|
||||
.set = pf_q_num_set,
|
||||
.get = param_get_int,
|
||||
};
|
||||
|
||||
static u32 pf_q_num = HRDE_PF_DEF_Q_NUM;
|
||||
module_param_cb(pf_q_num, &pf_q_num_ops, &pf_q_num, 0444);
|
||||
MODULE_PARM_DESC(pf_q_num, "Number of queues in PF(v1 0-4096, v2 0-1024)");
|
||||
|
||||
static const struct pci_device_id hisi_rde_dev_ids[] = {
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HRDE_PCI_DEVICE_ID)},
|
||||
{0,}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, hisi_rde_dev_ids);
|
||||
|
||||
struct hisi_qp *rde_create_qp(void)
|
||||
{
|
||||
int node = cpu_to_node(smp_processor_id());
|
||||
struct hisi_qp *qp;
|
||||
int ret;
|
||||
|
||||
ret = hisi_qm_alloc_qps_node(node, &rde_devices, &qp, 1, 0);
|
||||
if (!ret)
|
||||
return qp;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int hisi_rde_engine_init(struct hisi_qm *qm)
|
||||
{
|
||||
writel(DFX_CTRL0, qm->io_base + HRDE_DFX_CTRL_0);
|
||||
|
||||
/* usr domain */
|
||||
writel(HRDE_USER_SMMU, qm->io_base + HRDE_AWUSER_BD_1);
|
||||
writel(HRDE_USER_SMMU, qm->io_base + HRDE_ARUSER_BD_1);
|
||||
writel(HRDE_USER_SMMU, qm->io_base + HRDE_AWUSER_DAT_1);
|
||||
writel(HRDE_USER_SMMU, qm->io_base + HRDE_ARUSER_DAT_1);
|
||||
writel(HRDE_USER_SMMU, qm->io_base + HRDE_ARUSER_SGL_1);
|
||||
/* rde cache */
|
||||
writel(AWCACHE, qm->io_base + HRDE_AWCACHE);
|
||||
writel(ARCACHE, qm->io_base + HRDE_ARCACHE);
|
||||
|
||||
/* rde chn enable + outstangding config */
|
||||
writel(CHN_CFG, qm->io_base + HRDE_CFG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hisi_rde_set_user_domain_and_cache(struct hisi_qm *qm)
|
||||
{
|
||||
/* qm user domain */
|
||||
writel(AXUSER_BASE, qm->io_base + QM_ARUSER_M_CFG_1);
|
||||
writel(ARUSER_M_CFG_ENABLE, qm->io_base + QM_ARUSER_M_CFG_ENABLE);
|
||||
writel(AXUSER_BASE, qm->io_base + QM_AWUSER_M_CFG_1);
|
||||
writel(AWUSER_M_CFG_ENABLE, qm->io_base + QM_AWUSER_M_CFG_ENABLE);
|
||||
writel(WUSER_M_CFG_ENABLE, qm->io_base + QM_WUSER_M_CFG_ENABLE);
|
||||
|
||||
/* qm cache */
|
||||
writel(AXI_M_CFG, qm->io_base + QM_AXI_M_CFG);
|
||||
writel(AXI_M_CFG_ENABLE, qm->io_base + QM_AXI_M_CFG_ENABLE);
|
||||
|
||||
/* disable BME/PM/SRIOV FLR*/
|
||||
writel(PEH_AXUSER_CFG, qm->io_base + QM_PEH_AXUSER_CFG);
|
||||
writel(PEH_AXUSER_CFG_ENABLE, qm->io_base + QM_PEH_AXUSER_CFG_ENABLE);
|
||||
|
||||
writel(CACHE_CTL, qm->io_base + QM_CACHE_CTL);
|
||||
|
||||
return hisi_rde_engine_init(qm);
|
||||
}
|
||||
|
||||
static void hisi_rde_debug_regs_clear(struct hisi_qm *qm)
|
||||
{
|
||||
/* clear rde debug regs */
|
||||
readl(qm->io_base + HRDE_ECC_ERR);
|
||||
readl(qm->io_base + HRDE_ECC_ERR_CNT);
|
||||
readl(qm->io_base + HRDE_OP_DONE_CNT);
|
||||
readl(qm->io_base + HRDE_OP_ERR_CNT);
|
||||
readl(qm->io_base + HRDE_OP_ABORT_CNT);
|
||||
writel(WRITE_CLEAR_VAL, qm->io_base + HRDE_FIFO_STAT_0);
|
||||
writel(WRITE_CLEAR_VAL, qm->io_base + HRDE_DFX_STAT_7);
|
||||
writel(WRITE_CLEAR_VAL, qm->io_base + HRDE_DFX_STAT_8);
|
||||
|
||||
/* clear current_qm */
|
||||
writel(0x0, qm->io_base + QM_DFX_MB_CNT_VF);
|
||||
writel(0x0, qm->io_base + QM_DFX_DB_CNT_VF);
|
||||
|
||||
hisi_qm_debug_regs_clear(qm);
|
||||
}
|
||||
|
||||
static void hisi_rde_hw_error_enable(struct hisi_qm *qm)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(qm->io_base + HRDE_CFG);
|
||||
|
||||
/* clear RDE hw error source if having */
|
||||
writel(HRDE_INT_SOURCE_CLEAR, qm->io_base + HRDE_INT_SOURCE);
|
||||
writel(HRDE_RAS_ENABLE, qm->io_base + HRDE_RAS_INT_MSK);
|
||||
|
||||
/* bd prefetch should bd masked to prevent misreport */
|
||||
writel((HRDE_INT_ENABLE | HRDE_BD_PREFETCH),
|
||||
qm->io_base + HRDE_INT_MSK);
|
||||
|
||||
/* when m-bit error occur, master ooo will close */
|
||||
val = val | HRDE_AXI_SHUTDOWN_EN;
|
||||
writel(val, qm->io_base + HRDE_CFG);
|
||||
}
|
||||
|
||||
static void hisi_rde_hw_error_disable(struct hisi_qm *qm)
|
||||
{
|
||||
u32 ras_msk = HRDE_RAS_CE_MSK | HRDE_RAS_NFE_MSK;
|
||||
u32 val;
|
||||
|
||||
val = readl(qm->io_base + HRDE_CFG);
|
||||
|
||||
writel(ras_msk, qm->io_base + HRDE_RAS_INT_MSK);
|
||||
writel(HRDE_INT_DISABLE, qm->io_base + HRDE_INT_MSK);
|
||||
|
||||
/* when m-bit error occur, master ooo will not close */
|
||||
val = val & HRDE_AXI_SHUTDOWN_DIS;
|
||||
writel(val, qm->io_base + HRDE_CFG);
|
||||
}
|
||||
|
||||
static inline struct hisi_qm *file_to_qm(struct ctrl_debug_file *file)
|
||||
{
|
||||
struct hisi_rde *hisi_rde = file->ctrl->hisi_rde;
|
||||
|
||||
return &hisi_rde->qm;
|
||||
}
|
||||
|
||||
static u32 current_qm_read(struct ctrl_debug_file *file)
|
||||
{
|
||||
struct hisi_qm *qm = file_to_qm(file);
|
||||
|
||||
return readl(qm->io_base + QM_DFX_MB_CNT_VF);
|
||||
}
|
||||
|
||||
static int current_qm_write(struct ctrl_debug_file *file, u32 val)
|
||||
{
|
||||
struct hisi_qm *qm = file_to_qm(file);
|
||||
u32 tmp;
|
||||
|
||||
if (val > 0) {
|
||||
pr_err("Function id should be smaller than 0.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
writel(val, qm->io_base + QM_DFX_MB_CNT_VF);
|
||||
writel(val, qm->io_base + QM_DFX_DB_CNT_VF);
|
||||
|
||||
tmp = val |
|
||||
(readl(qm->io_base + QM_DFX_SQE_CNT_VF_SQN) & CURRENT_Q_MASK);
|
||||
writel(tmp, qm->io_base + QM_DFX_SQE_CNT_VF_SQN);
|
||||
|
||||
tmp = val |
|
||||
(readl(qm->io_base + QM_DFX_CQE_CNT_VF_CQN) & CURRENT_Q_MASK);
|
||||
writel(tmp, qm->io_base + QM_DFX_CQE_CNT_VF_CQN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int current_bd_read(struct ctrl_debug_file *file)
|
||||
{
|
||||
struct hisi_qm *qm = file_to_qm(file);
|
||||
|
||||
return readl(qm->io_base + HRDE_PROBE_DATA);
|
||||
}
|
||||
|
||||
static int current_bd_write(struct ctrl_debug_file *file, u32 val)
|
||||
{
|
||||
struct hisi_qm *qm = file_to_qm(file);
|
||||
u32 tmp = 0;
|
||||
|
||||
if (val >= (HRDE_SQE_SIZE / sizeof(u32))) {
|
||||
pr_err("Width index should be smaller than 16.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = HRDE_PROBE_DATA_EN | HRDE_PROBE_EN | (val << HRDE_STRB_CS_SHIFT);
|
||||
writel(tmp, qm->io_base + HRDE_PROBE_ADDR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t ctrl_debug_read(struct file *filp, char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct ctrl_debug_file *file = filp->private_data;
|
||||
char tbuf[HRDE_DBGFS_VAL_MAX_LEN];
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
spin_lock_irq(&file->lock);
|
||||
switch (file->index) {
|
||||
case HRDE_CURRENT_FUNCTION:
|
||||
val = current_qm_read(file);
|
||||
ret = snprintf(tbuf, HRDE_DBGFS_VAL_MAX_LEN, "%u\n", val);
|
||||
break;
|
||||
case HRDE_CURRENT_BD:
|
||||
val = current_bd_read(file);
|
||||
ret = snprintf(tbuf, HRDE_DBGFS_VAL_MAX_LEN, "%x\n", val);
|
||||
break;
|
||||
default:
|
||||
spin_unlock_irq(&file->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
spin_unlock_irq(&file->lock);
|
||||
|
||||
return simple_read_from_buffer(buf, count, pos, tbuf, ret);
|
||||
}
|
||||
|
||||
static ssize_t ctrl_debug_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct ctrl_debug_file *file = filp->private_data;
|
||||
char tbuf[20];
|
||||
unsigned long val;
|
||||
int len, ret;
|
||||
|
||||
if (*pos != 0)
|
||||
return 0;
|
||||
|
||||
if (count >= HRDE_DBGFS_VAL_MAX_LEN)
|
||||
return -ENOSPC;
|
||||
|
||||
len = simple_write_to_buffer(tbuf, HRDE_DBGFS_VAL_MAX_LEN - 1,
|
||||
pos, buf, count);
|
||||
if (len < 0)
|
||||
return len;
|
||||
|
||||
tbuf[len] = '\0';
|
||||
if (kstrtoul(tbuf, 0, &val))
|
||||
return -EFAULT;
|
||||
|
||||
spin_lock_irq(&file->lock);
|
||||
switch (file->index) {
|
||||
case HRDE_CURRENT_FUNCTION:
|
||||
ret = current_qm_write(file, val);
|
||||
if (ret)
|
||||
goto err_input;
|
||||
break;
|
||||
case HRDE_CURRENT_BD:
|
||||
ret = current_bd_write(file, val);
|
||||
if (ret)
|
||||
goto err_input;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto err_input;
|
||||
}
|
||||
spin_unlock_irq(&file->lock);
|
||||
|
||||
return count;
|
||||
|
||||
err_input:
|
||||
spin_unlock_irq(&file->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations ctrl_debug_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = ctrl_debug_read,
|
||||
.write = ctrl_debug_write,
|
||||
};
|
||||
|
||||
static int hisi_rde_chn_debug_init(struct hisi_qm *qm)
|
||||
{
|
||||
struct device *dev = &qm->pdev->dev;
|
||||
struct debugfs_regset32 *regset, *regset_ooo;
|
||||
struct dentry *tmp_d, *tmp;
|
||||
char buf[HRDE_DBGFS_VAL_MAX_LEN];
|
||||
int ret;
|
||||
|
||||
ret = snprintf(buf, HRDE_DBGFS_VAL_MAX_LEN, "rde_dfx");
|
||||
if (ret < 0)
|
||||
return -ENOENT;
|
||||
|
||||
tmp_d = debugfs_create_dir(buf, qm->debug.debug_root);
|
||||
if (!tmp_d)
|
||||
return -ENOENT;
|
||||
|
||||
regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
|
||||
if (!regset)
|
||||
return -ENOENT;
|
||||
regset->regs = hrde_dfx_regs;
|
||||
regset->nregs = ARRAY_SIZE(hrde_dfx_regs);
|
||||
regset->base = qm->io_base;
|
||||
tmp = debugfs_create_regset32("chn_regs", 0444, tmp_d, regset);
|
||||
if (!tmp)
|
||||
return -ENOENT;
|
||||
|
||||
regset_ooo = devm_kzalloc(dev, sizeof(*regset_ooo), GFP_KERNEL);
|
||||
if (!regset_ooo)
|
||||
return -ENOENT;
|
||||
regset_ooo->regs = hrde_ooo_dfx_regs;
|
||||
regset_ooo->nregs = ARRAY_SIZE(hrde_ooo_dfx_regs);
|
||||
regset_ooo->base = qm->io_base;
|
||||
tmp = debugfs_create_regset32("ooo_regs", 0444, tmp_d, regset_ooo);
|
||||
if (!tmp)
|
||||
return -ENOENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hisi_rde_ctrl_debug_init(struct hisi_qm *qm)
|
||||
{
|
||||
struct hisi_rde *hisi_rde = container_of(qm, struct hisi_rde, qm);
|
||||
struct dentry *tmp;
|
||||
int i;
|
||||
|
||||
for (i = HRDE_CURRENT_FUNCTION; i < HRDE_DEBUG_FILE_NUM; i++) {
|
||||
spin_lock_init(&hisi_rde->ctrl->files[i].lock);
|
||||
hisi_rde->ctrl->files[i].ctrl = hisi_rde->ctrl;
|
||||
hisi_rde->ctrl->files[i].index = i;
|
||||
|
||||
tmp = debugfs_create_file(ctrl_debug_file_name[i], 0600,
|
||||
qm->debug.debug_root,
|
||||
hisi_rde->ctrl->files + i,
|
||||
&ctrl_debug_fops);
|
||||
if (!tmp)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return hisi_rde_chn_debug_init(qm);
|
||||
}
|
||||
|
||||
static int hisi_rde_debugfs_init(struct hisi_qm *qm)
|
||||
{
|
||||
struct device *dev = &qm->pdev->dev;
|
||||
struct dentry *dev_d;
|
||||
int ret;
|
||||
|
||||
dev_d = debugfs_create_dir(dev_name(dev), hrde_debugfs_root);
|
||||
if (!dev_d)
|
||||
return -ENOENT;
|
||||
|
||||
qm->debug.debug_root = dev_d;
|
||||
ret = hisi_qm_debug_init(qm);
|
||||
if (ret)
|
||||
goto failed_to_create;
|
||||
|
||||
if (qm->pdev->device == HRDE_PCI_DEVICE_ID) {
|
||||
ret = hisi_rde_ctrl_debug_init(qm);
|
||||
if (ret)
|
||||
goto failed_to_create;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failed_to_create:
|
||||
debugfs_remove_recursive(qm->debug.debug_root);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hisi_rde_debugfs_exit(struct hisi_qm *qm)
|
||||
{
|
||||
debugfs_remove_recursive(qm->debug.debug_root);
|
||||
|
||||
if (qm->fun_type == QM_HW_PF) {
|
||||
hisi_rde_debug_regs_clear(qm);
|
||||
qm->debug.curr_qm_qp_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void hisi_rde_hw_error_log(struct hisi_qm *qm, u32 err_sts)
|
||||
{
|
||||
const struct hisi_rde_hw_error *err = rde_hw_error;
|
||||
struct device *dev = &qm->pdev->dev;
|
||||
u32 err_val;
|
||||
|
||||
while (err->msg) {
|
||||
if (err->int_msk & err_sts)
|
||||
dev_err_ratelimited(dev,
|
||||
"[%s] [Error status=0x%x] found.\n",
|
||||
err->msg, err->int_msk);
|
||||
err++;
|
||||
}
|
||||
|
||||
if (HRDE_ECC_2BIT_ERR & err_sts) {
|
||||
err_val = (readl(qm->io_base + HRDE_ERR_CNT) &
|
||||
HRDE_ECC_2BIT_CNT_MSK);
|
||||
dev_err_ratelimited(dev,
|
||||
"Rde ecc 2bit sram num=0x%x.\n", err_val);
|
||||
}
|
||||
|
||||
if (HRDE_STATE_INT_ERR & err_sts) {
|
||||
err_val = readl(qm->io_base + HRDE_AM_CURR_PORT_STS);
|
||||
dev_err_ratelimited(dev,
|
||||
"Rde ooo cur port sts=0x%x.\n", err_val);
|
||||
err_val = readl(qm->io_base + HRDE_MASTER_TRANS_RET);
|
||||
dev_err_ratelimited(dev,
|
||||
"Rde ooo outstanding sts=0x%x.\n", err_val);
|
||||
}
|
||||
}
|
||||
|
||||
u32 hisi_rde_get_hw_err_status(struct hisi_qm *qm)
|
||||
{
|
||||
return readl(qm->io_base + HRDE_INT_STATUS);
|
||||
}
|
||||
|
||||
void hisi_rde_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
|
||||
{
|
||||
writel(err_sts, qm->io_base + HRDE_INT_SOURCE);
|
||||
}
|
||||
|
||||
static void hisi_rde_open_master_ooo(struct hisi_qm *qm)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(qm->io_base + HRDE_CFG);
|
||||
writel(val & HRDE_AXI_SHUTDOWN_DIS, qm->io_base + HRDE_CFG);
|
||||
writel(val | HRDE_AXI_SHUTDOWN_EN, qm->io_base + HRDE_CFG);
|
||||
}
|
||||
|
||||
static int hisi_rde_pf_probe_init(struct hisi_qm *qm)
|
||||
{
|
||||
struct hisi_rde *hisi_rde = container_of(qm, struct hisi_rde, qm);
|
||||
struct hisi_rde_ctrl *ctrl;
|
||||
int ret;
|
||||
|
||||
ctrl = devm_kzalloc(&qm->pdev->dev, sizeof(*ctrl), GFP_KERNEL);
|
||||
if (!ctrl)
|
||||
return -ENOMEM;
|
||||
|
||||
hisi_rde->ctrl = ctrl;
|
||||
ctrl->hisi_rde = hisi_rde;
|
||||
|
||||
switch (qm->ver) {
|
||||
case QM_HW_V1:
|
||||
qm->ctrl_q_num = HRDE_QUEUE_NUM_V1;
|
||||
break;
|
||||
|
||||
case QM_HW_V2:
|
||||
qm->ctrl_q_num = HRDE_QUEUE_NUM_V2;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qm->err_ini.get_dev_hw_err_status = hisi_rde_get_hw_err_status;
|
||||
qm->err_ini.clear_dev_hw_err_status = hisi_rde_clear_hw_err_status;
|
||||
qm->err_ini.err_info.ecc_2bits_mask = HRDE_ECC_2BIT_ERR;
|
||||
qm->err_ini.err_info.ce = QM_BASE_CE;
|
||||
qm->err_ini.err_info.nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT;
|
||||
qm->err_ini.err_info.fe = 0;
|
||||
qm->err_ini.err_info.msi = 0;
|
||||
qm->err_ini.err_info.acpi_rst = "RRST";
|
||||
qm->err_ini.hw_err_disable = hisi_rde_hw_error_disable;
|
||||
qm->err_ini.hw_err_enable = hisi_rde_hw_error_enable;
|
||||
qm->err_ini.set_usr_domain_cache = hisi_rde_set_user_domain_and_cache;
|
||||
qm->err_ini.log_dev_hw_err = hisi_rde_hw_error_log;
|
||||
qm->err_ini.open_axi_master_ooo = hisi_rde_open_master_ooo;
|
||||
qm->err_ini.err_info.msi_wr_port = HRDE_WR_MSI_PORT;
|
||||
|
||||
ret = qm->err_ini.set_usr_domain_cache(qm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hisi_qm_dev_err_init(qm);
|
||||
qm->err_ini.open_axi_master_ooo(qm);
|
||||
hisi_rde_debug_regs_clear(qm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hisi_rde_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_CRYPTO_QM_UACCE
|
||||
qm->algs = "ec\n";
|
||||
qm->uacce_mode = uacce_mode;
|
||||
#endif
|
||||
|
||||
qm->pdev = pdev;
|
||||
ret = hisi_qm_pre_init(qm, pf_q_num, HRDE_PF_DEF_Q_BASE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
qm->qm_list = &rde_devices;
|
||||
qm->sqe_size = HRDE_SQE_SIZE;
|
||||
qm->dev_name = hisi_rde_name;
|
||||
qm->abnormal_fix = hisi_rde_abnormal_fix;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 hisi_rde_smmu_state(struct device *dev)
|
||||
{
|
||||
struct iommu_domain *domain;
|
||||
|
||||
domain = iommu_get_domain_for_dev(dev);
|
||||
if (domain) {
|
||||
if (domain->type == IOMMU_DOMAIN_DMA)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int hisi_rde_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct hisi_rde *hisi_rde;
|
||||
struct hisi_qm *qm;
|
||||
int ret;
|
||||
|
||||
hisi_rde = devm_kzalloc(&pdev->dev, sizeof(*hisi_rde), GFP_KERNEL);
|
||||
if (!hisi_rde)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_WORK(&hisi_rde->reset_work, hisi_rde_ras_proc);
|
||||
hisi_rde->smmu_state = hisi_rde_smmu_state(&pdev->dev);
|
||||
|
||||
qm = &hisi_rde->qm;
|
||||
qm->fun_type = QM_HW_PF;
|
||||
|
||||
ret = hisi_rde_qm_pre_init(qm, pdev);
|
||||
if (ret) {
|
||||
pci_err(pdev, "Pre init qm failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hisi_qm_init(qm);
|
||||
if (ret) {
|
||||
pci_err(pdev, "Init qm failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hisi_rde_pf_probe_init(qm);
|
||||
if (ret) {
|
||||
pci_err(pdev, "Init pf failed!\n");
|
||||
goto err_qm_uninit;
|
||||
}
|
||||
|
||||
ret = hisi_qm_start(qm);
|
||||
if (ret) {
|
||||
pci_err(pdev, "Start qm failed!\n");
|
||||
goto err_qm_uninit;
|
||||
}
|
||||
|
||||
ret = hisi_rde_debugfs_init(qm);
|
||||
if (ret)
|
||||
pci_warn(pdev, "Init debugfs failed!\n");
|
||||
|
||||
hisi_qm_add_to_list(qm, &rde_devices);
|
||||
|
||||
return 0;
|
||||
|
||||
err_qm_uninit:
|
||||
hisi_qm_uninit(qm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hisi_rde_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct hisi_qm *qm = pci_get_drvdata(pdev);
|
||||
struct hisi_rde *hisi_rde = container_of(qm, struct hisi_rde, qm);
|
||||
|
||||
hisi_qm_remove_wait_delay(qm, &rde_devices);
|
||||
|
||||
qm->abnormal_fix = NULL;
|
||||
hisi_qm_dev_err_uninit(qm);
|
||||
cancel_work_sync(&hisi_rde->reset_work);
|
||||
hisi_qm_del_from_list(qm, &rde_devices);
|
||||
hisi_rde_debugfs_exit(qm);
|
||||
hisi_qm_stop(qm, QM_NORMAL);
|
||||
hisi_qm_uninit(qm);
|
||||
}
|
||||
|
||||
static void hisi_rde_ras_proc(struct work_struct *work)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
struct hisi_rde *hisi_rde;
|
||||
pci_ers_result_t ret;
|
||||
|
||||
hisi_rde = container_of(work, struct hisi_rde, reset_work);
|
||||
pdev = hisi_rde->qm.pdev;
|
||||
if (!pdev)
|
||||
return;
|
||||
|
||||
ret = hisi_qm_process_dev_error(pdev);
|
||||
if (ret == PCI_ERS_RESULT_NEED_RESET)
|
||||
if (hisi_qm_controller_reset(&hisi_rde->qm))
|
||||
dev_err(&pdev->dev, "Hisi_rde reset fail.\n");
|
||||
|
||||
}
|
||||
|
||||
int hisi_rde_abnormal_fix(struct hisi_qm *qm)
|
||||
{
|
||||
struct hisi_rde *hisi_rde;
|
||||
|
||||
if (!qm)
|
||||
return -EINVAL;
|
||||
|
||||
hisi_rde = container_of(qm, struct hisi_rde, qm);
|
||||
|
||||
return schedule_work(&hisi_rde->reset_work);
|
||||
}
|
||||
|
||||
static const struct pci_error_handlers hisi_rde_err_handler = {
|
||||
.reset_prepare = hisi_qm_reset_prepare,
|
||||
.reset_done = hisi_qm_reset_done,
|
||||
};
|
||||
|
||||
static struct pci_driver hisi_rde_pci_driver = {
|
||||
.name = "hisi_rde",
|
||||
.id_table = hisi_rde_dev_ids,
|
||||
.probe = hisi_rde_probe,
|
||||
.remove = hisi_rde_remove,
|
||||
.err_handler = &hisi_rde_err_handler,
|
||||
.shutdown = hisi_qm_dev_shutdown,
|
||||
};
|
||||
|
||||
static void hisi_rde_register_debugfs(void)
|
||||
{
|
||||
if (!debugfs_initialized())
|
||||
return;
|
||||
|
||||
hrde_debugfs_root = debugfs_create_dir("hisi_rde", NULL);
|
||||
if (IS_ERR_OR_NULL(hrde_debugfs_root))
|
||||
hrde_debugfs_root = NULL;
|
||||
}
|
||||
|
||||
static void hisi_rde_unregister_debugfs(void)
|
||||
{
|
||||
debugfs_remove_recursive(hrde_debugfs_root);
|
||||
}
|
||||
|
||||
static int __init hisi_rde_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
INIT_LIST_HEAD(&rde_devices.list);
|
||||
mutex_init(&rde_devices.lock);
|
||||
rde_devices.check = NULL;
|
||||
hisi_rde_register_debugfs();
|
||||
|
||||
ret = pci_register_driver(&hisi_rde_pci_driver);
|
||||
if (ret < 0) {
|
||||
hisi_rde_unregister_debugfs();
|
||||
pr_err("Register pci driver failed.\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit hisi_rde_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&hisi_rde_pci_driver);
|
||||
hisi_rde_unregister_debugfs();
|
||||
}
|
||||
|
||||
module_init(hisi_rde_init);
|
||||
module_exit(hisi_rde_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Yu'an Wang<wangyuan46@huawei.com>");
|
||||
MODULE_DESCRIPTION("Driver for HiSilicon RDE accelerator");
|
||||
MODULE_VERSION("1.3.11");
|
|
@ -0,0 +1,45 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2019 HiSilicon Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RDE_USR_IF_H__
|
||||
#define __RDE_USR_IF_H__
|
||||
|
||||
struct hisi_rde_sqe {
|
||||
__u64 rsvd0: 16;
|
||||
__u64 op_tag: 16;
|
||||
__u64 alg_blk_size: 2;
|
||||
__u64 cm_type: 1;
|
||||
__u64 cm_le: 1;
|
||||
__u64 abort: 1;
|
||||
__u64 src_nblks: 6;
|
||||
__u64 dst_nblks: 5;
|
||||
__u64 chk_dst_ref_ctrl: 4;
|
||||
__u64 chk_dst_grd_ctrl: 4;
|
||||
__u64 op_type: 8;
|
||||
__u64 block_size: 16;
|
||||
__u64 page_pad_type: 2;
|
||||
__u64 dif_type: 1;
|
||||
__u64 rsvd1: 3;
|
||||
__u64 crciv_sel: 1;
|
||||
__u64 crciv_en: 1;
|
||||
__u64 status: 8;
|
||||
__u64 rsvd2: 10;
|
||||
__u64 cm_len: 6;
|
||||
__u64 transfer_size: 16;
|
||||
__u64 coef_matrix_addr;
|
||||
__u64 src_addr;
|
||||
__u64 src_tag_addr;
|
||||
__u64 dst_addr;
|
||||
__u64 dst_tag_addr;
|
||||
__u64 dw7;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_CRYPTO_DEV_HISI_SEC2) += hisi_sec2.o
|
||||
hisi_sec2-objs = sec_main.o sec_crypto.o
|
|
@ -0,0 +1,169 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/* Copyright (c) 2018-2019 HiSilicon Limited. */
|
||||
|
||||
#ifndef __HISI_SEC_V2_H
|
||||
#define __HISI_SEC_V2_H
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
#include "../qm.h"
|
||||
#include "sec_crypto.h"
|
||||
|
||||
/* Algorithm resource per hardware SEC queue */
|
||||
struct sec_alg_res {
|
||||
u8 *pbuf;
|
||||
dma_addr_t pbuf_dma;
|
||||
u8 *c_ivin;
|
||||
dma_addr_t c_ivin_dma;
|
||||
u8 *out_mac;
|
||||
dma_addr_t out_mac_dma;
|
||||
};
|
||||
|
||||
/* Cipher request of SEC private */
|
||||
struct sec_cipher_req {
|
||||
struct hisi_acc_hw_sgl *c_in;
|
||||
dma_addr_t c_in_dma;
|
||||
struct hisi_acc_hw_sgl *c_out;
|
||||
dma_addr_t c_out_dma;
|
||||
u8 *c_ivin;
|
||||
dma_addr_t c_ivin_dma;
|
||||
struct skcipher_request *sk_req;
|
||||
u32 c_len;
|
||||
bool encrypt;
|
||||
};
|
||||
|
||||
/* SEC request of Crypto */
|
||||
struct sec_req {
|
||||
struct sec_sqe sec_sqe;
|
||||
struct sec_ctx *ctx;
|
||||
struct sec_qp_ctx *qp_ctx;
|
||||
|
||||
struct sec_cipher_req c_req;
|
||||
struct list_head backlog_head;
|
||||
|
||||
int err_type;
|
||||
int req_id;
|
||||
|
||||
/* Status of the SEC request */
|
||||
bool fake_busy;
|
||||
bool use_pbuf;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sec_req_op - Operations for SEC request
|
||||
* @buf_map: DMA map the SGL buffers of the request
|
||||
* @buf_unmap: DMA unmap the SGL buffers of the request
|
||||
* @bd_fill: Fill the SEC queue BD
|
||||
* @bd_send: Send the SEC BD into the hardware queue
|
||||
* @callback: Call back for the request
|
||||
* @process: Main processing logic of Skcipher
|
||||
*/
|
||||
struct sec_req_op {
|
||||
int (*buf_map)(struct sec_ctx *ctx, struct sec_req *req);
|
||||
void (*buf_unmap)(struct sec_ctx *ctx, struct sec_req *req);
|
||||
void (*do_transfer)(struct sec_ctx *ctx, struct sec_req *req);
|
||||
int (*bd_fill)(struct sec_ctx *ctx, struct sec_req *req);
|
||||
int (*bd_send)(struct sec_ctx *ctx, struct sec_req *req);
|
||||
void (*callback)(struct sec_ctx *ctx, struct sec_req *req, int err);
|
||||
int (*process)(struct sec_ctx *ctx, struct sec_req *req);
|
||||
};
|
||||
|
||||
/* SEC cipher context which cipher's relatives */
|
||||
struct sec_cipher_ctx {
|
||||
u8 *c_key;
|
||||
dma_addr_t c_key_dma;
|
||||
sector_t iv_offset;
|
||||
u32 c_gran_size;
|
||||
u32 ivsize;
|
||||
u8 c_mode;
|
||||
u8 c_alg;
|
||||
u8 c_key_len;
|
||||
};
|
||||
|
||||
/* SEC queue context which defines queue's relatives */
|
||||
struct sec_qp_ctx {
|
||||
struct hisi_qp *qp;
|
||||
struct sec_req *req_list[QM_Q_DEPTH];
|
||||
struct idr req_idr;
|
||||
struct sec_alg_res res[QM_Q_DEPTH];
|
||||
struct sec_ctx *ctx;
|
||||
struct mutex req_lock;
|
||||
struct list_head backlog;
|
||||
struct hisi_acc_sgl_pool *c_in_pool;
|
||||
struct hisi_acc_sgl_pool *c_out_pool;
|
||||
};
|
||||
|
||||
enum sec_alg_type {
|
||||
SEC_SKCIPHER,
|
||||
SEC_AEAD
|
||||
};
|
||||
|
||||
/* SEC Crypto TFM context which defines queue and cipher .etc relatives */
|
||||
struct sec_ctx {
|
||||
struct sec_qp_ctx *qp_ctx;
|
||||
struct sec_dev *sec;
|
||||
const struct sec_req_op *req_op;
|
||||
struct hisi_qp **qps;
|
||||
|
||||
/* Half queues for encipher, and half for decipher */
|
||||
u32 hlf_q_num;
|
||||
|
||||
/* Threshold for fake busy, trigger to return -EBUSY to user */
|
||||
u32 fake_req_limit;
|
||||
|
||||
/* Currrent cyclic index to select a queue for encipher */
|
||||
atomic_t enc_qcyclic;
|
||||
|
||||
/* Currrent cyclic index to select a queue for decipher */
|
||||
atomic_t dec_qcyclic;
|
||||
|
||||
enum sec_alg_type alg_type;
|
||||
bool pbuf_supported;
|
||||
struct sec_cipher_ctx c_ctx;
|
||||
};
|
||||
|
||||
enum sec_endian {
|
||||
SEC_LE = 0,
|
||||
SEC_32BE,
|
||||
SEC_64BE
|
||||
};
|
||||
|
||||
enum sec_debug_file_index {
|
||||
SEC_CURRENT_QM,
|
||||
SEC_CLEAR_ENABLE,
|
||||
SEC_DEBUG_FILE_NUM,
|
||||
};
|
||||
|
||||
struct sec_debug_file {
|
||||
enum sec_debug_file_index index;
|
||||
spinlock_t lock;
|
||||
struct hisi_qm *qm;
|
||||
};
|
||||
|
||||
struct sec_dfx {
|
||||
atomic64_t send_cnt;
|
||||
atomic64_t recv_cnt;
|
||||
atomic64_t send_busy_cnt;
|
||||
atomic64_t recv_busy_cnt;
|
||||
atomic64_t err_bd_cnt;
|
||||
atomic64_t invalid_req_cnt;
|
||||
atomic64_t done_flag_cnt;
|
||||
};
|
||||
|
||||
struct sec_debug {
|
||||
struct sec_dfx dfx;
|
||||
struct sec_debug_file files[SEC_DEBUG_FILE_NUM];
|
||||
};
|
||||
|
||||
struct sec_dev {
|
||||
struct hisi_qm qm;
|
||||
struct sec_debug debug;
|
||||
u32 ctx_q_num;
|
||||
bool iommu_used;
|
||||
};
|
||||
|
||||
void sec_destroy_qps(struct hisi_qp **qps, int qp_num);
|
||||
struct hisi_qp **sec_create_qps(void);
|
||||
int sec_register_to_crypto(void);
|
||||
void sec_unregister_from_crypto(void);
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,238 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/* Copyright (c) 2018-2019 HiSilicon Limited. */
|
||||
|
||||
#ifndef __HISI_SEC_V2_CRYPTO_H
|
||||
#define __HISI_SEC_V2_CRYPTO_H
|
||||
|
||||
#define SEC_IV_SIZE 24
|
||||
#define SEC_MAX_KEY_SIZE 64
|
||||
#define SEC_MAX_AUTH_KEY_SIZE 64
|
||||
|
||||
#define SEC_COMM_SCENE 0
|
||||
|
||||
enum sec_calg {
|
||||
SEC_CALG_3DES = 0x1,
|
||||
SEC_CALG_AES = 0x2,
|
||||
SEC_CALG_SM4 = 0x3,
|
||||
};
|
||||
|
||||
enum sec_hash_alg {
|
||||
SEC_A_HMAC_SHA1 = 0x10,
|
||||
SEC_A_HMAC_SHA256 = 0x11,
|
||||
SEC_A_HMAC_SHA512 = 0x15,
|
||||
};
|
||||
|
||||
enum sec_mac_len {
|
||||
SEC_HMAC_SHA1_MAC = 20,
|
||||
SEC_HMAC_SHA256_MAC = 32,
|
||||
SEC_HMAC_SHA512_MAC = 64,
|
||||
};
|
||||
|
||||
enum sec_cmode {
|
||||
SEC_CMODE_ECB = 0x0,
|
||||
SEC_CMODE_CBC = 0x1,
|
||||
SEC_CMODE_CTR = 0x4,
|
||||
SEC_CMODE_XTS = 0x7,
|
||||
};
|
||||
|
||||
enum sec_ckey_type {
|
||||
SEC_CKEY_128BIT = 0x0,
|
||||
SEC_CKEY_192BIT = 0x1,
|
||||
SEC_CKEY_256BIT = 0x2,
|
||||
SEC_CKEY_3DES_3KEY = 0x1,
|
||||
SEC_CKEY_3DES_2KEY = 0x3,
|
||||
};
|
||||
|
||||
enum sec_bd_type {
|
||||
SEC_BD_TYPE1 = 0x1,
|
||||
SEC_BD_TYPE2 = 0x2,
|
||||
};
|
||||
|
||||
enum sec_auth {
|
||||
SEC_NO_AUTH = 0x0,
|
||||
SEC_AUTH_TYPE1 = 0x1,
|
||||
SEC_AUTH_TYPE2 = 0x2,
|
||||
};
|
||||
|
||||
enum sec_cipher_dir {
|
||||
SEC_CIPHER_ENC = 0x1,
|
||||
SEC_CIPHER_DEC = 0x2,
|
||||
};
|
||||
|
||||
enum sec_addr_type {
|
||||
SEC_PBUF = 0x0,
|
||||
SEC_SGL = 0x1,
|
||||
SEC_PRP = 0x2,
|
||||
};
|
||||
|
||||
enum sec_ci_gen {
|
||||
SEC_CI_GEN_BY_ADDR = 0x0,
|
||||
SEC_CI_GEN_BY_LBA = 0X3,
|
||||
};
|
||||
|
||||
enum sec_scene {
|
||||
SEC_SCENE_IPSEC = 0x1,
|
||||
SEC_SCENE_STORAGE = 0x5,
|
||||
};
|
||||
|
||||
enum sec_work_mode {
|
||||
SEC_NO_FUSION = 0x0,
|
||||
SEC_IV_FUSION = 0x1,
|
||||
SEC_FUSION_BUTT
|
||||
};
|
||||
|
||||
enum sec_req_ops_type {
|
||||
SEC_OPS_SKCIPHER_ALG = 0x0,
|
||||
SEC_OPS_DMCRYPT = 0x1,
|
||||
SEC_OPS_MULTI_IV = 0x2,
|
||||
SEC_OPS_BUTT
|
||||
};
|
||||
|
||||
struct sec_sqe_type2 {
|
||||
/*
|
||||
* mac_len: 0~4 bits
|
||||
* a_key_len: 5~10 bits
|
||||
* a_alg: 11~16 bits
|
||||
*/
|
||||
__le32 mac_key_alg;
|
||||
|
||||
/*
|
||||
* c_icv_len: 0~5 bits
|
||||
* c_width: 6~8 bits
|
||||
* c_key_len: 9~11 bits
|
||||
* c_mode: 12~15 bits
|
||||
*/
|
||||
__le16 icvw_kmode;
|
||||
|
||||
/* c_alg: 0~3 bits */
|
||||
__u8 c_alg;
|
||||
__u8 rsvd4;
|
||||
|
||||
/*
|
||||
* a_len: 0~23 bits
|
||||
* iv_offset_l: 24~31 bits
|
||||
*/
|
||||
__le32 alen_ivllen;
|
||||
|
||||
/*
|
||||
* c_len: 0~23 bits
|
||||
* iv_offset_h: 24~31 bits
|
||||
*/
|
||||
__le32 clen_ivhlen;
|
||||
|
||||
__le16 auth_src_offset;
|
||||
__le16 cipher_src_offset;
|
||||
__le16 cs_ip_header_offset;
|
||||
__le16 cs_udp_header_offset;
|
||||
__le16 pass_word_len;
|
||||
__le16 dk_len;
|
||||
__u8 salt3;
|
||||
__u8 salt2;
|
||||
__u8 salt1;
|
||||
__u8 salt0;
|
||||
|
||||
__le16 tag;
|
||||
__le16 rsvd5;
|
||||
|
||||
/*
|
||||
* c_pad_type: 0~3 bits
|
||||
* c_pad_len: 4~11 bits
|
||||
* c_pad_data_type: 12~15 bits
|
||||
*/
|
||||
__le16 cph_pad;
|
||||
|
||||
/* c_pad_len_field: 0~1 bits */
|
||||
__le16 c_pad_len_field;
|
||||
|
||||
__le64 long_a_data_len;
|
||||
__le64 a_ivin_addr;
|
||||
__le64 a_key_addr;
|
||||
__le64 mac_addr;
|
||||
__le64 c_ivin_addr;
|
||||
__le64 c_key_addr;
|
||||
|
||||
__le64 data_src_addr;
|
||||
__le64 data_dst_addr;
|
||||
|
||||
/*
|
||||
* done: 0 bit
|
||||
* icv: 1~3 bits
|
||||
* csc: 4~6 bits
|
||||
* flag: 7-10 bits
|
||||
* dif_check: 11~13 bits
|
||||
*/
|
||||
__le16 done_flag;
|
||||
|
||||
__u8 error_type;
|
||||
__u8 warning_type;
|
||||
__u8 mac_i3;
|
||||
__u8 mac_i2;
|
||||
__u8 mac_i1;
|
||||
__u8 mac_i0;
|
||||
__le16 check_sum_i;
|
||||
__u8 tls_pad_len_i;
|
||||
__u8 rsvd12;
|
||||
__le32 counter;
|
||||
};
|
||||
|
||||
struct sec_sqe {
|
||||
/*
|
||||
* type: 0~3 bits
|
||||
* cipher: 4~5 bits
|
||||
* auth: 6~7 bit s
|
||||
*/
|
||||
__u8 type_cipher_auth;
|
||||
|
||||
/*
|
||||
* seq: 0 bit
|
||||
* de: 1~2 bits
|
||||
* scene: 3~6 bits
|
||||
* src_addr_type: ~7 bit, with sdm_addr_type 0-1 bits
|
||||
*/
|
||||
__u8 sds_sa_type;
|
||||
|
||||
/*
|
||||
* src_addr_type: 0~1 bits, not used now,
|
||||
* if support PRP, set this field, or set zero.
|
||||
* dst_addr_type: 2~4 bits
|
||||
* mac_addr_type: 5~7 bits
|
||||
*/
|
||||
__u8 sdm_addr_type;
|
||||
__u8 rsvd0;
|
||||
|
||||
/*
|
||||
* nonce_len(type2): 0~3 bits
|
||||
* huk(type2): 4 bit
|
||||
* key_s(type2): 5 bit
|
||||
* ci_gen: 6~7 bits
|
||||
*/
|
||||
__u8 huk_key_ci;
|
||||
|
||||
/*
|
||||
* ai_gen: 0~1 bits
|
||||
* a_pad(type2): 2~3 bits
|
||||
* c_s(type2): 4~5 bits
|
||||
*/
|
||||
__u8 ai_apd_cs;
|
||||
|
||||
/*
|
||||
* rhf(type2): 0 bit
|
||||
* c_key_type: 1~2 bits
|
||||
* a_key_type: 3~4 bits
|
||||
* write_frame_len(type2): 5~7 bits
|
||||
*/
|
||||
__u8 rca_key_frm;
|
||||
|
||||
/*
|
||||
* cal_iv_addr_en(type2): 0 bit
|
||||
* tls_up(type2): 1 bit
|
||||
* inveld: 7 bit
|
||||
*/
|
||||
__u8 iv_tls_ld;
|
||||
|
||||
struct sec_sqe_type2 type2;
|
||||
};
|
||||
|
||||
int sec_register_to_crypto(void);
|
||||
void sec_unregister_from_crypto(void);
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,272 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2019 HiSilicon Limited. */
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include "qm.h"
|
||||
|
||||
#define HISI_ACC_SGL_SGE_NR_MIN 1
|
||||
#define HISI_ACC_SGL_NR_MAX 256
|
||||
#define HISI_ACC_SGL_ALIGN_SIZE 64
|
||||
#define HISI_ACC_MEM_BLOCK_NR 5
|
||||
|
||||
struct acc_hw_sge {
|
||||
dma_addr_t buf;
|
||||
void *page_ctrl;
|
||||
__le32 len;
|
||||
__le32 pad;
|
||||
__le32 pad0;
|
||||
__le32 pad1;
|
||||
};
|
||||
|
||||
/* use default sgl head size 64B */
|
||||
struct hisi_acc_hw_sgl {
|
||||
dma_addr_t next_dma;
|
||||
__le16 entry_sum_in_chain;
|
||||
__le16 entry_sum_in_sgl;
|
||||
__le16 entry_length_in_sgl;
|
||||
__le16 pad0;
|
||||
__le64 pad1[5];
|
||||
struct hisi_acc_hw_sgl *next;
|
||||
struct acc_hw_sge sge_entries[];
|
||||
} __aligned(1);
|
||||
|
||||
struct hisi_acc_sgl_pool {
|
||||
struct mem_block {
|
||||
struct hisi_acc_hw_sgl *sgl;
|
||||
dma_addr_t sgl_dma;
|
||||
size_t size;
|
||||
} mem_block[HISI_ACC_MEM_BLOCK_NR];
|
||||
u32 sgl_num_per_block;
|
||||
u32 block_num;
|
||||
u32 count;
|
||||
u32 sge_nr;
|
||||
size_t sgl_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* hisi_acc_create_sgl_pool() - Create a hw sgl pool.
|
||||
* @dev: The device which hw sgl pool belongs to.
|
||||
* @count: Count of hisi_acc_hw_sgl in pool.
|
||||
* @sge_nr: The count of sge in hw_sgl
|
||||
*
|
||||
* This function creates a hw sgl pool, after this user can get hw sgl memory
|
||||
* from it.
|
||||
*/
|
||||
struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
|
||||
u32 count, u32 sge_nr)
|
||||
{
|
||||
u32 sgl_size, block_size, sgl_num_per_block, block_num, remain_sgl;
|
||||
struct hisi_acc_sgl_pool *pool;
|
||||
struct mem_block *block;
|
||||
u32 i, j;
|
||||
|
||||
if (!dev || !count || !sge_nr || sge_nr > HISI_ACC_SGL_SGE_NR_MAX)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
sgl_size = sizeof(struct acc_hw_sge) * sge_nr +
|
||||
sizeof(struct hisi_acc_hw_sgl);
|
||||
block_size = PAGE_SIZE * (1 << (MAX_ORDER - 1));
|
||||
sgl_num_per_block = block_size / sgl_size;
|
||||
block_num = count / sgl_num_per_block;
|
||||
remain_sgl = count % sgl_num_per_block;
|
||||
|
||||
if ((!remain_sgl && block_num > HISI_ACC_MEM_BLOCK_NR) ||
|
||||
(remain_sgl > 0 && block_num > HISI_ACC_MEM_BLOCK_NR - 1))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
pool = kzalloc(sizeof(*pool), GFP_KERNEL);
|
||||
if (!pool)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
block = pool->mem_block;
|
||||
|
||||
for (i = 0; i < block_num; i++) {
|
||||
block[i].sgl = dma_alloc_coherent(dev, block_size,
|
||||
&block[i].sgl_dma,
|
||||
GFP_KERNEL);
|
||||
if (!block[i].sgl) {
|
||||
dev_err(dev, "Fail to allocate hw SG buffer!\n");
|
||||
goto err_free_mem;
|
||||
}
|
||||
|
||||
block[i].size = block_size;
|
||||
}
|
||||
|
||||
if (remain_sgl > 0) {
|
||||
block[i].sgl = dma_alloc_coherent(dev, remain_sgl * sgl_size,
|
||||
&block[i].sgl_dma,
|
||||
GFP_KERNEL);
|
||||
if (!block[i].sgl) {
|
||||
dev_err(dev, "Fail to allocate remained hw SG buffer!\n");
|
||||
goto err_free_mem;
|
||||
}
|
||||
|
||||
block[i].size = remain_sgl * sgl_size;
|
||||
}
|
||||
|
||||
pool->sgl_num_per_block = sgl_num_per_block;
|
||||
pool->block_num = remain_sgl ? block_num + 1 : block_num;
|
||||
pool->count = count;
|
||||
pool->sgl_size = sgl_size;
|
||||
pool->sge_nr = sge_nr;
|
||||
|
||||
return pool;
|
||||
|
||||
err_free_mem:
|
||||
for (j = 0; j < i; j++) {
|
||||
dma_free_coherent(dev, block_size, block[j].sgl,
|
||||
block[j].sgl_dma);
|
||||
memset(block + j, 0, sizeof(*block));
|
||||
}
|
||||
kfree(pool);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_acc_create_sgl_pool);
|
||||
|
||||
/**
|
||||
* hisi_acc_free_sgl_pool() - Free a hw sgl pool.
|
||||
* @dev: The device which hw sgl pool belongs to.
|
||||
* @pool: Pointer of pool.
|
||||
*
|
||||
* This function frees memory of a hw sgl pool.
|
||||
*/
|
||||
void hisi_acc_free_sgl_pool(struct device *dev, struct hisi_acc_sgl_pool *pool)
|
||||
{
|
||||
struct mem_block *block;
|
||||
int i;
|
||||
|
||||
if (!dev || !pool)
|
||||
return;
|
||||
|
||||
block = pool->mem_block;
|
||||
|
||||
for (i = 0; i < pool->block_num; i++)
|
||||
dma_free_coherent(dev, block[i].size, block[i].sgl,
|
||||
block[i].sgl_dma);
|
||||
|
||||
kfree(pool);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_acc_free_sgl_pool);
|
||||
|
||||
static struct hisi_acc_hw_sgl *acc_get_sgl(struct hisi_acc_sgl_pool *pool,
|
||||
u32 index, dma_addr_t *hw_sgl_dma)
|
||||
{
|
||||
struct mem_block *block;
|
||||
u32 block_index, offset;
|
||||
|
||||
if (!pool || !hw_sgl_dma || index >= pool->count)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
block = pool->mem_block;
|
||||
block_index = index / pool->sgl_num_per_block;
|
||||
offset = index % pool->sgl_num_per_block;
|
||||
|
||||
*hw_sgl_dma = block[block_index].sgl_dma + pool->sgl_size * offset;
|
||||
return (void *)block[block_index].sgl + pool->sgl_size * offset;
|
||||
}
|
||||
|
||||
static void sg_map_to_hw_sg(struct scatterlist *sgl,
|
||||
struct acc_hw_sge *hw_sge)
|
||||
{
|
||||
hw_sge->buf = sg_dma_address(sgl);
|
||||
hw_sge->len = cpu_to_le32(sg_dma_len(sgl));
|
||||
}
|
||||
|
||||
static void inc_hw_sgl_sge(struct hisi_acc_hw_sgl *hw_sgl)
|
||||
{
|
||||
u16 var = le16_to_cpu(hw_sgl->entry_sum_in_sgl);
|
||||
|
||||
var++;
|
||||
hw_sgl->entry_sum_in_sgl = cpu_to_le16(var);
|
||||
}
|
||||
|
||||
static void update_hw_sgl_sum_sge(struct hisi_acc_hw_sgl *hw_sgl, u16 sum)
|
||||
{
|
||||
hw_sgl->entry_sum_in_chain = cpu_to_le16(sum);
|
||||
}
|
||||
|
||||
/**
|
||||
* hisi_acc_sg_buf_map_to_hw_sgl - Map a scatterlist to a hw sgl.
|
||||
* @dev: The device which hw sgl belongs to.
|
||||
* @sgl: Scatterlist which will be mapped to hw sgl.
|
||||
* @pool: Pool which hw sgl memory will be allocated in.
|
||||
* @index: Index of hisi_acc_hw_sgl in pool.
|
||||
* @hw_sgl_dma: The dma address of allocated hw sgl.
|
||||
*
|
||||
* This function builds hw sgl according input sgl, user can use hw_sgl_dma
|
||||
* as src/dst in its BD. Only support single hw sgl currently.
|
||||
*/
|
||||
struct hisi_acc_hw_sgl *
|
||||
hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,
|
||||
struct scatterlist *sgl,
|
||||
struct hisi_acc_sgl_pool *pool,
|
||||
u32 index, dma_addr_t *hw_sgl_dma)
|
||||
{
|
||||
struct hisi_acc_hw_sgl *curr_hw_sgl;
|
||||
dma_addr_t curr_sgl_dma = 0;
|
||||
struct acc_hw_sge *curr_hw_sge;
|
||||
struct scatterlist *sg;
|
||||
int i, sg_n, sg_n_mapped;
|
||||
|
||||
if (!dev || !sgl || !pool || !hw_sgl_dma)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
sg_n = sg_nents(sgl);
|
||||
|
||||
sg_n_mapped = dma_map_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
|
||||
if (!sg_n_mapped) {
|
||||
dev_err(dev, "DMA mapping for SG error!\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (sg_n_mapped > pool->sge_nr) {
|
||||
dev_err(dev, "the number of entries in input scatterlist is bigger than SGL pool setting.\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
curr_hw_sgl = acc_get_sgl(pool, index, &curr_sgl_dma);
|
||||
if (IS_ERR(curr_hw_sgl)) {
|
||||
dev_err(dev, "Get SGL error!\n");
|
||||
dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
curr_hw_sgl->entry_length_in_sgl = cpu_to_le16(pool->sge_nr);
|
||||
curr_hw_sge = curr_hw_sgl->sge_entries;
|
||||
|
||||
for_each_sg(sgl, sg, sg_n_mapped, i) {
|
||||
sg_map_to_hw_sg(sg, curr_hw_sge);
|
||||
inc_hw_sgl_sge(curr_hw_sgl);
|
||||
curr_hw_sge++;
|
||||
}
|
||||
|
||||
update_hw_sgl_sum_sge(curr_hw_sgl, pool->sge_nr);
|
||||
*hw_sgl_dma = curr_sgl_dma;
|
||||
|
||||
return curr_hw_sgl;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_acc_sg_buf_map_to_hw_sgl);
|
||||
|
||||
/**
|
||||
* hisi_acc_sg_buf_unmap() - Unmap allocated hw sgl.
|
||||
* @dev: The device which hw sgl belongs to.
|
||||
* @sgl: Related scatterlist.
|
||||
* @hw_sgl: Virtual address of hw sgl.
|
||||
* @hw_sgl_dma: DMA address of hw sgl.
|
||||
* @pool: Pool which hw sgl is allocated in.
|
||||
*
|
||||
* This function unmaps allocated hw sgl.
|
||||
*/
|
||||
void hisi_acc_sg_buf_unmap(struct device *dev, struct scatterlist *sgl,
|
||||
struct hisi_acc_hw_sgl *hw_sgl)
|
||||
{
|
||||
if (!dev || !sgl || !hw_sgl)
|
||||
return;
|
||||
|
||||
dma_unmap_sg(dev, sgl, sg_nents(sgl), DMA_BIDIRECTIONAL);
|
||||
|
||||
hw_sgl->entry_sum_in_chain = 0;
|
||||
hw_sgl->entry_sum_in_sgl = 0;
|
||||
hw_sgl->entry_length_in_sgl = 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_acc_sg_buf_unmap);
|
||||
MODULE_VERSION("1.3.11");
|
|
@ -0,0 +1,37 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/* Copyright (c) 2019 HiSilicon Limited. */
|
||||
|
||||
#ifndef HISI_ZIP_H
|
||||
#define HISI_ZIP_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include "../qm.h"
|
||||
#include "zip_usr_if.h"
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "hisi_zip: " fmt
|
||||
#define ZIP_WAIT_DELAY 1000
|
||||
|
||||
enum hisi_zip_error_type {
|
||||
/* negative compression */
|
||||
HZIP_NC_ERR = 0x0d,
|
||||
};
|
||||
|
||||
struct zip_dfx {
|
||||
atomic64_t send_cnt;
|
||||
atomic64_t recv_cnt;
|
||||
atomic64_t send_busy_cnt;
|
||||
atomic64_t err_bd_cnt;
|
||||
};
|
||||
|
||||
struct hisi_zip_ctrl;
|
||||
struct hisi_zip {
|
||||
struct hisi_qm qm;
|
||||
struct hisi_zip_ctrl *ctrl;
|
||||
struct zip_dfx dfx;
|
||||
};
|
||||
|
||||
int zip_create_qps(struct hisi_qp **qps, int ctx_num);
|
||||
int hisi_zip_register_to_crypto(void);
|
||||
void hisi_zip_unregister_from_crypto(void);
|
||||
#endif
|
|
@ -6,8 +6,19 @@
|
|||
#include <linux/scatterlist.h>
|
||||
#include "zip.h"
|
||||
|
||||
#define HZIP_ZLIB_HEAD_SIZE 2
|
||||
#define HZIP_GZIP_HEAD_SIZE 10
|
||||
/* hisi_zip_sqe dw3 */
|
||||
#define HZIP_BD_STATUS_M GENMASK(7, 0)
|
||||
/* hisi_zip_sqe dw7 */
|
||||
#define HZIP_IN_SGE_DATA_OFFSET_M GENMASK(23, 0)
|
||||
/* hisi_zip_sqe dw8 */
|
||||
#define HZIP_OUT_SGE_DATA_OFFSET_M GENMASK(23, 0)
|
||||
/* hisi_zip_sqe dw9 */
|
||||
#define HZIP_REQ_TYPE_M GENMASK(7, 0)
|
||||
#define HZIP_ALG_TYPE_ZLIB 0x02
|
||||
#define HZIP_ALG_TYPE_GZIP 0x03
|
||||
#define HZIP_BUF_TYPE_M GENMASK(11, 8)
|
||||
#define HZIP_PBUFFER 0x0
|
||||
#define HZIP_SGL 0x1
|
||||
|
||||
#define GZIP_HEAD_FHCRC_BIT BIT(1)
|
||||
#define GZIP_HEAD_FEXTRA_BIT BIT(2)
|
||||
|
@ -16,21 +27,32 @@
|
|||
|
||||
#define GZIP_HEAD_FLG_SHIFT 3
|
||||
#define GZIP_HEAD_FEXTRA_SHIFT 10
|
||||
#define GZIP_HEAD_FEXTRA_XLEN 2
|
||||
#define GZIP_HEAD_FEXTRA_XLEN 2UL
|
||||
#define GZIP_HEAD_FHCRC_SIZE 2
|
||||
|
||||
#define HZIP_CTX_Q_NUM 2
|
||||
#define HZIP_ZLIB_HEAD_SIZE 2
|
||||
#define HZIP_GZIP_HEAD_SIZE 10
|
||||
#define HZIP_GZIP_HEAD_BUF 256
|
||||
#define HZIP_ALG_PRIORITY 300
|
||||
|
||||
#define HZIP_SGL_SGE_NR 10
|
||||
#define HZIP_SGL_SGE_MAX 255
|
||||
|
||||
static const u8 zlib_head[HZIP_ZLIB_HEAD_SIZE] = {0x78, 0x9c};
|
||||
static const u8 gzip_head[HZIP_GZIP_HEAD_SIZE] = {0x1f, 0x8b, 0x08, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x03};
|
||||
static const u8 gzip_head[HZIP_GZIP_HEAD_SIZE] = {
|
||||
0x1f, 0x8b, 0x08, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x03
|
||||
};
|
||||
enum hisi_zip_alg_type {
|
||||
HZIP_ALG_TYPE_COMP = 0,
|
||||
HZIP_ALG_TYPE_DECOMP = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
QPC_COMP,
|
||||
QPC_DECOMP,
|
||||
HZIP_CTX_Q_NUM
|
||||
};
|
||||
|
||||
#define COMP_NAME_TO_TYPE(alg_name) \
|
||||
(!strcmp((alg_name), "zlib-deflate") ? HZIP_ALG_TYPE_ZLIB : \
|
||||
!strcmp((alg_name), "gzip") ? HZIP_ALG_TYPE_GZIP : 0) \
|
||||
|
@ -41,17 +63,17 @@ enum hisi_zip_alg_type {
|
|||
|
||||
#define TO_HEAD(req_type) \
|
||||
(((req_type) == HZIP_ALG_TYPE_ZLIB) ? zlib_head : \
|
||||
((req_type) == HZIP_ALG_TYPE_GZIP) ? gzip_head : 0) \
|
||||
((req_type) == HZIP_ALG_TYPE_GZIP) ? gzip_head : NULL) \
|
||||
|
||||
struct hisi_zip_req {
|
||||
struct acomp_req *req;
|
||||
int sskip;
|
||||
int dskip;
|
||||
u32 sskip;
|
||||
u32 dskip;
|
||||
struct hisi_acc_hw_sgl *hw_src;
|
||||
struct hisi_acc_hw_sgl *hw_dst;
|
||||
dma_addr_t dma_src;
|
||||
dma_addr_t dma_dst;
|
||||
int req_id;
|
||||
u16 req_id;
|
||||
};
|
||||
|
||||
struct hisi_zip_req_q {
|
||||
|
@ -65,17 +87,41 @@ struct hisi_zip_qp_ctx {
|
|||
struct hisi_qp *qp;
|
||||
struct hisi_zip_sqe zip_sqe;
|
||||
struct hisi_zip_req_q req_q;
|
||||
struct hisi_acc_sgl_pool sgl_pool;
|
||||
struct hisi_acc_sgl_pool *sgl_pool;
|
||||
struct hisi_zip *zip_dev;
|
||||
struct hisi_zip_ctx *ctx;
|
||||
};
|
||||
|
||||
struct hisi_zip_ctx {
|
||||
#define QPC_COMP 0
|
||||
#define QPC_DECOMP 1
|
||||
struct hisi_zip_qp_ctx qp_ctx[HZIP_CTX_Q_NUM];
|
||||
};
|
||||
|
||||
static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
int ret;
|
||||
u16 n;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
ret = kstrtou16(val, 10, &n);
|
||||
if (ret || n == 0 || n > HZIP_SGL_SGE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
return param_set_int(val, kp);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops sgl_sge_nr_ops = {
|
||||
.set = sgl_sge_nr_set,
|
||||
.get = param_get_int,
|
||||
};
|
||||
|
||||
static u16 sgl_sge_nr = HZIP_SGL_SGE_NR;
|
||||
module_param_cb(sgl_sge_nr, &sgl_sge_nr_ops, &sgl_sge_nr, 0444);
|
||||
MODULE_PARM_DESC(sgl_sge_nr, "Number of sge in sgl(1-255)");
|
||||
static DEFINE_MUTEX(hisi_zip_alg_lock);
|
||||
static unsigned int hisi_zip_active_devs;
|
||||
|
||||
static void hisi_zip_config_buf_type(struct hisi_zip_sqe *sqe, u8 buf_type)
|
||||
{
|
||||
u32 val;
|
||||
|
@ -92,7 +138,7 @@ static void hisi_zip_config_tag(struct hisi_zip_sqe *sqe, u32 tag)
|
|||
|
||||
static void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type,
|
||||
dma_addr_t s_addr, dma_addr_t d_addr, u32 slen,
|
||||
u32 dlen, int sskip, int dskip)
|
||||
u32 dlen, u32 sskip, u32 dskip)
|
||||
{
|
||||
memset(sqe, 0, sizeof(struct hisi_zip_sqe));
|
||||
|
||||
|
@ -107,29 +153,24 @@ static void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type,
|
|||
sqe->dest_addr_h = upper_32_bits(d_addr);
|
||||
}
|
||||
|
||||
static int hisi_zip_create_qp(struct hisi_qm *qm, struct hisi_zip_qp_ctx *ctx,
|
||||
static int hisi_zip_start_qp(struct hisi_qp *qp, struct hisi_zip_qp_ctx *ctx,
|
||||
int alg_type, int req_type)
|
||||
{
|
||||
struct hisi_qp *qp;
|
||||
struct device *dev = &qp->qm->pdev->dev;
|
||||
int ret;
|
||||
|
||||
qp = hisi_qm_create_qp(qm, alg_type);
|
||||
if (IS_ERR(qp))
|
||||
return PTR_ERR(qp);
|
||||
|
||||
qp->req_type = req_type;
|
||||
qp->alg_type = alg_type;
|
||||
qp->qp_ctx = ctx;
|
||||
ctx->qp = qp;
|
||||
|
||||
ret = hisi_qm_start_qp(qp, 0);
|
||||
if (ret < 0)
|
||||
goto err_release_qp;
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "start qp failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx->qp = qp;
|
||||
return 0;
|
||||
|
||||
err_release_qp:
|
||||
hisi_qm_release_qp(qp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hisi_zip_release_qp(struct hisi_zip_qp_ctx *ctx)
|
||||
|
@ -140,34 +181,34 @@ static void hisi_zip_release_qp(struct hisi_zip_qp_ctx *ctx)
|
|||
|
||||
static int hisi_zip_ctx_init(struct hisi_zip_ctx *hisi_zip_ctx, u8 req_type)
|
||||
{
|
||||
struct hisi_qp *qps[HZIP_CTX_Q_NUM] = { NULL };
|
||||
struct hisi_zip *hisi_zip;
|
||||
struct hisi_qm *qm;
|
||||
int ret, i, j;
|
||||
|
||||
/* find the proper zip device */
|
||||
hisi_zip = find_zip_device(cpu_to_node(smp_processor_id()));
|
||||
if (!hisi_zip) {
|
||||
pr_err("Failed to find a proper ZIP device!\n");
|
||||
ret = zip_create_qps(qps, HZIP_CTX_Q_NUM);
|
||||
if (ret) {
|
||||
pr_err("Can not create zip qps!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
qm = &hisi_zip->qm;
|
||||
|
||||
hisi_zip = container_of(qps[0]->qm, struct hisi_zip, qm);
|
||||
|
||||
for (i = 0; i < HZIP_CTX_Q_NUM; i++) {
|
||||
/* alg_type = 0 for compress, 1 for decompress in hw sqe */
|
||||
ret = hisi_zip_create_qp(qm, &hisi_zip_ctx->qp_ctx[i], i,
|
||||
ret = hisi_zip_start_qp(qps[i], &hisi_zip_ctx->qp_ctx[i], i,
|
||||
req_type);
|
||||
if (ret)
|
||||
goto err;
|
||||
if (ret) {
|
||||
for (j = i - 1; j >= 0; j--)
|
||||
hisi_qm_stop_qp(hisi_zip_ctx->qp_ctx[j].qp);
|
||||
|
||||
hisi_qm_free_qps(qps, HZIP_CTX_Q_NUM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
hisi_zip_ctx->qp_ctx[i].zip_dev = hisi_zip;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
for (j = i - 1; j >= 0; j--)
|
||||
hisi_zip_release_qp(&hisi_zip_ctx->qp_ctx[j]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hisi_zip_ctx_exit(struct hisi_zip_ctx *hisi_zip_ctx)
|
||||
|
@ -265,14 +306,15 @@ static void hisi_zip_release_req_q(struct hisi_zip_ctx *ctx)
|
|||
static int hisi_zip_create_sgl_pool(struct hisi_zip_ctx *ctx)
|
||||
{
|
||||
struct hisi_zip_qp_ctx *tmp;
|
||||
int i, ret;
|
||||
struct device *dev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HZIP_CTX_Q_NUM; i++) {
|
||||
tmp = &ctx->qp_ctx[i];
|
||||
ret = hisi_acc_create_sgl_pool(&tmp->qp->qm->pdev->dev,
|
||||
&tmp->sgl_pool,
|
||||
QM_Q_DEPTH << 1);
|
||||
if (ret < 0) {
|
||||
dev = &tmp->qp->qm->pdev->dev;
|
||||
tmp->sgl_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH << 1,
|
||||
sgl_sge_nr);
|
||||
if (IS_ERR(tmp->sgl_pool)) {
|
||||
if (i == 1)
|
||||
goto err_free_sgl_pool0;
|
||||
return -ENOMEM;
|
||||
|
@ -283,7 +325,7 @@ static int hisi_zip_create_sgl_pool(struct hisi_zip_ctx *ctx)
|
|||
|
||||
err_free_sgl_pool0:
|
||||
hisi_acc_free_sgl_pool(&ctx->qp_ctx[QPC_COMP].qp->qm->pdev->dev,
|
||||
&ctx->qp_ctx[QPC_COMP].sgl_pool);
|
||||
ctx->qp_ctx[QPC_COMP].sgl_pool);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -293,7 +335,7 @@ static void hisi_zip_release_sgl_pool(struct hisi_zip_ctx *ctx)
|
|||
|
||||
for (i = 0; i < HZIP_CTX_Q_NUM; i++)
|
||||
hisi_acc_free_sgl_pool(&ctx->qp_ctx[i].qp->qm->pdev->dev,
|
||||
&ctx->qp_ctx[i].sgl_pool);
|
||||
ctx->qp_ctx[i].sgl_pool);
|
||||
}
|
||||
|
||||
static void hisi_zip_remove_req(struct hisi_zip_qp_ctx *qp_ctx,
|
||||
|
@ -311,6 +353,7 @@ static void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data)
|
|||
{
|
||||
struct hisi_zip_sqe *sqe = data;
|
||||
struct hisi_zip_qp_ctx *qp_ctx = qp->qp_ctx;
|
||||
struct zip_dfx *dfx = &qp_ctx->zip_dev->dfx;
|
||||
struct hisi_zip_req_q *req_q = &qp_ctx->req_q;
|
||||
struct hisi_zip_req *req = req_q->q + sqe->tag;
|
||||
struct acomp_req *acomp_req = req->req;
|
||||
|
@ -318,12 +361,13 @@ static void hisi_zip_acomp_cb(struct hisi_qp *qp, void *data)
|
|||
u32 status, dlen, head_size;
|
||||
int err = 0;
|
||||
|
||||
atomic64_inc(&dfx->recv_cnt);
|
||||
status = sqe->dw3 & HZIP_BD_STATUS_M;
|
||||
|
||||
if (status != 0 && status != HZIP_NC_ERR) {
|
||||
dev_err(dev, "%scompress fail in qp%u: %u, output: %u\n",
|
||||
(qp->alg_type == 0) ? "" : "de", qp->qp_id, status,
|
||||
sqe->produced);
|
||||
atomic64_inc(&dfx->err_bd_cnt);
|
||||
err = -EIO;
|
||||
}
|
||||
dlen = sqe->produced;
|
||||
|
@ -353,19 +397,27 @@ static int hisi_zip_acomp_init(struct crypto_acomp *tfm)
|
|||
{
|
||||
const char *alg_name = crypto_tfm_alg_name(&tfm->base);
|
||||
struct hisi_zip_ctx *ctx = crypto_tfm_ctx(&tfm->base);
|
||||
struct device *dev;
|
||||
int ret;
|
||||
|
||||
ret = hisi_zip_ctx_init(ctx, COMP_NAME_TO_TYPE(alg_name));
|
||||
if (ret)
|
||||
if (ret) {
|
||||
pr_err("Init ctx failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev = &ctx->qp_ctx[0].qp->qm->pdev->dev;
|
||||
ret = hisi_zip_create_req_q(ctx);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "Create request queue failed!\n ");
|
||||
goto err_ctx_exit;
|
||||
}
|
||||
|
||||
ret = hisi_zip_create_sgl_pool(ctx);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(dev, "Create sgl pool failed!\n ");
|
||||
goto err_release_req_q;
|
||||
}
|
||||
|
||||
hisi_zip_set_acomp_cb(ctx, hisi_zip_acomp_cb);
|
||||
|
||||
|
@ -395,13 +447,15 @@ static int add_comp_head(struct scatterlist *dst, u8 req_type)
|
|||
int ret;
|
||||
|
||||
ret = sg_copy_from_buffer(dst, sg_nents(dst), head, head_size);
|
||||
if (ret != head_size)
|
||||
if (ret != head_size) {
|
||||
pr_err("The head size of buffer is wrong!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return head_size;
|
||||
}
|
||||
|
||||
static size_t get_gzip_head_size(struct scatterlist *sgl)
|
||||
static size_t __maybe_unused get_gzip_head_size(struct scatterlist *sgl)
|
||||
{
|
||||
char buf[HZIP_GZIP_HEAD_BUF];
|
||||
|
||||
|
@ -410,13 +464,20 @@ static size_t get_gzip_head_size(struct scatterlist *sgl)
|
|||
return __get_gzip_head_size(buf);
|
||||
}
|
||||
|
||||
static size_t get_comp_head_size(struct scatterlist *src, u8 req_type)
|
||||
static int get_comp_head_size(struct acomp_req *acomp_req, u8 req_type)
|
||||
{
|
||||
if (!acomp_req->src || !acomp_req->slen)
|
||||
return -EINVAL;
|
||||
|
||||
if ((req_type == HZIP_ALG_TYPE_GZIP) &&
|
||||
(acomp_req->slen < GZIP_HEAD_FEXTRA_SHIFT))
|
||||
return -EINVAL;
|
||||
|
||||
switch (req_type) {
|
||||
case HZIP_ALG_TYPE_ZLIB:
|
||||
return TO_HEAD_SIZE(HZIP_ALG_TYPE_ZLIB);
|
||||
case HZIP_ALG_TYPE_GZIP:
|
||||
return get_gzip_head_size(src);
|
||||
return TO_HEAD_SIZE(HZIP_ALG_TYPE_GZIP);
|
||||
default:
|
||||
pr_err("request type does not support!\n");
|
||||
return -EINVAL;
|
||||
|
@ -438,7 +499,7 @@ static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req,
|
|||
if (req_id >= req_q->size) {
|
||||
write_unlock(&req_q->req_lock);
|
||||
dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n");
|
||||
return ERR_PTR(-EBUSY);
|
||||
return ERR_PTR(-EPERM);
|
||||
}
|
||||
set_bit(req_id, req_q->req_bitmap);
|
||||
|
||||
|
@ -466,7 +527,8 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
|
|||
struct acomp_req *a_req = req->req;
|
||||
struct hisi_qp *qp = qp_ctx->qp;
|
||||
struct device *dev = &qp->qm->pdev->dev;
|
||||
struct hisi_acc_sgl_pool *pool = &qp_ctx->sgl_pool;
|
||||
struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool;
|
||||
struct zip_dfx *dfx = &qp_ctx->zip_dev->dfx;
|
||||
dma_addr_t input;
|
||||
dma_addr_t output;
|
||||
int ret;
|
||||
|
@ -476,14 +538,17 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
|
|||
|
||||
req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->src, pool,
|
||||
req->req_id << 1, &input);
|
||||
if (IS_ERR(req->hw_src))
|
||||
if (IS_ERR(req->hw_src)) {
|
||||
dev_err(dev, "the src map to hw SGL failed!\n");
|
||||
return PTR_ERR(req->hw_src);
|
||||
}
|
||||
req->dma_src = input;
|
||||
|
||||
req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->dst, pool,
|
||||
(req->req_id << 1) + 1,
|
||||
&output);
|
||||
if (IS_ERR(req->hw_dst)) {
|
||||
dev_err(dev, "the dst map to hw SGL failed!\n");
|
||||
ret = PTR_ERR(req->hw_dst);
|
||||
goto err_unmap_input;
|
||||
}
|
||||
|
@ -495,9 +560,14 @@ static int hisi_zip_do_work(struct hisi_zip_req *req,
|
|||
hisi_zip_config_tag(zip_sqe, req->req_id);
|
||||
|
||||
/* send command to start a task */
|
||||
atomic64_inc(&dfx->send_cnt);
|
||||
ret = hisi_qp_send(qp, zip_sqe);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
atomic64_inc(&dfx->send_busy_cnt);
|
||||
ret = -EPERM;
|
||||
dev_dbg_ratelimited(dev, "send task message failed!\n");
|
||||
goto err_unmap_output;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
|
||||
|
@ -512,6 +582,7 @@ static int hisi_zip_acompress(struct acomp_req *acomp_req)
|
|||
{
|
||||
struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm);
|
||||
struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[QPC_COMP];
|
||||
struct device *dev = &qp_ctx->qp->qm->pdev->dev;
|
||||
struct hisi_zip_req *req;
|
||||
int head_size;
|
||||
int ret;
|
||||
|
@ -521,13 +592,17 @@ static int hisi_zip_acompress(struct acomp_req *acomp_req)
|
|||
if (head_size < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
req = hisi_zip_create_req(acomp_req, qp_ctx, (size_t)head_size, true);
|
||||
if (IS_ERR(req))
|
||||
req = hisi_zip_create_req(acomp_req, qp_ctx, head_size, true);
|
||||
if (IS_ERR(req)) {
|
||||
dev_err_ratelimited(dev, "create request before compress failed!\n");
|
||||
return PTR_ERR(req);
|
||||
}
|
||||
|
||||
ret = hisi_zip_do_work(req, qp_ctx);
|
||||
if (ret != -EINPROGRESS)
|
||||
if (ret != -EINPROGRESS) {
|
||||
dev_err_ratelimited(dev, "do compress work failed!\n");
|
||||
hisi_zip_remove_req(qp_ctx, req);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -536,19 +611,26 @@ static int hisi_zip_adecompress(struct acomp_req *acomp_req)
|
|||
{
|
||||
struct hisi_zip_ctx *ctx = crypto_tfm_ctx(acomp_req->base.tfm);
|
||||
struct hisi_zip_qp_ctx *qp_ctx = &ctx->qp_ctx[QPC_DECOMP];
|
||||
struct device *dev = &qp_ctx->qp->qm->pdev->dev;
|
||||
struct hisi_zip_req *req;
|
||||
size_t head_size;
|
||||
int head_size;
|
||||
int ret;
|
||||
|
||||
head_size = get_comp_head_size(acomp_req->src, qp_ctx->qp->req_type);
|
||||
head_size = get_comp_head_size(acomp_req, qp_ctx->qp->req_type);
|
||||
if (head_size < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
req = hisi_zip_create_req(acomp_req, qp_ctx, head_size, false);
|
||||
if (IS_ERR(req))
|
||||
if (IS_ERR(req)) {
|
||||
dev_err_ratelimited(dev, "create request before decompress failed!\n");
|
||||
return PTR_ERR(req);
|
||||
}
|
||||
|
||||
ret = hisi_zip_do_work(req, qp_ctx);
|
||||
if (ret != -EINPROGRESS)
|
||||
if (ret != -EINPROGRESS) {
|
||||
dev_err_ratelimited(dev, "do decompress work failed!\n");
|
||||
hisi_zip_remove_req(qp_ctx, req);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -585,23 +667,32 @@ int hisi_zip_register_to_crypto(void)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = crypto_register_acomp(&hisi_zip_acomp_zlib);
|
||||
if (ret) {
|
||||
pr_err("Zlib acomp algorithm registration failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = crypto_register_acomp(&hisi_zip_acomp_gzip);
|
||||
if (ret) {
|
||||
pr_err("Gzip acomp algorithm registration failed\n");
|
||||
crypto_unregister_acomp(&hisi_zip_acomp_zlib);
|
||||
mutex_lock(&hisi_zip_alg_lock);
|
||||
if (++hisi_zip_active_devs == 1) {
|
||||
ret = crypto_register_acomp(&hisi_zip_acomp_zlib);
|
||||
if (ret) {
|
||||
pr_err("Zlib acomp algorithm registration failed\n");
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
ret = crypto_register_acomp(&hisi_zip_acomp_gzip);
|
||||
if (ret) {
|
||||
pr_err("Gzip acomp algorithm registration failed\n");
|
||||
crypto_unregister_acomp(&hisi_zip_acomp_zlib);
|
||||
}
|
||||
}
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&hisi_zip_alg_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void hisi_zip_unregister_from_crypto(void)
|
||||
{
|
||||
crypto_unregister_acomp(&hisi_zip_acomp_gzip);
|
||||
crypto_unregister_acomp(&hisi_zip_acomp_zlib);
|
||||
mutex_lock(&hisi_zip_alg_lock);
|
||||
if (--hisi_zip_active_devs == 0) {
|
||||
crypto_unregister_acomp(&hisi_zip_acomp_gzip);
|
||||
crypto_unregister_acomp(&hisi_zip_acomp_zlib);
|
||||
}
|
||||
mutex_unlock(&hisi_zip_alg_lock);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,47 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 HiSilicon Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HISI_ZIP_USR_IF_H
|
||||
#define HISI_ZIP_USR_IF_H
|
||||
|
||||
struct hisi_zip_sqe {
|
||||
__u32 consumed;
|
||||
__u32 produced;
|
||||
__u32 comp_data_length;
|
||||
__u32 dw3;
|
||||
__u32 input_data_length;
|
||||
__u32 lba_l;
|
||||
__u32 lba_h;
|
||||
__u32 dw7;
|
||||
__u32 dw8;
|
||||
__u32 dw9;
|
||||
__u32 dw10;
|
||||
__u32 priv_info;
|
||||
__u32 dw12;
|
||||
__u32 tag;
|
||||
__u32 dest_avail_out;
|
||||
__u32 rsvd0;
|
||||
__u32 comp_head_addr_l;
|
||||
__u32 comp_head_addr_h;
|
||||
__u32 source_addr_l;
|
||||
__u32 source_addr_h;
|
||||
__u32 dest_addr_l;
|
||||
__u32 dest_addr_h;
|
||||
__u32 stream_ctx_addr_l;
|
||||
__u32 stream_ctx_addr_h;
|
||||
__u32 cipher_key1_addr_l;
|
||||
__u32 cipher_key1_addr_h;
|
||||
__u32 cipher_key2_addr_l;
|
||||
__u32 cipher_key2_addr_h;
|
||||
__u32 rsvd1[4];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* Copyright (c) 2018-2019 HiSilicon Limited. */
|
||||
#ifndef __ACC_COMPAT_H
|
||||
#define __ACC_COMPAT_H
|
||||
|
||||
#include <linux/pci-dma-compat.h>
|
||||
|
||||
#define CONFIG_CRYPTO_QM_UACCE 1
|
||||
#ifndef pci_emerg
|
||||
#define pci_emerg(pdev, fmt, arg...) dev_emerg(&(pdev)->dev, fmt, ##arg)
|
||||
#endif
|
||||
|
||||
#ifndef pci_err
|
||||
#define pci_err(pdev, fmt, arg...) dev_err(&(pdev)->dev, fmt, ##arg)
|
||||
#endif
|
||||
|
||||
#ifndef pci_warn
|
||||
#define pci_warn(pdev, fmt, arg...) dev_warn(&(pdev)->dev, fmt, ##arg)
|
||||
#endif
|
||||
|
||||
#ifndef pci_info
|
||||
#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,135 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* Copyright (c) 2018-2019 HiSilicon Limited. */
|
||||
#ifndef __UACCE_H
|
||||
#define __UACCE_H
|
||||
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/iommu.h>
|
||||
#include "../include_uapi_linux/uacce.h"
|
||||
|
||||
struct uacce_queue;
|
||||
struct uacce;
|
||||
|
||||
#define UACCE_QFRF_MMAP BIT(0) /* map to user space */
|
||||
#define UACCE_QFRF_DMA BIT(1) /* use dma api for the region */
|
||||
#define UACCE_QFRF_SELFMT BIT(2) /* self maintained qfr */
|
||||
|
||||
struct uacce_hw_err {
|
||||
struct list_head list;
|
||||
unsigned long long tick_stamp;
|
||||
};
|
||||
|
||||
struct uacce_err_isolate {
|
||||
struct list_head hw_errs;
|
||||
u32 hw_err_isolate_hz; /* user cfg freq which triggers isolation */
|
||||
atomic_t is_isolate;
|
||||
};
|
||||
|
||||
struct uacce_dma_slice {
|
||||
void *kaddr; /* kernel address for ss */
|
||||
dma_addr_t dma; /* dma address, if created by dma api */
|
||||
u32 size; /* Size of this dma slice */
|
||||
u32 total_num; /* Total slices in this dma list */
|
||||
};
|
||||
|
||||
struct uacce_qfile_region {
|
||||
enum uacce_qfrt type;
|
||||
unsigned long iova; /* iova share between user and device space */
|
||||
unsigned long nr_pages;
|
||||
int prot;
|
||||
unsigned int flags;
|
||||
struct list_head qs; /* qs sharing the same region, for ss */
|
||||
void *kaddr; /* kernel address for dko */
|
||||
struct uacce_dma_slice *dma_list;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct uacce_ops - WD device operations
|
||||
* @get_queue: get a queue from the device according to algorithm
|
||||
* @put_queue: free a queue to the device
|
||||
* @start_queue: make the queue start work after get_queue
|
||||
* @stop_queue: make the queue stop work before put_queue
|
||||
* @is_q_updated: check whether the task is finished
|
||||
* @mask_notify: mask the task irq of queue
|
||||
* @mmap: mmap addresses of queue to user space
|
||||
* @reset: reset the WD device
|
||||
* @reset_queue: reset the queue
|
||||
* @ioctl: ioctl for user space users of the queue
|
||||
*/
|
||||
struct uacce_ops {
|
||||
int (*get_available_instances)(struct uacce *uacce);
|
||||
int (*get_queue)(struct uacce *uacce, unsigned long arg,
|
||||
struct uacce_queue **q);
|
||||
void (*put_queue)(struct uacce_queue *q);
|
||||
int (*start_queue)(struct uacce_queue *q);
|
||||
void (*stop_queue)(struct uacce_queue *q);
|
||||
int (*is_q_updated)(struct uacce_queue *q);
|
||||
void (*mask_notify)(struct uacce_queue *q, int event_mask);
|
||||
int (*mmap)(struct uacce_queue *q, struct vm_area_struct *vma,
|
||||
struct uacce_qfile_region *qfr);
|
||||
int (*reset)(struct uacce *uacce);
|
||||
int (*reset_queue)(struct uacce_queue *q);
|
||||
long (*ioctl)(struct uacce_queue *q, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
enum uacce_dev_state (*get_dev_state)(struct uacce *uacce);
|
||||
};
|
||||
|
||||
enum uacce_dev_state {
|
||||
UACCE_DEV_ERR = -1,
|
||||
UACCE_DEV_NORMAL,
|
||||
};
|
||||
|
||||
enum uacce_q_state {
|
||||
UACCE_Q_INIT,
|
||||
UACCE_Q_STARTED,
|
||||
UACCE_Q_ZOMBIE,
|
||||
UACCE_Q_CLOSED,
|
||||
};
|
||||
|
||||
struct uacce_queue {
|
||||
struct uacce *uacce;
|
||||
__u32 flags;
|
||||
atomic_t status;
|
||||
void *priv;
|
||||
wait_queue_head_t wait;
|
||||
int pasid;
|
||||
struct list_head list; /* as list for as->qs */
|
||||
struct mm_struct *mm;
|
||||
struct uacce_qfile_region *qfrs[UACCE_QFRT_MAX];
|
||||
struct fasync_struct *async_queue;
|
||||
struct file *filep;
|
||||
enum uacce_q_state state;
|
||||
};
|
||||
|
||||
struct uacce {
|
||||
const char *name;
|
||||
const char *drv_name;
|
||||
const char *algs;
|
||||
const char *api_ver;
|
||||
unsigned long qf_pg_start[UACCE_QFRT_MAX];
|
||||
int status;
|
||||
unsigned int flags;
|
||||
struct uacce_ops *ops;
|
||||
struct device *pdev;
|
||||
bool is_vf;
|
||||
u32 dev_id;
|
||||
struct cdev cdev;
|
||||
struct device dev;
|
||||
void *priv;
|
||||
atomic_t ref;
|
||||
int prot;
|
||||
struct uacce_err_isolate isolate_data;
|
||||
struct uacce_err_isolate *isolate;
|
||||
};
|
||||
|
||||
int uacce_register(struct uacce *uacce);
|
||||
int uacce_unregister(struct uacce *uacce);
|
||||
void uacce_wake_up(struct uacce_queue *q);
|
||||
const char *uacce_qfrt_str(struct uacce_qfile_region *qfr);
|
||||
struct uacce *dev_to_uacce(struct device *dev);
|
||||
int uacce_hw_err_isolate(struct uacce *uacce);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,57 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */
|
||||
/* Copyright (c) 2018-2019 HiSilicon Limited. */
|
||||
#ifndef _UAPIUUACCE_H
|
||||
#define _UAPIUUACCE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#define UACCE_CLASS_NAME "uacce"
|
||||
#define UACCE_DEV_ATTRS "attrs"
|
||||
#define UACCE_CMD_SHARE_SVAS _IO('W', 0)
|
||||
#define UACCE_CMD_START _IO('W', 1)
|
||||
#define UACCE_CMD_GET_SS_DMA _IOR('W', 2, unsigned long)
|
||||
#define UACCE_CMD_PUT_Q _IO('W', 3)
|
||||
|
||||
/**
|
||||
* UACCE Device Attributes:
|
||||
*
|
||||
* NOIOMMU: the device has no IOMMU support
|
||||
* can do ssva, but no map to the dev
|
||||
* PASID: the device has IOMMU which support PASID setting
|
||||
* can do ssva, mapped to dev per process
|
||||
* FAULT_FROM_DEV: the device has IOMMU which can do page fault request
|
||||
* no need for ssva, should be used with PASID
|
||||
* KMAP_DUS: map the Device user-shared space to kernel
|
||||
* DRVMAP_DUS: Driver self-maintain its DUS
|
||||
* SVA: full function device
|
||||
* SHARE_DOMAIN: no PASID, can do ssva only for one process and the kernel
|
||||
*/
|
||||
#define UACCE_DEV_NOIOMMU (1 << 0)
|
||||
#define UACCE_DEV_PASID (1 << 1)
|
||||
#define UACCE_DEV_FAULT_FROM_DEV (1 << 2)
|
||||
|
||||
#define UACCE_DEV_SVA (UACCE_DEV_PASID | UACCE_DEV_FAULT_FROM_DEV)
|
||||
#define UACCE_DEV_SHARE_DOMAIN (0)
|
||||
|
||||
/* uacce mode of the driver */
|
||||
#define UACCE_MODE_NOUACCE 0 /* don't use uacce */
|
||||
#define UACCE_MODE_NOIOMMU 2 /* use uacce noiommu mode */
|
||||
|
||||
#define UACCE_API_VER_NOIOMMU_SUBFIX "_noiommu"
|
||||
|
||||
#define UACCE_QFR_NA ((unsigned long)-1)
|
||||
enum uacce_qfrt {
|
||||
UACCE_QFRT_MMIO = 0, /* device mmio region */
|
||||
UACCE_QFRT_DUS, /* device user share */
|
||||
UACCE_QFRT_SS, /* static share memory */
|
||||
UACCE_QFRT_MAX,
|
||||
};
|
||||
#define UACCE_QFRT_INVALID UACCE_QFRT_MAX
|
||||
|
||||
/* Pass DMA SS region slice size by granularity 64KB */
|
||||
#define UACCE_GRAN_SIZE 0x10000ull
|
||||
#define UACCE_GRAN_SHIFT 16
|
||||
#define UACCE_GRAN_NUM_MASK 0xfffull
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,215 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2019 HiSilicon Limited. */
|
||||
#ifndef HISI_ACC_QM_H
|
||||
#define HISI_ACC_QM_H
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
/* qm user domain */
|
||||
#define QM_ARUSER_M_CFG_1 0x100088
|
||||
#define AXUSER_SNOOP_ENABLE BIT(30)
|
||||
#define AXUSER_CMD_TYPE GENMASK(14, 12)
|
||||
#define AXUSER_CMD_SMMU_NORMAL 1
|
||||
#define AXUSER_NS BIT(6)
|
||||
#define AXUSER_NO BIT(5)
|
||||
#define AXUSER_FP BIT(4)
|
||||
#define AXUSER_SSV BIT(0)
|
||||
#define AXUSER_BASE (AXUSER_SNOOP_ENABLE | \
|
||||
FIELD_PREP(AXUSER_CMD_TYPE, \
|
||||
AXUSER_CMD_SMMU_NORMAL) | \
|
||||
AXUSER_NS | AXUSER_NO | AXUSER_FP)
|
||||
#define QM_ARUSER_M_CFG_ENABLE 0x100090
|
||||
#define ARUSER_M_CFG_ENABLE 0xfffffffe
|
||||
#define QM_AWUSER_M_CFG_1 0x100098
|
||||
#define QM_AWUSER_M_CFG_ENABLE 0x1000a0
|
||||
#define AWUSER_M_CFG_ENABLE 0xfffffffe
|
||||
#define QM_WUSER_M_CFG_ENABLE 0x1000a8
|
||||
#define WUSER_M_CFG_ENABLE 0xffffffff
|
||||
|
||||
/* qm cache */
|
||||
#define QM_CACHE_CTL 0x100050
|
||||
#define SQC_CACHE_ENABLE BIT(0)
|
||||
#define CQC_CACHE_ENABLE BIT(1)
|
||||
#define SQC_CACHE_WB_ENABLE BIT(4)
|
||||
#define SQC_CACHE_WB_THRD GENMASK(10, 5)
|
||||
#define CQC_CACHE_WB_ENABLE BIT(11)
|
||||
#define CQC_CACHE_WB_THRD GENMASK(17, 12)
|
||||
#define QM_AXI_M_CFG 0x1000ac
|
||||
#define AXI_M_CFG 0xffff
|
||||
#define QM_AXI_M_CFG_ENABLE 0x1000b0
|
||||
#define AXI_M_CFG_ENABLE 0xffffffff
|
||||
#define QM_PEH_AXUSER_CFG 0x1000cc
|
||||
#define QM_PEH_AXUSER_CFG_ENABLE 0x1000d0
|
||||
#define PEH_AXUSER_CFG 0x401001
|
||||
#define PEH_AXUSER_CFG_ENABLE 0xffffffff
|
||||
|
||||
#define QM_DFX_MB_CNT_VF 0x104010
|
||||
#define QM_DFX_DB_CNT_VF 0x104020
|
||||
#define QM_DFX_SQE_CNT_VF_SQN 0x104030
|
||||
#define QM_DFX_CQE_CNT_VF_CQN 0x104040
|
||||
#define QM_DFX_QN_SHIFT 16
|
||||
#define CURRENT_FUN_MASK GENMASK(5, 0)
|
||||
#define CURRENT_Q_MASK GENMASK(31, 16)
|
||||
|
||||
#define QM_AXI_RRESP BIT(0)
|
||||
#define QM_AXI_BRESP BIT(1)
|
||||
#define QM_ECC_MBIT BIT(2)
|
||||
#define QM_ECC_1BIT BIT(3)
|
||||
#define QM_ACC_GET_TASK_TIMEOUT BIT(4)
|
||||
#define QM_ACC_DO_TASK_TIMEOUT BIT(5)
|
||||
#define QM_ACC_WB_NOT_READY_TIMEOUT BIT(6)
|
||||
#define QM_SQ_CQ_VF_INVALID BIT(7)
|
||||
#define QM_CQ_VF_INVALID BIT(8)
|
||||
#define QM_SQ_VF_INVALID BIT(9)
|
||||
#define QM_DB_TIMEOUT BIT(10)
|
||||
#define QM_OF_FIFO_OF BIT(11)
|
||||
#define QM_DB_RANDOM_INVALID BIT(12)
|
||||
|
||||
#define QM_BASE_NFE (QM_AXI_RRESP | QM_AXI_BRESP | QM_ECC_MBIT | \
|
||||
QM_ACC_GET_TASK_TIMEOUT | QM_DB_TIMEOUT | \
|
||||
QM_OF_FIFO_OF)
|
||||
#define QM_BASE_CE QM_ECC_1BIT
|
||||
|
||||
#define QM_Q_DEPTH 1024
|
||||
|
||||
enum qp_state {
|
||||
QP_STOP,
|
||||
};
|
||||
|
||||
enum qm_hw_ver {
|
||||
QM_HW_UNKNOWN = -1,
|
||||
QM_HW_V1 = 0x20,
|
||||
QM_HW_V2 = 0x21,
|
||||
};
|
||||
|
||||
enum qm_fun_type {
|
||||
QM_HW_PF,
|
||||
QM_HW_VF,
|
||||
};
|
||||
|
||||
enum qm_debug_file {
|
||||
CURRENT_Q,
|
||||
CLEAR_ENABLE,
|
||||
DEBUG_FILE_NUM,
|
||||
};
|
||||
|
||||
struct debugfs_file {
|
||||
enum qm_debug_file index;
|
||||
struct mutex lock;
|
||||
struct qm_debug *debug;
|
||||
};
|
||||
|
||||
struct qm_debug {
|
||||
u32 curr_qm_qp_num;
|
||||
struct dentry *debug_root;
|
||||
struct dentry *qm_d;
|
||||
struct debugfs_file files[DEBUG_FILE_NUM];
|
||||
};
|
||||
|
||||
struct qm_dma {
|
||||
void *va;
|
||||
dma_addr_t dma;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct hisi_qm_status {
|
||||
u32 eq_head;
|
||||
bool eqc_phase;
|
||||
u32 aeq_head;
|
||||
bool aeqc_phase;
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
struct hisi_qm {
|
||||
enum qm_hw_ver ver;
|
||||
enum qm_fun_type fun_type;
|
||||
const char *dev_name;
|
||||
struct pci_dev *pdev;
|
||||
void __iomem *io_base;
|
||||
u32 sqe_size;
|
||||
u32 qp_base;
|
||||
u32 qp_num;
|
||||
u32 ctrl_qp_num;
|
||||
|
||||
struct qm_dma qdma;
|
||||
struct qm_sqc *sqc;
|
||||
struct qm_cqc *cqc;
|
||||
struct qm_eqe *eqe;
|
||||
struct qm_aeqe *aeqe;
|
||||
dma_addr_t sqc_dma;
|
||||
dma_addr_t cqc_dma;
|
||||
dma_addr_t eqe_dma;
|
||||
dma_addr_t aeqe_dma;
|
||||
|
||||
struct hisi_qm_status status;
|
||||
|
||||
rwlock_t qps_lock;
|
||||
unsigned long *qp_bitmap;
|
||||
struct hisi_qp **qp_array;
|
||||
|
||||
struct mutex mailbox_lock;
|
||||
|
||||
const struct hisi_qm_hw_ops *ops;
|
||||
|
||||
struct qm_debug debug;
|
||||
|
||||
u32 error_mask;
|
||||
u32 msi_mask;
|
||||
|
||||
bool use_dma_api;
|
||||
};
|
||||
|
||||
struct hisi_qp_status {
|
||||
atomic_t used;
|
||||
u16 sq_tail;
|
||||
u16 cq_head;
|
||||
bool cqc_phase;
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
struct hisi_qp_ops {
|
||||
int (*fill_sqe)(void *sqe, void *q_parm, void *d_parm);
|
||||
};
|
||||
|
||||
struct hisi_qp {
|
||||
u32 qp_id;
|
||||
u8 alg_type;
|
||||
u8 req_type;
|
||||
|
||||
struct qm_dma qdma;
|
||||
void *sqe;
|
||||
struct qm_cqe *cqe;
|
||||
dma_addr_t sqe_dma;
|
||||
dma_addr_t cqe_dma;
|
||||
|
||||
struct hisi_qp_status qp_status;
|
||||
struct hisi_qp_ops *hw_ops;
|
||||
void *qp_ctx;
|
||||
void (*req_cb)(struct hisi_qp *qp, void *data);
|
||||
struct work_struct work;
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
struct hisi_qm *qm;
|
||||
};
|
||||
|
||||
int hisi_qm_init(struct hisi_qm *qm);
|
||||
void hisi_qm_uninit(struct hisi_qm *qm);
|
||||
int hisi_qm_start(struct hisi_qm *qm);
|
||||
int hisi_qm_stop(struct hisi_qm *qm);
|
||||
struct hisi_qp *hisi_qm_create_qp(struct hisi_qm *qm, u8 alg_type);
|
||||
int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long arg);
|
||||
int hisi_qm_stop_qp(struct hisi_qp *qp);
|
||||
void hisi_qm_release_qp(struct hisi_qp *qp);
|
||||
int hisi_qp_send(struct hisi_qp *qp, const void *msg);
|
||||
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);
|
||||
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);
|
||||
int hisi_qm_hw_error_handle(struct hisi_qm *qm);
|
||||
enum qm_hw_ver hisi_qm_get_hw_version(struct pci_dev *pdev);
|
||||
void hisi_qm_debug_regs_clear(struct hisi_qm *qm);
|
||||
#endif
|
|
@ -1,3 +0,0 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += hisi_sec.o
|
||||
hisi_sec-y = sec_algs.o sec_drv.o
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,428 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2016-2017 Hisilicon Limited. */
|
||||
|
||||
#ifndef _SEC_DRV_H_
|
||||
#define _SEC_DRV_H_
|
||||
|
||||
#include <crypto/algapi.h>
|
||||
#include <linux/kfifo.h>
|
||||
|
||||
#define SEC_MAX_SGE_NUM 64
|
||||
#define SEC_HW_RING_NUM 3
|
||||
|
||||
#define SEC_CMD_RING 0
|
||||
#define SEC_OUTORDER_RING 1
|
||||
#define SEC_DBG_RING 2
|
||||
|
||||
/* A reasonable length to balance memory use against flexibility */
|
||||
#define SEC_QUEUE_LEN 512
|
||||
|
||||
#define SEC_MAX_SGE_NUM 64
|
||||
|
||||
struct sec_bd_info {
|
||||
#define SEC_BD_W0_T_LEN_M GENMASK(4, 0)
|
||||
#define SEC_BD_W0_T_LEN_S 0
|
||||
|
||||
#define SEC_BD_W0_C_WIDTH_M GENMASK(6, 5)
|
||||
#define SEC_BD_W0_C_WIDTH_S 5
|
||||
#define SEC_C_WIDTH_AES_128BIT 0
|
||||
#define SEC_C_WIDTH_AES_8BIT 1
|
||||
#define SEC_C_WIDTH_AES_1BIT 2
|
||||
#define SEC_C_WIDTH_DES_64BIT 0
|
||||
#define SEC_C_WIDTH_DES_8BIT 1
|
||||
#define SEC_C_WIDTH_DES_1BIT 2
|
||||
|
||||
#define SEC_BD_W0_C_MODE_M GENMASK(9, 7)
|
||||
#define SEC_BD_W0_C_MODE_S 7
|
||||
#define SEC_C_MODE_ECB 0
|
||||
#define SEC_C_MODE_CBC 1
|
||||
#define SEC_C_MODE_CTR 4
|
||||
#define SEC_C_MODE_CCM 5
|
||||
#define SEC_C_MODE_GCM 6
|
||||
#define SEC_C_MODE_XTS 7
|
||||
|
||||
#define SEC_BD_W0_SEQ BIT(10)
|
||||
#define SEC_BD_W0_DE BIT(11)
|
||||
#define SEC_BD_W0_DAT_SKIP_M GENMASK(13, 12)
|
||||
#define SEC_BD_W0_DAT_SKIP_S 12
|
||||
#define SEC_BD_W0_C_GRAN_SIZE_19_16_M GENMASK(17, 14)
|
||||
#define SEC_BD_W0_C_GRAN_SIZE_19_16_S 14
|
||||
|
||||
#define SEC_BD_W0_CIPHER_M GENMASK(19, 18)
|
||||
#define SEC_BD_W0_CIPHER_S 18
|
||||
#define SEC_CIPHER_NULL 0
|
||||
#define SEC_CIPHER_ENCRYPT 1
|
||||
#define SEC_CIPHER_DECRYPT 2
|
||||
|
||||
#define SEC_BD_W0_AUTH_M GENMASK(21, 20)
|
||||
#define SEC_BD_W0_AUTH_S 20
|
||||
#define SEC_AUTH_NULL 0
|
||||
#define SEC_AUTH_MAC 1
|
||||
#define SEC_AUTH_VERIF 2
|
||||
|
||||
#define SEC_BD_W0_AI_GEN BIT(22)
|
||||
#define SEC_BD_W0_CI_GEN BIT(23)
|
||||
#define SEC_BD_W0_NO_HPAD BIT(24)
|
||||
#define SEC_BD_W0_HM_M GENMASK(26, 25)
|
||||
#define SEC_BD_W0_HM_S 25
|
||||
#define SEC_BD_W0_ICV_OR_SKEY_EN_M GENMASK(28, 27)
|
||||
#define SEC_BD_W0_ICV_OR_SKEY_EN_S 27
|
||||
|
||||
/* Multi purpose field - gran size bits for send, flag for recv */
|
||||
#define SEC_BD_W0_FLAG_M GENMASK(30, 29)
|
||||
#define SEC_BD_W0_C_GRAN_SIZE_21_20_M GENMASK(30, 29)
|
||||
#define SEC_BD_W0_FLAG_S 29
|
||||
#define SEC_BD_W0_C_GRAN_SIZE_21_20_S 29
|
||||
|
||||
#define SEC_BD_W0_DONE BIT(31)
|
||||
u32 w0;
|
||||
|
||||
#define SEC_BD_W1_AUTH_GRAN_SIZE_M GENMASK(21, 0)
|
||||
#define SEC_BD_W1_AUTH_GRAN_SIZE_S 0
|
||||
#define SEC_BD_W1_M_KEY_EN BIT(22)
|
||||
#define SEC_BD_W1_BD_INVALID BIT(23)
|
||||
#define SEC_BD_W1_ADDR_TYPE BIT(24)
|
||||
|
||||
#define SEC_BD_W1_A_ALG_M GENMASK(28, 25)
|
||||
#define SEC_BD_W1_A_ALG_S 25
|
||||
#define SEC_A_ALG_SHA1 0
|
||||
#define SEC_A_ALG_SHA256 1
|
||||
#define SEC_A_ALG_MD5 2
|
||||
#define SEC_A_ALG_SHA224 3
|
||||
#define SEC_A_ALG_HMAC_SHA1 8
|
||||
#define SEC_A_ALG_HMAC_SHA224 10
|
||||
#define SEC_A_ALG_HMAC_SHA256 11
|
||||
#define SEC_A_ALG_HMAC_MD5 12
|
||||
#define SEC_A_ALG_AES_XCBC 13
|
||||
#define SEC_A_ALG_AES_CMAC 14
|
||||
|
||||
#define SEC_BD_W1_C_ALG_M GENMASK(31, 29)
|
||||
#define SEC_BD_W1_C_ALG_S 29
|
||||
#define SEC_C_ALG_DES 0
|
||||
#define SEC_C_ALG_3DES 1
|
||||
#define SEC_C_ALG_AES 2
|
||||
|
||||
u32 w1;
|
||||
|
||||
#define SEC_BD_W2_C_GRAN_SIZE_15_0_M GENMASK(15, 0)
|
||||
#define SEC_BD_W2_C_GRAN_SIZE_15_0_S 0
|
||||
#define SEC_BD_W2_GRAN_NUM_M GENMASK(31, 16)
|
||||
#define SEC_BD_W2_GRAN_NUM_S 16
|
||||
u32 w2;
|
||||
|
||||
#define SEC_BD_W3_AUTH_LEN_OFFSET_M GENMASK(9, 0)
|
||||
#define SEC_BD_W3_AUTH_LEN_OFFSET_S 0
|
||||
#define SEC_BD_W3_CIPHER_LEN_OFFSET_M GENMASK(19, 10)
|
||||
#define SEC_BD_W3_CIPHER_LEN_OFFSET_S 10
|
||||
#define SEC_BD_W3_MAC_LEN_M GENMASK(24, 20)
|
||||
#define SEC_BD_W3_MAC_LEN_S 20
|
||||
#define SEC_BD_W3_A_KEY_LEN_M GENMASK(29, 25)
|
||||
#define SEC_BD_W3_A_KEY_LEN_S 25
|
||||
#define SEC_BD_W3_C_KEY_LEN_M GENMASK(31, 30)
|
||||
#define SEC_BD_W3_C_KEY_LEN_S 30
|
||||
#define SEC_KEY_LEN_AES_128 0
|
||||
#define SEC_KEY_LEN_AES_192 1
|
||||
#define SEC_KEY_LEN_AES_256 2
|
||||
#define SEC_KEY_LEN_DES 1
|
||||
#define SEC_KEY_LEN_3DES_3_KEY 1
|
||||
#define SEC_KEY_LEN_3DES_2_KEY 3
|
||||
u32 w3;
|
||||
|
||||
/* W4,5 */
|
||||
union {
|
||||
u32 authkey_addr_lo;
|
||||
u32 authiv_addr_lo;
|
||||
};
|
||||
union {
|
||||
u32 authkey_addr_hi;
|
||||
u32 authiv_addr_hi;
|
||||
};
|
||||
|
||||
/* W6,7 */
|
||||
u32 cipher_key_addr_lo;
|
||||
u32 cipher_key_addr_hi;
|
||||
|
||||
/* W8,9 */
|
||||
u32 cipher_iv_addr_lo;
|
||||
u32 cipher_iv_addr_hi;
|
||||
|
||||
/* W10,11 */
|
||||
u32 data_addr_lo;
|
||||
u32 data_addr_hi;
|
||||
|
||||
/* W12,13 */
|
||||
u32 mac_addr_lo;
|
||||
u32 mac_addr_hi;
|
||||
|
||||
/* W14,15 */
|
||||
u32 cipher_destin_addr_lo;
|
||||
u32 cipher_destin_addr_hi;
|
||||
};
|
||||
|
||||
enum sec_mem_region {
|
||||
SEC_COMMON = 0,
|
||||
SEC_SAA,
|
||||
SEC_NUM_ADDR_REGIONS
|
||||
};
|
||||
|
||||
#define SEC_NAME_SIZE 64
|
||||
#define SEC_Q_NUM 16
|
||||
|
||||
|
||||
/**
|
||||
* struct sec_queue_ring_cmd - store information about a SEC HW cmd ring
|
||||
* @used: Local counter used to cheaply establish if the ring is empty.
|
||||
* @lock: Protect against simultaneous adjusting of the read and write pointers.
|
||||
* @vaddr: Virtual address for the ram pages used for the ring.
|
||||
* @paddr: Physical address of the dma mapped region of ram used for the ring.
|
||||
* @callback: Callback function called on a ring element completing.
|
||||
*/
|
||||
struct sec_queue_ring_cmd {
|
||||
atomic_t used;
|
||||
struct mutex lock;
|
||||
struct sec_bd_info *vaddr;
|
||||
dma_addr_t paddr;
|
||||
void (*callback)(struct sec_bd_info *resp, void *ctx);
|
||||
};
|
||||
|
||||
struct sec_debug_bd_info;
|
||||
struct sec_queue_ring_db {
|
||||
struct sec_debug_bd_info *vaddr;
|
||||
dma_addr_t paddr;
|
||||
};
|
||||
|
||||
struct sec_out_bd_info;
|
||||
struct sec_queue_ring_cq {
|
||||
struct sec_out_bd_info *vaddr;
|
||||
dma_addr_t paddr;
|
||||
};
|
||||
|
||||
struct sec_dev_info;
|
||||
|
||||
enum sec_cipher_alg {
|
||||
SEC_C_DES_ECB_64,
|
||||
SEC_C_DES_CBC_64,
|
||||
|
||||
SEC_C_3DES_ECB_192_3KEY,
|
||||
SEC_C_3DES_ECB_192_2KEY,
|
||||
|
||||
SEC_C_3DES_CBC_192_3KEY,
|
||||
SEC_C_3DES_CBC_192_2KEY,
|
||||
|
||||
SEC_C_AES_ECB_128,
|
||||
SEC_C_AES_ECB_192,
|
||||
SEC_C_AES_ECB_256,
|
||||
|
||||
SEC_C_AES_CBC_128,
|
||||
SEC_C_AES_CBC_192,
|
||||
SEC_C_AES_CBC_256,
|
||||
|
||||
SEC_C_AES_CTR_128,
|
||||
SEC_C_AES_CTR_192,
|
||||
SEC_C_AES_CTR_256,
|
||||
|
||||
SEC_C_AES_XTS_128,
|
||||
SEC_C_AES_XTS_256,
|
||||
|
||||
SEC_C_NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sec_alg_tfm_ctx - hardware specific tranformation context
|
||||
* @cipher_alg: Cipher algorithm enabled include encryption mode.
|
||||
* @key: Key storage if required.
|
||||
* @pkey: DMA address for the key storage.
|
||||
* @req_template: Request template to save time on setup.
|
||||
* @queue: The hardware queue associated with this tfm context.
|
||||
* @lock: Protect key and pkey to ensure they are consistent
|
||||
* @auth_buf: Current context buffer for auth operations.
|
||||
* @backlog: The backlog queue used for cases where our buffers aren't
|
||||
* large enough.
|
||||
*/
|
||||
struct sec_alg_tfm_ctx {
|
||||
enum sec_cipher_alg cipher_alg;
|
||||
u8 *key;
|
||||
dma_addr_t pkey;
|
||||
struct sec_bd_info req_template;
|
||||
struct sec_queue *queue;
|
||||
struct mutex lock;
|
||||
u8 *auth_buf;
|
||||
struct list_head backlog;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sec_request - data associate with a single crypto request
|
||||
* @elements: List of subparts of this request (hardware size restriction)
|
||||
* @num_elements: The number of subparts (used as an optimization)
|
||||
* @lock: Protect elements of this structure against concurrent change.
|
||||
* @tfm_ctx: hardware specific context.
|
||||
* @len_in: length of in sgl from upper layers
|
||||
* @len_out: length of out sgl from upper layers
|
||||
* @dma_iv: initialization vector - phsyical address
|
||||
* @err: store used to track errors across subelements of this request.
|
||||
* @req_base: pointer to base element of associate crypto context.
|
||||
* This is needed to allow shared handling skcipher, ahash etc.
|
||||
* @cb: completion callback.
|
||||
* @backlog_head: list head to allow backlog maintenance.
|
||||
*
|
||||
* The hardware is limited in the maximum size of data that it can
|
||||
* process from a single BD. Typically this is fairly large (32MB)
|
||||
* but still requires the complexity of splitting the incoming
|
||||
* skreq up into a number of elements complete with appropriate
|
||||
* iv chaining.
|
||||
*/
|
||||
struct sec_request {
|
||||
struct list_head elements;
|
||||
int num_elements;
|
||||
struct mutex lock;
|
||||
struct sec_alg_tfm_ctx *tfm_ctx;
|
||||
int len_in;
|
||||
int len_out;
|
||||
dma_addr_t dma_iv;
|
||||
int err;
|
||||
struct crypto_async_request *req_base;
|
||||
void (*cb)(struct sec_bd_info *resp, struct crypto_async_request *req);
|
||||
struct list_head backlog_head;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sec_request_el - A subpart of a request.
|
||||
* @head: allow us to attach this to the list in the sec_request
|
||||
* @req: hardware block descriptor corresponding to this request subpart
|
||||
* @in: hardware sgl for input - virtual address
|
||||
* @dma_in: hardware sgl for input - physical address
|
||||
* @sgl_in: scatterlist for this request subpart
|
||||
* @out: hardware sgl for output - virtual address
|
||||
* @dma_out: hardware sgl for output - physical address
|
||||
* @sgl_out: scatterlist for this request subpart
|
||||
* @sec_req: The request which this subpart forms a part of
|
||||
* @el_length: Number of bytes in this subpart. Needed to locate
|
||||
* last ivsize chunk for iv chaining.
|
||||
*/
|
||||
struct sec_request_el {
|
||||
struct list_head head;
|
||||
struct sec_bd_info req;
|
||||
struct sec_hw_sgl *in;
|
||||
dma_addr_t dma_in;
|
||||
struct scatterlist *sgl_in;
|
||||
struct sec_hw_sgl *out;
|
||||
dma_addr_t dma_out;
|
||||
struct scatterlist *sgl_out;
|
||||
struct sec_request *sec_req;
|
||||
size_t el_length;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sec_queue - All the information about a HW queue
|
||||
* @dev_info: The parent SEC device to which this queue belongs.
|
||||
* @task_irq: Completion interrupt for the queue.
|
||||
* @name: Human readable queue description also used as irq name.
|
||||
* @ring: The several HW rings associated with one queue.
|
||||
* @regs: The iomapped device registers
|
||||
* @queue_id: Index of the queue used for naming and resource selection.
|
||||
* @in_use: Flag to say if the queue is in use.
|
||||
* @expected: The next expected element to finish assuming we were in order.
|
||||
* @uprocessed: A bitmap to track which OoO elements are done but not handled.
|
||||
* @softqueue: A software queue used when chaining requirements prevent direct
|
||||
* use of the hardware queues.
|
||||
* @havesoftqueue: A flag to say we have a queues - as we may need one for the
|
||||
* current mode.
|
||||
* @queuelock: Protect the soft queue from concurrent changes to avoid some
|
||||
* potential loss of data races.
|
||||
* @shadow: Pointers back to the shadow copy of the hardware ring element
|
||||
* need because we can't store any context reference in the bd element.
|
||||
*/
|
||||
struct sec_queue {
|
||||
struct sec_dev_info *dev_info;
|
||||
int task_irq;
|
||||
char name[SEC_NAME_SIZE];
|
||||
struct sec_queue_ring_cmd ring_cmd;
|
||||
struct sec_queue_ring_cq ring_cq;
|
||||
struct sec_queue_ring_db ring_db;
|
||||
void __iomem *regs;
|
||||
u32 queue_id;
|
||||
bool in_use;
|
||||
int expected;
|
||||
|
||||
DECLARE_BITMAP(unprocessed, SEC_QUEUE_LEN);
|
||||
DECLARE_KFIFO_PTR(softqueue, typeof(struct sec_request_el *));
|
||||
bool havesoftqueue;
|
||||
struct mutex queuelock;
|
||||
void *shadow[SEC_QUEUE_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sec_hw_sge: Track each of the 64 element SEC HW SGL entries
|
||||
* @buf: The IOV dma address for this entry.
|
||||
* @len: Length of this IOV.
|
||||
* @pad: Reserved space.
|
||||
*/
|
||||
struct sec_hw_sge {
|
||||
dma_addr_t buf;
|
||||
unsigned int len;
|
||||
unsigned int pad;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sec_hw_sgl: One hardware SGL entry.
|
||||
* @next_sgl: The next entry if we need to chain dma address. Null if last.
|
||||
* @entry_sum_in_chain: The full count of SGEs - only matters for first SGL.
|
||||
* @entry_sum_in_sgl: The number of SGEs in this SGL element.
|
||||
* @flag: Unused in skciphers.
|
||||
* @serial_num: Unsued in skciphers.
|
||||
* @cpuid: Currently unused.
|
||||
* @data_bytes_in_sgl: Count of bytes from all SGEs in this SGL.
|
||||
* @next: Virtual address used to stash the next sgl - useful in completion.
|
||||
* @reserved: A reserved field not currently used.
|
||||
* @sge_entries: The (up to) 64 Scatter Gather Entries, representing IOVs.
|
||||
* @node: Currently unused.
|
||||
*/
|
||||
struct sec_hw_sgl {
|
||||
dma_addr_t next_sgl;
|
||||
u16 entry_sum_in_chain;
|
||||
u16 entry_sum_in_sgl;
|
||||
u32 flag;
|
||||
u64 serial_num;
|
||||
u32 cpuid;
|
||||
u32 data_bytes_in_sgl;
|
||||
struct sec_hw_sgl *next;
|
||||
u64 reserved;
|
||||
struct sec_hw_sge sge_entries[SEC_MAX_SGE_NUM];
|
||||
u8 node[16];
|
||||
};
|
||||
|
||||
struct dma_pool;
|
||||
|
||||
/**
|
||||
* struct sec_dev_info: The full SEC unit comprising queues and processors.
|
||||
* @sec_id: Index used to track which SEC this is when more than one is present.
|
||||
* @num_saas: The number of backed processors enabled.
|
||||
* @regs: iomapped register regions shared by whole SEC unit.
|
||||
* @dev_lock: Protects concurrent queue allocation / freeing for the SEC.
|
||||
* @queues: The 16 queues that this SEC instance provides.
|
||||
* @dev: Device pointer.
|
||||
* @hw_sgl_pool: DMA pool used to mimise mapping for the scatter gather lists.
|
||||
*/
|
||||
struct sec_dev_info {
|
||||
int sec_id;
|
||||
int num_saas;
|
||||
void __iomem *regs[SEC_NUM_ADDR_REGIONS];
|
||||
struct mutex dev_lock;
|
||||
int queues_in_use;
|
||||
struct sec_queue queues[SEC_Q_NUM];
|
||||
struct device *dev;
|
||||
struct dma_pool *hw_sgl_pool;
|
||||
};
|
||||
|
||||
int sec_queue_send(struct sec_queue *queue, struct sec_bd_info *msg, void *ctx);
|
||||
bool sec_queue_can_enqueue(struct sec_queue *queue, int num);
|
||||
int sec_queue_stop_release(struct sec_queue *queue);
|
||||
struct sec_queue *sec_queue_alloc_start_safe(void);
|
||||
bool sec_queue_empty(struct sec_queue *queue);
|
||||
|
||||
/* Algorithm specific elements from sec_algs.c */
|
||||
void sec_alg_callback(struct sec_bd_info *resp, void *ctx);
|
||||
int sec_algs_register(void);
|
||||
void sec_algs_unregister(void);
|
||||
|
||||
#endif /* _SEC_DRV_H_ */
|
|
@ -1,214 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2019 HiSilicon Limited. */
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
#include "./sgl.h"
|
||||
|
||||
#define HISI_ACC_SGL_SGE_NR_MIN 1
|
||||
#define HISI_ACC_SGL_SGE_NR_MAX 255
|
||||
#define HISI_ACC_SGL_SGE_NR_DEF 10
|
||||
#define HISI_ACC_SGL_NR_MAX 256
|
||||
#define HISI_ACC_SGL_ALIGN_SIZE 64
|
||||
|
||||
static int acc_sgl_sge_set(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
int ret;
|
||||
u32 n;
|
||||
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
|
||||
ret = kstrtou32(val, 10, &n);
|
||||
if (ret != 0 || n > HISI_ACC_SGL_SGE_NR_MAX || n == 0)
|
||||
return -EINVAL;
|
||||
|
||||
return param_set_int(val, kp);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops acc_sgl_sge_ops = {
|
||||
.set = acc_sgl_sge_set,
|
||||
.get = param_get_int,
|
||||
};
|
||||
|
||||
static u32 acc_sgl_sge_nr = HISI_ACC_SGL_SGE_NR_DEF;
|
||||
module_param_cb(acc_sgl_sge_nr, &acc_sgl_sge_ops, &acc_sgl_sge_nr, 0444);
|
||||
MODULE_PARM_DESC(acc_sgl_sge_nr, "Number of sge in sgl(1-255)");
|
||||
|
||||
struct acc_hw_sge {
|
||||
dma_addr_t buf;
|
||||
void *page_ctrl;
|
||||
__le32 len;
|
||||
__le32 pad;
|
||||
__le32 pad0;
|
||||
__le32 pad1;
|
||||
};
|
||||
|
||||
/* use default sgl head size 64B */
|
||||
struct hisi_acc_hw_sgl {
|
||||
dma_addr_t next_dma;
|
||||
__le16 entry_sum_in_chain;
|
||||
__le16 entry_sum_in_sgl;
|
||||
__le16 entry_length_in_sgl;
|
||||
__le16 pad0;
|
||||
__le64 pad1[5];
|
||||
struct hisi_acc_hw_sgl *next;
|
||||
struct acc_hw_sge sge_entries[];
|
||||
} __aligned(1);
|
||||
|
||||
/**
|
||||
* hisi_acc_create_sgl_pool() - Create a hw sgl pool.
|
||||
* @dev: The device which hw sgl pool belongs to.
|
||||
* @pool: Pointer of pool.
|
||||
* @count: Count of hisi_acc_hw_sgl in pool.
|
||||
*
|
||||
* This function creates a hw sgl pool, after this user can get hw sgl memory
|
||||
* from it.
|
||||
*/
|
||||
int hisi_acc_create_sgl_pool(struct device *dev,
|
||||
struct hisi_acc_sgl_pool *pool, u32 count)
|
||||
{
|
||||
u32 sgl_size;
|
||||
u32 size;
|
||||
|
||||
if (!dev || !pool || !count)
|
||||
return -EINVAL;
|
||||
|
||||
sgl_size = sizeof(struct acc_hw_sge) * acc_sgl_sge_nr +
|
||||
sizeof(struct hisi_acc_hw_sgl);
|
||||
size = sgl_size * count;
|
||||
|
||||
pool->sgl = dma_alloc_coherent(dev, size, &pool->sgl_dma, GFP_KERNEL);
|
||||
if (!pool->sgl)
|
||||
return -ENOMEM;
|
||||
|
||||
pool->size = size;
|
||||
pool->count = count;
|
||||
pool->sgl_size = sgl_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_acc_create_sgl_pool);
|
||||
|
||||
/**
|
||||
* hisi_acc_free_sgl_pool() - Free a hw sgl pool.
|
||||
* @dev: The device which hw sgl pool belongs to.
|
||||
* @pool: Pointer of pool.
|
||||
*
|
||||
* This function frees memory of a hw sgl pool.
|
||||
*/
|
||||
void hisi_acc_free_sgl_pool(struct device *dev, struct hisi_acc_sgl_pool *pool)
|
||||
{
|
||||
dma_free_coherent(dev, pool->size, pool->sgl, pool->sgl_dma);
|
||||
memset(pool, 0, sizeof(struct hisi_acc_sgl_pool));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_acc_free_sgl_pool);
|
||||
|
||||
struct hisi_acc_hw_sgl *acc_get_sgl(struct hisi_acc_sgl_pool *pool, u32 index,
|
||||
dma_addr_t *hw_sgl_dma)
|
||||
{
|
||||
if (!pool || !hw_sgl_dma || index >= pool->count || !pool->sgl)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
*hw_sgl_dma = pool->sgl_dma + pool->sgl_size * index;
|
||||
return (void *)pool->sgl + pool->sgl_size * index;
|
||||
}
|
||||
|
||||
void acc_put_sgl(struct hisi_acc_sgl_pool *pool, u32 index) {}
|
||||
|
||||
static void sg_map_to_hw_sg(struct scatterlist *sgl,
|
||||
struct acc_hw_sge *hw_sge)
|
||||
{
|
||||
hw_sge->buf = sgl->dma_address;
|
||||
hw_sge->len = sgl->dma_length;
|
||||
}
|
||||
|
||||
static void inc_hw_sgl_sge(struct hisi_acc_hw_sgl *hw_sgl)
|
||||
{
|
||||
hw_sgl->entry_sum_in_sgl++;
|
||||
}
|
||||
|
||||
static void update_hw_sgl_sum_sge(struct hisi_acc_hw_sgl *hw_sgl, u16 sum)
|
||||
{
|
||||
hw_sgl->entry_sum_in_chain = sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* hisi_acc_sg_buf_map_to_hw_sgl - Map a scatterlist to a hw sgl.
|
||||
* @dev: The device which hw sgl belongs to.
|
||||
* @sgl: Scatterlist which will be mapped to hw sgl.
|
||||
* @pool: Pool which hw sgl memory will be allocated in.
|
||||
* @index: Index of hisi_acc_hw_sgl in pool.
|
||||
* @hw_sgl_dma: The dma address of allocated hw sgl.
|
||||
*
|
||||
* This function builds hw sgl according input sgl, user can use hw_sgl_dma
|
||||
* as src/dst in its BD. Only support single hw sgl currently.
|
||||
*/
|
||||
struct hisi_acc_hw_sgl *
|
||||
hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,
|
||||
struct scatterlist *sgl,
|
||||
struct hisi_acc_sgl_pool *pool,
|
||||
u32 index, dma_addr_t *hw_sgl_dma)
|
||||
{
|
||||
struct hisi_acc_hw_sgl *curr_hw_sgl;
|
||||
dma_addr_t curr_sgl_dma = 0;
|
||||
struct acc_hw_sge *curr_hw_sge;
|
||||
struct scatterlist *sg;
|
||||
int sg_n = sg_nents(sgl);
|
||||
int i, ret;
|
||||
|
||||
if (!dev || !sgl || !pool || !hw_sgl_dma || sg_n > acc_sgl_sge_nr)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
ret = dma_map_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
|
||||
if (!ret)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
curr_hw_sgl = acc_get_sgl(pool, index, &curr_sgl_dma);
|
||||
if (!curr_hw_sgl) {
|
||||
ret = -ENOMEM;
|
||||
goto err_unmap_sg;
|
||||
}
|
||||
curr_hw_sgl->entry_length_in_sgl = acc_sgl_sge_nr;
|
||||
curr_hw_sge = curr_hw_sgl->sge_entries;
|
||||
|
||||
for_each_sg(sgl, sg, sg_n, i) {
|
||||
sg_map_to_hw_sg(sg, curr_hw_sge);
|
||||
inc_hw_sgl_sge(curr_hw_sgl);
|
||||
curr_hw_sge++;
|
||||
}
|
||||
|
||||
update_hw_sgl_sum_sge(curr_hw_sgl, acc_sgl_sge_nr);
|
||||
*hw_sgl_dma = curr_sgl_dma;
|
||||
|
||||
return curr_hw_sgl;
|
||||
|
||||
err_unmap_sg:
|
||||
dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_acc_sg_buf_map_to_hw_sgl);
|
||||
|
||||
/**
|
||||
* hisi_acc_sg_buf_unmap() - Unmap allocated hw sgl.
|
||||
* @dev: The device which hw sgl belongs to.
|
||||
* @sgl: Related scatterlist.
|
||||
* @hw_sgl: Virtual address of hw sgl.
|
||||
* @hw_sgl_dma: DMA address of hw sgl.
|
||||
* @pool: Pool which hw sgl is allocated in.
|
||||
*
|
||||
* This function unmaps allocated hw sgl.
|
||||
*/
|
||||
void hisi_acc_sg_buf_unmap(struct device *dev, struct scatterlist *sgl,
|
||||
struct hisi_acc_hw_sgl *hw_sgl)
|
||||
{
|
||||
dma_unmap_sg(dev, sgl, sg_nents(sgl), DMA_BIDIRECTIONAL);
|
||||
|
||||
hw_sgl->entry_sum_in_chain = 0;
|
||||
hw_sgl->entry_sum_in_sgl = 0;
|
||||
hw_sgl->entry_length_in_sgl = 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_acc_sg_buf_unmap);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>");
|
||||
MODULE_DESCRIPTION("HiSilicon Accelerator SGL support");
|
|
@ -1,24 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2019 HiSilicon Limited. */
|
||||
#ifndef HISI_ACC_SGL_H
|
||||
#define HISI_ACC_SGL_H
|
||||
|
||||
struct hisi_acc_sgl_pool {
|
||||
struct hisi_acc_hw_sgl *sgl;
|
||||
dma_addr_t sgl_dma;
|
||||
size_t size;
|
||||
u32 count;
|
||||
size_t sgl_size;
|
||||
};
|
||||
|
||||
struct hisi_acc_hw_sgl *
|
||||
hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,
|
||||
struct scatterlist *sgl,
|
||||
struct hisi_acc_sgl_pool *pool,
|
||||
u32 index, dma_addr_t *hw_sgl_dma);
|
||||
void hisi_acc_sg_buf_unmap(struct device *dev, struct scatterlist *sgl,
|
||||
struct hisi_acc_hw_sgl *hw_sgl);
|
||||
int hisi_acc_create_sgl_pool(struct device *dev, struct hisi_acc_sgl_pool *pool,
|
||||
u32 count);
|
||||
void hisi_acc_free_sgl_pool(struct device *dev, struct hisi_acc_sgl_pool *pool);
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
menuconfig UACCE
|
||||
tristate "Accelerator Framework for User Land"
|
||||
depends on IOMMU_API
|
||||
select ANON_INODES
|
||||
help
|
||||
UACCE provides interface for the user process to access the hardware
|
||||
without interaction with the kernel space in data path.
|
||||
|
||||
See Documentation/warpdrive/warpdrive.rst for more details.
|
||||
|
||||
If you don't know what to do here, say N.
|
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
obj-$(CONFIG_UACCE) += uacce.o
|
File diff suppressed because it is too large
Load Diff
|
@ -1,75 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2019 HiSilicon Limited. */
|
||||
#ifndef HISI_ZIP_H
|
||||
#define HISI_ZIP_H
|
||||
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "hisi_zip: " fmt
|
||||
|
||||
#include <linux/list.h>
|
||||
#include "../qm.h"
|
||||
#include "../sgl.h"
|
||||
|
||||
/* hisi_zip_sqe dw3 */
|
||||
#define HZIP_BD_STATUS_M GENMASK(7, 0)
|
||||
/* hisi_zip_sqe dw7 */
|
||||
#define HZIP_IN_SGE_DATA_OFFSET_M GENMASK(23, 0)
|
||||
/* hisi_zip_sqe dw8 */
|
||||
#define HZIP_OUT_SGE_DATA_OFFSET_M GENMASK(23, 0)
|
||||
/* hisi_zip_sqe dw9 */
|
||||
#define HZIP_REQ_TYPE_M GENMASK(7, 0)
|
||||
#define HZIP_ALG_TYPE_ZLIB 0x02
|
||||
#define HZIP_ALG_TYPE_GZIP 0x03
|
||||
#define HZIP_BUF_TYPE_M GENMASK(11, 8)
|
||||
#define HZIP_PBUFFER 0x0
|
||||
#define HZIP_SGL 0x1
|
||||
|
||||
enum hisi_zip_error_type {
|
||||
/* negative compression */
|
||||
HZIP_NC_ERR = 0x0d,
|
||||
};
|
||||
|
||||
struct hisi_zip_ctrl;
|
||||
|
||||
struct hisi_zip {
|
||||
struct hisi_qm qm;
|
||||
struct list_head list;
|
||||
struct hisi_zip_ctrl *ctrl;
|
||||
};
|
||||
|
||||
struct hisi_zip_sqe {
|
||||
u32 consumed;
|
||||
u32 produced;
|
||||
u32 comp_data_length;
|
||||
u32 dw3;
|
||||
u32 input_data_length;
|
||||
u32 lba_l;
|
||||
u32 lba_h;
|
||||
u32 dw7;
|
||||
u32 dw8;
|
||||
u32 dw9;
|
||||
u32 dw10;
|
||||
u32 priv_info;
|
||||
u32 dw12;
|
||||
u32 tag;
|
||||
u32 dest_avail_out;
|
||||
u32 rsvd0;
|
||||
u32 comp_head_addr_l;
|
||||
u32 comp_head_addr_h;
|
||||
u32 source_addr_l;
|
||||
u32 source_addr_h;
|
||||
u32 dest_addr_l;
|
||||
u32 dest_addr_h;
|
||||
u32 stream_ctx_addr_l;
|
||||
u32 stream_ctx_addr_h;
|
||||
u32 cipher_key1_addr_l;
|
||||
u32 cipher_key1_addr_h;
|
||||
u32 cipher_key2_addr_l;
|
||||
u32 cipher_key2_addr_h;
|
||||
u32 rsvd1[4];
|
||||
};
|
||||
|
||||
struct hisi_zip *find_zip_device(int node);
|
||||
int hisi_zip_register_to_crypto(void);
|
||||
void hisi_zip_unregister_from_crypto(void);
|
||||
#endif
|
|
@ -5663,8 +5663,13 @@ CONFIG_CRYPTO_DEV_CCP_CRYPTO=m
|
|||
CONFIG_CRYPTO_DEV_VIRTIO=m
|
||||
# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
|
||||
# CONFIG_CRYPTO_DEV_CCREE is not set
|
||||
# CONFIG_CRYPTO_DEV_HISI_SEC is not set
|
||||
# CONFIG_CRYPTO_DEV_HISI_ZIP is not set
|
||||
CONFIG_CRYPTO_DEV_HISI_QM=m
|
||||
CONFIG_CRYPTO_QM_UACCE=y
|
||||
CONFIG_CRYPTO_DEV_HISI_ZIP=m
|
||||
CONFIG_CRYPTO_DEV_HISI_HPRE=m
|
||||
CONFIG_CRYPTO_DEV_HISI_SEC2=m
|
||||
CONFIG_CRYPTO_DEV_HISI_RDE=m
|
||||
CONFIG_UACCE=m
|
||||
CONFIG_ASYMMETRIC_KEY_TYPE=y
|
||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
|
||||
CONFIG_X509_CERTIFICATE_PARSER=y
|
||||
|
|
|
@ -5745,8 +5745,13 @@ CONFIG_CRYPTO_DEV_CCP_CRYPTO=m
|
|||
CONFIG_CRYPTO_DEV_VIRTIO=m
|
||||
# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
|
||||
# CONFIG_CRYPTO_DEV_CCREE is not set
|
||||
# CONFIG_CRYPTO_DEV_HISI_SEC is not set
|
||||
# CONFIG_CRYPTO_DEV_HISI_ZIP is not set
|
||||
CONFIG_CRYPTO_DEV_HISI_QM=m
|
||||
CONFIG_CRYPTO_QM_UACCE=y
|
||||
CONFIG_CRYPTO_DEV_HISI_ZIP=m
|
||||
CONFIG_CRYPTO_DEV_HISI_HPRE=m
|
||||
CONFIG_CRYPTO_DEV_HISI_SEC2=m
|
||||
CONFIG_CRYPTO_DEV_HISI_RDE=m
|
||||
CONFIG_UACCE=m
|
||||
CONFIG_ASYMMETRIC_KEY_TYPE=y
|
||||
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
|
||||
CONFIG_X509_CERTIFICATE_PARSER=y
|
||||
|
|
Loading…
Reference in New Issue