crypto: hisilicon - fix driver compatibility issue with different versions of devices

In order to be compatible with devices of different versions, V1 in the
accelerator driver is now isolated, and other versions are the previous
V2 processing flow.

Signed-off-by: Weili Qian <qianweili@huawei.com>
Signed-off-by: Shukun Tan <tanshukun1@huawei.com>
Reviewed-by: Zhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Weili Qian 2020-05-20 17:19:50 +08:00 коммит произвёл Herbert Xu
Родитель d1c72f6e4c
Коммит 58ca0060ec
5 изменённых файлов: 39 добавлений и 112 удалений

Просмотреть файл

@ -717,19 +717,13 @@ static void hpre_debugfs_exit(struct hpre *hpre)
static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
enum qm_hw_ver rev_id;
rev_id = hisi_qm_get_hw_version(pdev);
if (rev_id < 0)
return -ENODEV;
if (rev_id == QM_HW_V1) {
if (pdev->revision == QM_HW_V1) {
pci_warn(pdev, "HPRE version 1 is not supported!\n");
return -EINVAL;
}
qm->pdev = pdev;
qm->ver = rev_id;
qm->ver = pdev->revision;
qm->sqe_size = HPRE_SQE_SIZE;
qm->dev_name = hpre_name;

Просмотреть файл

@ -737,13 +737,14 @@ static void qm_irq_unregister(struct hisi_qm *qm)
free_irq(pci_irq_vector(pdev, QM_EQ_EVENT_IRQ_VECTOR), qm);
if (qm->ver == QM_HW_V2) {
free_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR), qm);
if (qm->ver == QM_HW_V1)
return;
if (qm->fun_type == QM_HW_PF)
free_irq(pci_irq_vector(pdev,
QM_ABNORMAL_EVENT_IRQ_VECTOR), qm);
}
free_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR), qm);
if (qm->fun_type == QM_HW_PF)
free_irq(pci_irq_vector(pdev,
QM_ABNORMAL_EVENT_IRQ_VECTOR), qm);
}
static void qm_init_qp_status(struct hisi_qp *qp)
@ -764,36 +765,26 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base,
if (number > 0) {
switch (type) {
case SQC_VFT:
switch (qm->ver) {
case QM_HW_V1:
if (qm->ver == QM_HW_V1) {
tmp = QM_SQC_VFT_BUF_SIZE |
QM_SQC_VFT_SQC_SIZE |
QM_SQC_VFT_INDEX_NUMBER |
QM_SQC_VFT_VALID |
(u64)base << QM_SQC_VFT_START_SQN_SHIFT;
break;
case QM_HW_V2:
} else {
tmp = (u64)base << QM_SQC_VFT_START_SQN_SHIFT |
QM_SQC_VFT_VALID |
(u64)(number - 1) << QM_SQC_VFT_SQN_SHIFT;
break;
case QM_HW_UNKNOWN:
break;
}
break;
case CQC_VFT:
switch (qm->ver) {
case QM_HW_V1:
if (qm->ver == QM_HW_V1) {
tmp = QM_CQC_VFT_BUF_SIZE |
QM_CQC_VFT_SQC_SIZE |
QM_CQC_VFT_INDEX_NUMBER |
QM_CQC_VFT_VALID;
break;
case QM_HW_V2:
} else {
tmp = QM_CQC_VFT_VALID;
break;
case QM_HW_UNKNOWN:
break;
}
break;
}
@ -1777,7 +1768,7 @@ static int qm_qp_ctx_cfg(struct hisi_qp *qp, int qp_id, int pasid)
if (ver == QM_HW_V1) {
sqc->dw3 = cpu_to_le32(QM_MK_SQC_DW3_V1(0, 0, 0, qm->sqe_size));
sqc->w8 = cpu_to_le16(QM_Q_DEPTH - 1);
} else if (ver == QM_HW_V2) {
} else {
sqc->dw3 = cpu_to_le32(QM_MK_SQC_DW3_V2(qm->sqe_size));
sqc->w8 = 0; /* rand_qc */
}
@ -1804,7 +1795,7 @@ static int qm_qp_ctx_cfg(struct hisi_qp *qp, int qp_id, int pasid)
if (ver == QM_HW_V1) {
cqc->dw3 = cpu_to_le32(QM_MK_CQC_DW3_V1(0, 0, 0, 4));
cqc->w8 = cpu_to_le16(QM_Q_DEPTH - 1);
} else if (ver == QM_HW_V2) {
} else {
cqc->dw3 = cpu_to_le32(QM_MK_CQC_DW3_V2(4));
cqc->w8 = 0;
}
@ -2020,12 +2011,13 @@ static void hisi_qm_cache_wb(struct hisi_qm *qm)
{
unsigned int val;
if (qm->ver == QM_HW_V2) {
writel(0x1, qm->io_base + QM_CACHE_WB_START);
if (readl_relaxed_poll_timeout(qm->io_base + QM_CACHE_WB_DONE,
val, val & BIT(0), 10, 1000))
dev_err(&qm->pdev->dev, "QM writeback sqc cache fail!\n");
}
if (qm->ver == QM_HW_V1)
return;
writel(0x1, qm->io_base + QM_CACHE_WB_START);
if (readl_relaxed_poll_timeout(qm->io_base + QM_CACHE_WB_DONE,
val, val & BIT(0), 10, 1000))
dev_err(&qm->pdev->dev, "QM writeback sqc cache fail!\n");
}
static void qm_qp_event_notifier(struct hisi_qp *qp)
@ -2082,12 +2074,12 @@ static int hisi_qm_uacce_mmap(struct uacce_queue *q,
switch (qfr->type) {
case UACCE_QFRT_MMIO:
if (qm->ver == QM_HW_V2) {
if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR +
QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE))
if (qm->ver == QM_HW_V1) {
if (sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR)
return -EINVAL;
} else {
if (sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR)
if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR +
QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE))
return -EINVAL;
}
@ -2342,16 +2334,10 @@ static void hisi_qm_pre_init(struct hisi_qm *qm)
{
struct pci_dev *pdev = qm->pdev;
switch (qm->ver) {
case QM_HW_V1:
if (qm->ver == QM_HW_V1)
qm->ops = &qm_hw_ops_v1;
break;
case QM_HW_V2:
else
qm->ops = &qm_hw_ops_v2;
break;
default:
return;
}
pci_set_drvdata(pdev, qm);
mutex_init(&qm->mailbox_lock);
@ -2859,25 +2845,6 @@ static enum acc_err_result qm_hw_error_handle(struct hisi_qm *qm)
return qm->ops->hw_error_handle(qm);
}
/**
* hisi_qm_get_hw_version() - Get hardware version of a qm.
* @pdev: The device which hardware version we want to get.
*
* This function gets the hardware version of a qm. Return QM_HW_UNKNOWN
* if the hardware version is not supported.
*/
enum qm_hw_ver hisi_qm_get_hw_version(struct pci_dev *pdev)
{
switch (pdev->revision) {
case QM_HW_V1:
case QM_HW_V2:
return pdev->revision;
default:
return QM_HW_UNKNOWN;
}
}
EXPORT_SYMBOL_GPL(hisi_qm_get_hw_version);
/**
* hisi_qm_dev_err_init() - Initialize device error configuration.
* @qm: The qm for which we want to do error initialization.
@ -3846,7 +3813,7 @@ static int qm_irq_register(struct hisi_qm *qm)
if (ret)
return ret;
if (qm->ver == QM_HW_V2) {
if (qm->ver != QM_HW_V1) {
ret = request_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR),
qm_aeq_irq, IRQF_SHARED, qm->dev_name, qm);
if (ret)
@ -3942,7 +3909,7 @@ int hisi_qm_init(struct hisi_qm *qm)
if (ret)
goto err_free_irq_vectors;
if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2) {
if (qm->fun_type == QM_HW_VF && qm->ver != QM_HW_V1) {
/* v2 starts to support get vft by mailbox */
ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
if (ret)

Просмотреть файл

@ -108,6 +108,7 @@ enum qm_hw_ver {
QM_HW_UNKNOWN = -1,
QM_HW_V1 = 0x20,
QM_HW_V2 = 0x21,
QM_HW_V3 = 0x30,
};
enum qm_fun_type {
@ -287,7 +288,6 @@ static inline int q_num_set(const char *val, const struct kernel_param *kp,
struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI,
device, NULL);
u32 n, q_num;
u8 rev_id;
int ret;
if (!val)
@ -298,17 +298,10 @@ static inline int q_num_set(const char *val, const struct kernel_param *kp,
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:
if (pdev->revision == QM_HW_V1)
q_num = QM_QNUM_V1;
break;
case QM_HW_V2:
else
q_num = QM_QNUM_V2;
break;
default:
return -EINVAL;
}
}
ret = kstrtou32(val, 10, &n);

Просмотреть файл

@ -728,18 +728,10 @@ static int sec_pf_probe_init(struct sec_dev *sec)
struct hisi_qm *qm = &sec->qm;
int ret;
switch (qm->ver) {
case QM_HW_V1:
if (qm->ver == QM_HW_V1)
qm->ctrl_qp_num = SEC_QUEUE_NUM_V1;
break;
case QM_HW_V2:
else
qm->ctrl_qp_num = SEC_QUEUE_NUM_V2;
break;
default:
return -EINVAL;
}
qm->err_ini = &sec_err_ini;
@ -755,15 +747,10 @@ static int sec_pf_probe_init(struct sec_dev *sec)
static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
enum qm_hw_ver rev_id;
int ret;
rev_id = hisi_qm_get_hw_version(pdev);
if (rev_id == QM_HW_UNKNOWN)
return -ENODEV;
qm->pdev = pdev;
qm->ver = rev_id;
qm->ver = pdev->revision;
qm->sqe_size = SEC_SQE_SIZE;
qm->dev_name = sec_name;

Просмотреть файл

@ -719,18 +719,10 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
hisi_zip->ctrl = ctrl;
ctrl->hisi_zip = hisi_zip;
switch (qm->ver) {
case QM_HW_V1:
if (qm->ver == QM_HW_V1)
qm->ctrl_qp_num = HZIP_QUEUE_NUM_V1;
break;
case QM_HW_V2:
else
qm->ctrl_qp_num = HZIP_QUEUE_NUM_V2;
break;
default:
return -EINVAL;
}
qm->err_ini = &hisi_zip_err_ini;
@ -743,14 +735,8 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
enum qm_hw_ver rev_id;
rev_id = hisi_qm_get_hw_version(pdev);
if (rev_id == QM_HW_UNKNOWN)
return -EINVAL;
qm->pdev = pdev;
qm->ver = rev_id;
qm->ver = pdev->revision;
qm->algs = "zlib\ngzip";
qm->sqe_size = HZIP_SQE_SIZE;
qm->dev_name = hisi_zip_name;