Skip to content

Commit 3296992

Browse files
Weili Qianherbertx
authored andcommitted
crypto: hisilicon/qm - obtain the mailbox configuration at one time
The malibox needs to be triggered by a 128bit atomic operation. The reason is that the PF and VFs of the device share the mmio memory of the mailbox, and the mutex cannot lock mailbox operations in different functions, especially when passing through VFs to virtual machines. Currently, the write operation to the mailbox is already a 128-bit atomic write. The read operation also needs to be modified to a 128-bit atomic read. Since there is no general 128-bit IO memory access API in the current ARM64 architecture, and the stp and ldp instructions do not guarantee atomic access to device memory, they cannot be extracted as a general API. Therefore, the 128-bit atomic read and write operations need to be implemented in the driver. Signed-off-by: Weili Qian <qianweili@huawei.com> Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent fc8ae11 commit 3296992

2 files changed

Lines changed: 87 additions & 47 deletions

File tree

drivers/crypto/hisilicon/qm.c

Lines changed: 86 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
/* mailbox */
3232
#define QM_MB_PING_ALL_VFS 0xffff
3333
#define QM_MB_STATUS_MASK GENMASK(12, 9)
34+
#define QM_MB_BUSY_MASK BIT(13)
3435

3536
/* sqc shift */
3637
#define QM_SQ_HOP_NUM_SHIFT 0
@@ -582,16 +583,30 @@ static void qm_mb_pre_init(struct qm_mailbox *mailbox, u8 cmd,
582583
mailbox->rsvd = 0;
583584
}
584585

585-
/* return 0 mailbox ready, -ETIMEDOUT hardware timeout */
586-
int hisi_qm_wait_mb_ready(struct hisi_qm *qm)
586+
/*
587+
* The mailbox is 128 bits and requires a single read/write operation.
588+
* Since there is no general 128-bit IO memory access API in the current
589+
* ARM64 architecture, this needs to be implemented in the driver.
590+
*/
591+
static struct qm_mailbox qm_mb_read(struct hisi_qm *qm)
587592
{
588-
u32 val;
593+
struct qm_mailbox mailbox = {0};
594+
595+
#if IS_ENABLED(CONFIG_ARM64)
596+
const void __iomem *fun_base = qm->io_base + QM_MB_CMD_SEND_BASE;
597+
unsigned long tmp0, tmp1;
589598

590-
return readl_relaxed_poll_timeout(qm->io_base + QM_MB_CMD_SEND_BASE,
591-
val, !((val >> QM_MB_BUSY_SHIFT) &
592-
0x1), POLL_PERIOD, POLL_TIMEOUT);
599+
asm volatile("ldp %0, %1, %3\n"
600+
"stp %0, %1, %2\n"
601+
: "=&r" (tmp0),
602+
"=&r" (tmp1),
603+
"+Q" (mailbox)
604+
: "Q" (*((char __iomem *)fun_base))
605+
: "memory");
606+
#endif
607+
608+
return mailbox;
593609
}
594-
EXPORT_SYMBOL_GPL(hisi_qm_wait_mb_ready);
595610

596611
/* 128 bit should be written to hardware at one time to trigger a mailbox */
597612
static void qm_mb_write(struct hisi_qm *qm, const void *src)
@@ -614,35 +629,61 @@ static void qm_mb_write(struct hisi_qm *qm, const void *src)
614629
#endif
615630
}
616631

