Skip to content

Commit 7ce396f

Browse files
tsk-lieacuiherbertx
authored andcommitted
crypto: hisilicon - add FLR support
Add callback reset_prepare and reset_done in QM, The callback reset_prepare will uninit device error configuration and stop the QM, the callback reset_done will init the device error configuration and restart the QM. Uninit the error configuration will disable device block master OOO when Multi-bit ECC error occurs to avoid the request of FLR will not return. Signed-off-by: Shukun Tan <[email protected]> Reviewed-by: Zhou Wang <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent b67202e commit 7ce396f

File tree

5 files changed

+165
-4
lines changed

5 files changed

+165
-4
lines changed

drivers/crypto/hisilicon/hpre/hpre_main.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,21 @@ static void hpre_cnt_regs_clear(struct hisi_qm *qm)
310310

311311
static void hpre_hw_error_disable(struct hisi_qm *qm)
312312
{
313+
u32 val;
314+
313315
/* disable hpre hw error interrupts */
314316
writel(HPRE_CORE_INT_DISABLE, qm->io_base + HPRE_INT_MASK);
317+
318+
/* disable HPRE block master OOO when m-bit error occur */
319+
val = readl(qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
320+
val &= ~HPRE_AM_OOO_SHUTDOWN_ENABLE;
321+
writel(val, qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
315322
}
316323

317324
static void hpre_hw_error_enable(struct hisi_qm *qm)
318325
{
326+
u32 val;
327+
319328
/* clear HPRE hw error source if having */
320329
writel(HPRE_CORE_INT_DISABLE, qm->io_base + HPRE_HAC_SOURCE_INT);
321330

@@ -324,6 +333,11 @@ static void hpre_hw_error_enable(struct hisi_qm *qm)
324333
writel(HPRE_HAC_RAS_CE_ENABLE, qm->io_base + HPRE_RAS_CE_ENB);
325334
writel(HPRE_HAC_RAS_NFE_ENABLE, qm->io_base + HPRE_RAS_NFE_ENB);
326335
writel(HPRE_HAC_RAS_FE_ENABLE, qm->io_base + HPRE_RAS_FE_ENB);
336+
337+
/* enable HPRE block master OOO when m-bit error occur */
338+
val = readl(qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
339+
val |= HPRE_AM_OOO_SHUTDOWN_ENABLE;
340+
writel(val, qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
327341
}
328342

329343
static inline struct hisi_qm *hpre_file_to_qm(struct hpre_debugfs_file *file)
@@ -851,6 +865,8 @@ static void hpre_remove(struct pci_dev *pdev)
851865
static const struct pci_error_handlers hpre_err_handler = {
852866
.error_detected = hisi_qm_dev_err_detected,
853867
.slot_reset = hisi_qm_dev_slot_reset,
868+
.reset_prepare = hisi_qm_reset_prepare,
869+
.reset_done = hisi_qm_reset_done,
854870
};
855871

856872
static struct pci_driver hpre_pci_driver = {

drivers/crypto/hisilicon/qm.c

Lines changed: 129 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@
175175
#define QMC_ALIGN(sz) ALIGN(sz, 32)
176176

177177
#define QM_DBG_TMP_BUF_LEN 22
178+
#define QM_PCI_COMMAND_INVALID ~0
178179

179180
#define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \
180181
(((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \
@@ -2874,6 +2875,11 @@ pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
28742875
}
28752876
EXPORT_SYMBOL_GPL(hisi_qm_dev_err_detected);
28762877

2878+
static int qm_get_hw_error_status(struct hisi_qm *qm)
2879+
{
2880+
return readl(qm->io_base + QM_ABNORMAL_INT_STATUS);
2881+
}
2882+
28772883
static int qm_check_req_recv(struct hisi_qm *qm)
28782884
{
28792885
struct pci_dev *pdev = qm->pdev;
@@ -3166,9 +3172,7 @@ static int qm_vf_reset_done(struct hisi_qm *qm)
31663172

31673173
static int qm_get_dev_err_status(struct hisi_qm *qm)
31683174
{
3169-
3170-
return(qm->err_ini->get_dev_hw_err_status(qm) &
3171-
qm->err_ini->err_info.ecc_2bits_mask);
3175+
return qm->err_ini->get_dev_hw_err_status(qm);
31723176
}
31733177

31743178
static int qm_dev_hw_init(struct hisi_qm *qm)
@@ -3190,7 +3194,8 @@ static void qm_restart_prepare(struct hisi_qm *qm)
31903194
qm->io_base + ACC_AM_CFG_PORT_WR_EN);
31913195

31923196
/* clear dev ecc 2bit error source if having */
3193-
value = qm_get_dev_err_status(qm);
3197+
value = qm_get_dev_err_status(qm) &
3198+
qm->err_ini->err_info.ecc_2bits_mask;
31943199
if (value && qm->err_ini->clear_dev_hw_err_status)
31953200
qm->err_ini->clear_dev_hw_err_status(qm, value);
31963201

@@ -3336,6 +3341,126 @@ pci_ers_result_t hisi_qm_dev_slot_reset(struct pci_dev *pdev)
33363341
}
33373342
EXPORT_SYMBOL_GPL(hisi_qm_dev_slot_reset);
33383343

3344+
/* check the interrupt is ecc-mbit error or not */
3345+
static int qm_check_dev_error(struct hisi_qm *qm)
3346+
{
3347+
int ret;
3348+
3349+
if (qm->fun_type == QM_HW_VF)
3350+
return 0;
3351+
3352+
ret = qm_get_hw_error_status(qm) & QM_ECC_MBIT;
3353+
if (ret)
3354+
return ret;
3355+
3356+
return (qm_get_dev_err_status(qm) &
3357+
qm->err_ini->err_info.ecc_2bits_mask);
3358+
}
3359+
3360+
void hisi_qm_reset_prepare(struct pci_dev *pdev)
3361+
{
3362+
struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev));
3363+
struct hisi_qm *qm = pci_get_drvdata(pdev);
3364+
u32 delay = 0;
3365+
int ret;
3366+
3367+
hisi_qm_dev_err_uninit(pf_qm);
3368+
3369+
/*
3370+
* Check whether there is an ECC mbit error, If it occurs, need to
3371+
* wait for soft reset to fix it.
3372+
*/
3373+
while (qm_check_dev_error(pf_qm)) {
3374+
msleep(++delay);
3375+
if (delay > QM_RESET_WAIT_TIMEOUT)
3376+
return;
3377+
}
3378+
3379+
ret = qm_reset_prepare_ready(qm);
3380+
if (ret) {
3381+
pci_err(pdev, "FLR not ready!\n");
3382+
return;
3383+
}
3384+
3385+
if (qm->vfs_num) {
3386+
ret = qm_vf_reset_prepare(qm);
3387+
if (ret) {
3388+
pci_err(pdev, "Failed to prepare reset, ret = %d.\n",
3389+
ret);
3390+
return;
3391+
}
3392+
}
3393+
3394+
ret = hisi_qm_stop(qm);
3395+
if (ret) {
3396+
pci_err(pdev, "Failed to stop QM, ret = %d.\n", ret);
3397+
return;
3398+
}
3399+
3400+
pci_info(pdev, "FLR resetting...\n");
3401+
}
3402+
EXPORT_SYMBOL_GPL(hisi_qm_reset_prepare);
3403+
3404+
static bool qm_flr_reset_complete(struct pci_dev *pdev)
3405+
{
3406+
struct pci_dev *pf_pdev = pci_physfn(pdev);
3407+
struct hisi_qm *qm = pci_get_drvdata(pf_pdev);
3408+
u32 id;
3409+
3410+
pci_read_config_dword(qm->pdev, PCI_COMMAND, &id);
3411+
if (id == QM_PCI_COMMAND_INVALID) {
3412+
pci_err(pdev, "Device can not be used!\n");
3413+
return false;
3414+
}
3415+
3416+
clear_bit(QM_DEV_RESET_FLAG, &qm->reset_flag);
3417+
3418+
return true;
3419+
}
3420+
3421+
void hisi_qm_reset_done(struct pci_dev *pdev)
3422+
{
3423+
struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev));
3424+
struct hisi_qm *qm = pci_get_drvdata(pdev);
3425+
int ret;
3426+
3427+
hisi_qm_dev_err_init(pf_qm);
3428+
3429+
ret = qm_restart(qm);
3430+
if (ret) {
3431+
pci_err(pdev, "Failed to start QM, ret = %d.\n", ret);
3432+
goto flr_done;
3433+
}
3434+
3435+
if (qm->fun_type == QM_HW_PF) {
3436+
ret = qm_dev_hw_init(qm);
3437+
if (ret) {
3438+
pci_err(pdev, "Failed to init PF, ret = %d.\n", ret);
3439+
goto flr_done;
3440+
}
3441+
3442+
if (!qm->vfs_num)
3443+
goto flr_done;
3444+
3445+
ret = qm_vf_q_assign(qm, qm->vfs_num);
3446+
if (ret) {
3447+
pci_err(pdev, "Failed to assign VFs, ret = %d.\n", ret);
3448+
goto flr_done;
3449+
}
3450+
3451+
ret = qm_vf_reset_done(qm);
3452+
if (ret) {
3453+
pci_err(pdev, "Failed to start VFs, ret = %d.\n", ret);
3454+
goto flr_done;
3455+
}
3456+
}
3457+
3458+
flr_done:
3459+
if (qm_flr_reset_complete(pdev))
3460+
pci_info(pdev, "FLR reset complete\n");
3461+
}
3462+
EXPORT_SYMBOL_GPL(hisi_qm_reset_done);
3463+
33393464
MODULE_LICENSE("GPL v2");
33403465
MODULE_AUTHOR("Zhou Wang <[email protected]>");
33413466
MODULE_DESCRIPTION("HiSilicon Accelerator queue manager driver");

drivers/crypto/hisilicon/qm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ void hisi_qm_dev_err_uninit(struct hisi_qm *qm);
371371
pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
372372
pci_channel_state_t state);
373373
pci_ers_result_t hisi_qm_dev_slot_reset(struct pci_dev *pdev);
374+
void hisi_qm_reset_prepare(struct pci_dev *pdev);
375+
void hisi_qm_reset_done(struct pci_dev *pdev);
374376

375377
struct hisi_acc_sgl_pool;
376378
struct hisi_acc_hw_sgl *hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,

drivers/crypto/hisilicon/sec2/sec_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,8 @@ static void sec_remove(struct pci_dev *pdev)
914914
static const struct pci_error_handlers sec_err_handler = {
915915
.error_detected = hisi_qm_dev_err_detected,
916916
.slot_reset = hisi_qm_dev_slot_reset,
917+
.reset_prepare = hisi_qm_reset_prepare,
918+
.reset_done = hisi_qm_reset_done,
917919
};
918920

919921
static struct pci_driver sec_pci_driver = {

drivers/crypto/hisilicon/zip/zip_main.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm)
278278

279279
static void hisi_zip_hw_error_enable(struct hisi_qm *qm)
280280
{
281+
u32 val;
282+
281283
if (qm->ver == QM_HW_V1) {
282284
writel(HZIP_CORE_INT_MASK_ALL,
283285
qm->io_base + HZIP_CORE_INT_MASK_REG);
@@ -296,12 +298,24 @@ static void hisi_zip_hw_error_enable(struct hisi_qm *qm)
296298

297299
/* enable ZIP hw error interrupts */
298300
writel(0, qm->io_base + HZIP_CORE_INT_MASK_REG);
301+
302+
/* enable ZIP block master OOO when m-bit error occur */
303+
val = readl(qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
304+
val = val | HZIP_AXI_SHUTDOWN_ENABLE;
305+
writel(val, qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
299306
}
300307

301308
static void hisi_zip_hw_error_disable(struct hisi_qm *qm)
302309
{
310+
u32 val;
311+
303312
/* disable ZIP hw error interrupts */
304313
writel(HZIP_CORE_INT_MASK_ALL, qm->io_base + HZIP_CORE_INT_MASK_REG);
314+
315+
/* disable ZIP block master OOO when m-bit error occur */
316+
val = readl(qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
317+
val = val & ~HZIP_AXI_SHUTDOWN_ENABLE;
318+
writel(val, qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
305319
}
306320

307321
static inline struct hisi_qm *file_to_qm(struct ctrl_debug_file *file)
@@ -802,6 +816,8 @@ static void hisi_zip_remove(struct pci_dev *pdev)
802816
static const struct pci_error_handlers hisi_zip_err_handler = {
803817
.error_detected = hisi_qm_dev_err_detected,
804818
.slot_reset = hisi_qm_dev_slot_reset,
819+
.reset_prepare = hisi_qm_reset_prepare,
820+
.reset_done = hisi_qm_reset_done,
805821
};
806822

807823
static struct pci_driver hisi_zip_pci_driver = {

0 commit comments

Comments
 (0)