diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index ab8309dff7dd2eb34cc9f650b2c00b10bbfa6736..fb71859c04a613149b5f54bbdb66311e589c2342 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -1446,24 +1446,28 @@ static int hisi_qm_uacce_mmap(struct uacce_queue *q, size_t sz = vma->vm_end - vma->vm_start; struct pci_dev *pdev = qm->pdev; struct device *dev = &pdev->dev; - unsigned long long mmio_base; unsigned long vm_pgoff; int ret; switch (qfr->type) { case UACCE_QFRT_MMIO: - WARN_ON(sz > PAGE_SIZE); - vma->vm_flags |= VM_IO; - if (qm->ver == QM_HW_V1) - mmio_base = qm->phys_base; + + /* Try to mmap corresponding pages size region */ + if (qm->ver == QM_HW_V2) + WARN_ON(sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR + + QM_V2_DOORBELL_OFFSET / PAGE_SIZE)); else - mmio_base = qm->phys_base + QM_V2_BASE_OFFSET; + WARN_ON(sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR); + + vma->vm_flags |= VM_IO; + /* - * Warning: This is not safe as multiple queues use the same - * doorbell, v1 hardware interface problem. will fix it in v2 + * Warning: This is not safe as multiple processes use the same + * doorbell, v1/v2 hardware interface problem. It will be fixed + * it in next version. */ return remap_pfn_range(vma, vma->vm_start, - mmio_base >> PAGE_SHIFT, + qm->phys_base >> PAGE_SHIFT, sz, pgprot_noncached(vma->vm_page_prot)); case UACCE_QFRT_DUS: if (qm->use_dma_api) { @@ -2009,6 +2013,7 @@ int hisi_qm_start(struct hisi_qm *qm) struct uacce_ops *ops = qm->uacce.ops; unsigned long dus_page_nr = 0; unsigned long dko_page_nr = 0; + unsigned long mmio_page_nr; if (qm->use_uacce) { dus_page_nr = (PAGE_SIZE - 1 + qm->sqe_size * QM_Q_DEPTH + @@ -2032,18 +2037,21 @@ int hisi_qm_start(struct hisi_qm *qm) /* reset qfr definition */ #ifdef CONFIG_CRYPTO_QM_UACCE + if (qm->ver == QM_HW_V2) + mmio_page_nr = QM_DOORBELL_PAGE_NR + + QM_V2_DOORBELL_OFFSET / PAGE_SIZE; + else + mmio_page_nr = QM_DOORBELL_PAGE_NR; if (qm->use_uacce && qm->use_dma_api) { ops->qf_pg_start[UACCE_QFRT_MMIO] = 0; ops->qf_pg_start[UACCE_QFRT_DKO] = UACCE_QFR_NA; - ops->qf_pg_start[UACCE_QFRT_DUS] = QM_DOORBELL_PAGE_NR; - ops->qf_pg_start[UACCE_QFRT_SS] = QM_DOORBELL_PAGE_NR + - dus_page_nr; + ops->qf_pg_start[UACCE_QFRT_DUS] = mmio_page_nr; + ops->qf_pg_start[UACCE_QFRT_SS] = mmio_page_nr + dus_page_nr; } else if (qm->use_uacce) { ops->qf_pg_start[UACCE_QFRT_MMIO] = 0; - ops->qf_pg_start[UACCE_QFRT_DKO] = QM_DOORBELL_PAGE_NR; - ops->qf_pg_start[UACCE_QFRT_DUS] = QM_DOORBELL_PAGE_NR + - dko_page_nr; - ops->qf_pg_start[UACCE_QFRT_SS] = QM_DOORBELL_PAGE_NR + + ops->qf_pg_start[UACCE_QFRT_DKO] = mmio_page_nr; + ops->qf_pg_start[UACCE_QFRT_DUS] = mmio_page_nr + dko_page_nr; + ops->qf_pg_start[UACCE_QFRT_SS] = mmio_page_nr + dko_page_nr + dus_page_nr; } diff --git a/drivers/crypto/hisilicon/qm_usr_if.h b/drivers/crypto/hisilicon/qm_usr_if.h index ca88e6d8dd7a998909bc990002179fc5b8ca7f3d..a8086ae0f3b82e1d20e0aa655b908528d84604db 100644 --- a/drivers/crypto/hisilicon/qm_usr_if.h +++ b/drivers/crypto/hisilicon/qm_usr_if.h @@ -8,10 +8,11 @@ #define QM_Q_DEPTH 1024 /* page number for queue file region */ -#define QM_DOORBELL_PAGE_NR 1 +#define QM_DOORBELL_PAGE_NR 1 -#define QM_DOORBELL_OFFSET 0x340 +#define QM_DOORBELL_OFFSET 0x340 +#define QM_V2_DOORBELL_OFFSET 0x1000 struct cqe { __le32 rsvd0; diff --git a/drivers/uacce/uacce.c b/drivers/uacce/uacce.c index 00d252100073d746a184a9cb90177a5e6f110af1..df8d0a81fcc21468753f3da9c1dc919c1b759314 100644 --- a/drivers/uacce/uacce.c +++ b/drivers/uacce/uacce.c @@ -920,22 +920,27 @@ uacce_dev_show_algorithms(struct device *dev, static DEVICE_ATTR(algorithms, S_IRUGO, uacce_dev_show_algorithms, NULL); -static ssize_t -uacce_dev_show_qfrs_pg_start(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t uacce_dev_show_qfrs_offset(struct device *dev, + struct device_attribute *attr, + char *buf) { struct uacce *uacce = UACCE_FROM_CDEV_ATTR(dev); int i, ret; + unsigned long offset; - for (i = 0, ret = 0; i < UACCE_QFRT_MAX - 1; i++) - ret += sprintf(buf + ret, "%lu\t", uacce->ops->qf_pg_start[i]); - - ret += sprintf(buf + ret, "%lu\n", uacce->ops->qf_pg_start[i]); + for (i = 0, ret = 0; i < UACCE_QFRT_MAX; i++) { + offset = uacce->ops->qf_pg_start[i]; + if (offset != UACCE_QFR_NA) + offset = offset << PAGE_SHIFT; + if (i == UACCE_QFRT_SS) + break; + ret += sprintf(buf + ret, "%lu\t", offset); + } + ret += sprintf(buf + ret, "%lu\n", offset); return ret; } - -static DEVICE_ATTR(qfrs_pg_start, S_IRUGO, uacce_dev_show_qfrs_pg_start, NULL); +static DEVICE_ATTR(qfrs_offset, S_IRUGO, uacce_dev_show_qfrs_offset, NULL); static struct attribute *uacce_dev_attrs[] = { &dev_attr_id.attr, @@ -945,7 +950,7 @@ static struct attribute *uacce_dev_attrs[] = { &dev_attr_flags.attr, &dev_attr_available_instances.attr, &dev_attr_algorithms.attr, - &dev_attr_qfrs_pg_start.attr, + &dev_attr_qfrs_offset.attr, NULL, };