617-
static int qm_mb_nolock(struct hisi_qm *qm, struct qm_mailbox *mailbox)
632+
int hisi_qm_wait_mb_ready(struct hisi_qm *qm)
618633
{
634+
struct qm_mailbox mailbox = {0};
619635
int ret;
620-
u32 val;
621636

622-
if (unlikely(hisi_qm_wait_mb_ready(qm))) {
637+
ret = read_poll_timeout(qm_mb_read, mailbox,
638+
!(le16_to_cpu(mailbox.w0) & QM_MB_BUSY_MASK),
639+
POLL_PERIOD, POLL_TIMEOUT,
640+
true, qm);
641+
if (ret)
623642
dev_err(&qm->pdev->dev, "QM mailbox is busy to start!\n");
624-
ret = -EBUSY;
625-
goto mb_busy;
626-
}
627643

628-
qm_mb_write(qm, mailbox);
644+
return ret;
645+
}
646+
EXPORT_SYMBOL_GPL(hisi_qm_wait_mb_ready);
647+
648+
static int qm_wait_mb_finish(struct hisi_qm *qm, struct qm_mailbox *mailbox)
649+
{
650+
struct device *dev = &qm->pdev->dev;
651+
int ret;
629652

630-
if (unlikely(hisi_qm_wait_mb_ready(qm))) {
631-
dev_err(&qm->pdev->dev, "QM mailbox operation timeout!\n");
632-
ret = -ETIMEDOUT;
633-
goto mb_busy;
653+
ret = read_poll_timeout(qm_mb_read, *mailbox,
654+
!(le16_to_cpu(mailbox->w0) & QM_MB_BUSY_MASK),
655+
POLL_PERIOD, POLL_TIMEOUT,
656+
true, qm);
657+
if (ret) {
658+
dev_err(dev, "QM mailbox operation timeout!\n");
659+
return ret;
634660
}
635661

636-
val = readl(qm->io_base + QM_MB_CMD_SEND_BASE);
637-
if (val & QM_MB_STATUS_MASK) {
638-
dev_err(&qm->pdev->dev, "QM mailbox operation failed!\n");
639-
ret = -EIO;
640-
goto mb_busy;
662+
if (le16_to_cpu(mailbox->w0) & QM_MB_STATUS_MASK) {
663+
dev_err(dev, "QM mailbox operation failed!\n");
664+
return -EIO;
641665
}
642666

643667
return 0;
668+
}
669+
670+
static int qm_mb_nolock(struct hisi_qm *qm, struct qm_mailbox *mailbox)
671+
{
672+
int ret;
673+
674+
ret = hisi_qm_wait_mb_ready(qm);
675+
if (ret)
676+
goto mb_err_cnt_increase;
677+
678+
qm_mb_write(qm, mailbox);
679+
680+
ret = qm_wait_mb_finish(qm, mailbox);
681+
if (ret)
682+
goto mb_err_cnt_increase;
683+
684+
return 0;
644685

645-
mb_busy:
686+
mb_err_cnt_increase:
646687
atomic64_inc(&qm->debug.dfx.mb_err_cnt);
647688
return ret;
648689
}
@@ -663,6 +704,25 @@ int hisi_qm_mb(struct hisi_qm *qm, u8 cmd, dma_addr_t dma_addr, u16 queue,
663704
}
664705
EXPORT_SYMBOL_GPL(hisi_qm_mb);
665706

707+
int hisi_qm_mb_read(struct hisi_qm *qm, u64 *base, u8 cmd, u16 queue)
708+
{
709+
struct qm_mailbox mailbox;
710+
int ret;
711+
712+
qm_mb_pre_init(&mailbox, cmd, 0, queue, 1);
713+
mutex_lock(&qm->mailbox_lock);
714+
ret = qm_mb_nolock(qm, &mailbox);
715+
mutex_unlock(&qm->mailbox_lock);
716+
if (ret)
717+
return ret;
718+
719+
*base = le32_to_cpu(mailbox.base_l) |
720+
((u64)le32_to_cpu(mailbox.base_h) << 32);
721+
722+
return 0;
723+
}
724+
EXPORT_SYMBOL_GPL(hisi_qm_mb_read);
725+
666726
/* op 0: set xqc information to hardware, 1: get xqc information from hardware. */
667727
int qm_set_and_get_xqc(struct hisi_qm *qm, u8 cmd, void *xqc, u32 qp_id, bool op)
668728
{
@@ -1379,12 +1439,10 @@ static int qm_get_vft_v2(struct hisi_qm *qm, u32 *base, u32 *number)
13791439
u64 sqc_vft;
13801440
int ret;
13811441

1382-
ret = hisi_qm_mb(qm, QM_MB_CMD_SQC_VFT_V2, 0, 0, 1);
1442+
ret = hisi_qm_mb_read(qm, &sqc_vft, QM_MB_CMD_SQC_VFT_V2, 0);
13831443
if (ret)
13841444
return ret;
13851445

1386-
sqc_vft = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) |
1387-
((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32);
13881446
*base = QM_SQC_VFT_BASE_MASK_V2 & (sqc_vft >> QM_SQC_VFT_BASE_SHIFT_V2);
13891447
*number = (QM_SQC_VFT_NUM_MASK_V2 &
13901448
(sqc_vft >> QM_SQC_VFT_NUM_SHIFT_V2)) + 1;
@@ -1524,25 +1582,6 @@ static enum acc_err_result qm_hw_error_handle_v2(struct hisi_qm *qm)
15241582
return ACC_ERR_RECOVERED;
15251583
}
15261584

1527-
static int qm_get_mb_cmd(struct hisi_qm *qm, u64 *msg, u16 fun_num)
1528-
{
1529-
struct qm_mailbox mailbox;
1530-
int ret;
1531-
1532-
qm_mb_pre_init(&mailbox, QM_MB_CMD_DST, 0, fun_num, 0);
1533-
mutex_lock(&qm->mailbox_lock);
1534-
ret = qm_mb_nolock(qm, &mailbox);
1535-
if (ret)
1536-
goto err_unlock;
1537-
1538-
*msg = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) |
1539-
((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32);
1540-
1541-
err_unlock:
1542-
mutex_unlock(&qm->mailbox_lock);
1543-
return ret;
1544-
}
1545-
15461585
static void qm_clear_cmd_interrupt(struct hisi_qm *qm, u64 vf_mask)
15471586
{
15481587
u32 val;
@@ -1871,7 +1910,7 @@ static int qm_get_ifc_v3(struct hisi_qm *qm, enum qm_ifc_cmd *cmd, u32 *data, u3
18711910
u64 msg;
18721911
int ret;
18731912

1874-
ret = qm_get_mb_cmd(qm, &msg, fun_num);
1913+
ret = hisi_qm_mb_read(qm, &msg, QM_MB_CMD_DST, fun_num);
18751914
if (ret)
18761915
return ret;
18771916

include/linux/hisi_acc_qm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ void hisi_qm_reset_done(struct pci_dev *pdev);
571571
int hisi_qm_wait_mb_ready(struct hisi_qm *qm);
572572
int hisi_qm_mb(struct hisi_qm *qm, u8 cmd, dma_addr_t dma_addr, u16 queue,
573573
bool op);
574+
int hisi_qm_mb_read(struct hisi_qm *qm, u64 *base, u8 cmd, u16 queue);
574575

575576
struct hisi_acc_sgl_pool;
576577
struct hisi_acc_hw_sgl *hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,

0 commit comments

Comments
 (0)