Skip to content

Commit c418ba6

Browse files
Weili Qianherbertx
authored andcommitted
crypto: hisilicon/qm - disable same error report before resetting
If an error indicating that the device needs to be reset is reported, disable the error reporting before device reset is complete, enable the error reporting after the reset is complete to prevent the same error from being reported repeatedly. Fixes: eaebf4c ("crypto: hisilicon - Unify hardware error init/uninit into QM") Signed-off-by: Weili Qian <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 2a69297 commit c418ba6

File tree

5 files changed

+110
-50
lines changed

5 files changed

+110
-50
lines changed

drivers/crypto/hisilicon/hpre/hpre_main.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,11 +1353,15 @@ static u32 hpre_get_hw_err_status(struct hisi_qm *qm)
13531353

13541354
static void hpre_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
13551355
{
1356-
u32 nfe;
1357-
13581356
writel(err_sts, qm->io_base + HPRE_HAC_SOURCE_INT);
1359-
nfe = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_NFE_MASK_CAP, qm->cap_ver);
1360-
writel(nfe, qm->io_base + HPRE_RAS_NFE_ENB);
1357+
}
1358+
1359+
static void hpre_disable_error_report(struct hisi_qm *qm, u32 err_type)
1360+
{
1361+
u32 nfe_mask;
1362+
1363+
nfe_mask = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_NFE_MASK_CAP, qm->cap_ver);
1364+
writel(nfe_mask & (~err_type), qm->io_base + HPRE_RAS_NFE_ENB);
13611365
}
13621366

13631367
static void hpre_open_axi_master_ooo(struct hisi_qm *qm)
@@ -1371,6 +1375,27 @@ static void hpre_open_axi_master_ooo(struct hisi_qm *qm)
13711375
qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
13721376
}
13731377

1378+
static enum acc_err_result hpre_get_err_result(struct hisi_qm *qm)
1379+
{
1380+
u32 err_status;
1381+
1382+
err_status = hpre_get_hw_err_status(qm);
1383+
if (err_status) {
1384+
if (err_status & qm->err_info.ecc_2bits_mask)
1385+
qm->err_status.is_dev_ecc_mbit = true;
1386+
hpre_log_hw_error(qm, err_status);
1387+
1388+
if (err_status & qm->err_info.dev_reset_mask) {
1389+
/* Disable the same error reporting until device is recovered. */
1390+
hpre_disable_error_report(qm, err_status);
1391+
return ACC_ERR_NEED_RESET;
1392+
}
1393+
hpre_clear_hw_err_status(qm, err_status);
1394+
}
1395+
1396+
return ACC_ERR_RECOVERED;
1397+
}
1398+
13741399
static void hpre_err_info_init(struct hisi_qm *qm)
13751400
{
13761401
struct hisi_qm_err_info *err_info = &qm->err_info;
@@ -1397,12 +1422,12 @@ static const struct hisi_qm_err_ini hpre_err_ini = {
13971422
.hw_err_disable = hpre_hw_error_disable,
13981423
.get_dev_hw_err_status = hpre_get_hw_err_status,
13991424
.clear_dev_hw_err_status = hpre_clear_hw_err_status,
1400-
.log_dev_hw_err = hpre_log_hw_error,
14011425
.open_axi_master_ooo = hpre_open_axi_master_ooo,
14021426
.open_sva_prefetch = hpre_open_sva_prefetch,
14031427
.close_sva_prefetch = hpre_close_sva_prefetch,
14041428
.show_last_dfx_regs = hpre_show_last_dfx_regs,
14051429
.err_info_init = hpre_err_info_init,
1430+
.get_err_result = hpre_get_err_result,
14061431
};
14071432

14081433
static int hpre_pf_probe_init(struct hpre *hpre)

drivers/crypto/hisilicon/qm.c

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,6 @@ enum vft_type {
271271
SHAPER_VFT,
272272
};
273273

274-
enum acc_err_result {
275-
ACC_ERR_NONE,
276-
ACC_ERR_NEED_RESET,
277-
ACC_ERR_RECOVERED,
278-
};
279-
280274
enum qm_alg_type {
281275
ALG_TYPE_0,
282276
ALG_TYPE_1,
@@ -1488,22 +1482,25 @@ static void qm_log_hw_error(struct hisi_qm *qm, u32 error_status)
14881482

14891483
static enum acc_err_result qm_hw_error_handle_v2(struct hisi_qm *qm)
14901484
{
1491-
u32 error_status, tmp;
1492-
1493-
/* read err sts */
1494-
tmp = readl(qm->io_base + QM_ABNORMAL_INT_STATUS);
1495-
error_status = qm->error_mask & tmp;
1485+
u32 error_status;
14961486

1497-
if (error_status) {
1487+
error_status = qm_get_hw_error_status(qm);
1488+
if (error_status & qm->error_mask) {
14981489
if (error_status & QM_ECC_MBIT)
14991490
qm->err_status.is_qm_ecc_mbit = true;
15001491

15011492
qm_log_hw_error(qm, error_status);
1502-
if (error_status & qm->err_info.qm_reset_mask)
1493+
if (error_status & qm->err_info.qm_reset_mask) {
1494+
/* Disable the same error reporting until device is recovered. */
1495+
writel(qm->err_info.nfe & (~error_status),
1496+
qm->io_base + QM_RAS_NFE_ENABLE);
15031497
return ACC_ERR_NEED_RESET;
1498+
}
15041499

1500+
/* Clear error source if not need reset. */
15051501
writel(error_status, qm->io_base + QM_ABNORMAL_INT_SOURCE);
15061502
writel(qm->err_info.nfe, qm->io_base + QM_RAS_NFE_ENABLE);
1503+
writel(qm->err_info.ce, qm->io_base + QM_RAS_CE_ENABLE);
15071504
}
15081505

15091506
return ACC_ERR_RECOVERED;
@@ -3924,30 +3921,12 @@ EXPORT_SYMBOL_GPL(hisi_qm_sriov_configure);
39243921

39253922
static enum acc_err_result qm_dev_err_handle(struct hisi_qm *qm)
39263923
{
3927-
u32 err_sts;
3928-
3929-
if (!qm->err_ini->get_dev_hw_err_status) {
3930-
dev_err(&qm->pdev->dev, "Device doesn't support get hw error status!\n");
3924+
if (!qm->err_ini->get_err_result) {
3925+
dev_err(&qm->pdev->dev, "Device doesn't support reset!\n");
39313926
return ACC_ERR_NONE;
39323927
}
39333928

3934-
/* get device hardware error status */
3935-
err_sts = qm->err_ini->get_dev_hw_err_status(qm);
3936-
if (err_sts) {
3937-
if (err_sts & qm->err_info.ecc_2bits_mask)
3938-
qm->err_status.is_dev_ecc_mbit = true;
3939-
3940-
if (qm->err_ini->log_dev_hw_err)
3941-
qm->err_ini->log_dev_hw_err(qm, err_sts);
3942-
3943-
if (err_sts & qm->err_info.dev_reset_mask)
3944-
return ACC_ERR_NEED_RESET;
3945-
3946-
if (qm->err_ini->clear_dev_hw_err_status)
3947-
qm->err_ini->clear_dev_hw_err_status(qm, err_sts);
3948-
}
3949-
3950-
return ACC_ERR_RECOVERED;
3929+
return qm->err_ini->get_err_result(qm);
39513930
}
39523931

39533932
static enum acc_err_result qm_process_dev_error(struct hisi_qm *qm)

drivers/crypto/hisilicon/sec2/sec_main.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,11 +1056,15 @@ static u32 sec_get_hw_err_status(struct hisi_qm *qm)
10561056

10571057
static void sec_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
10581058
{
1059-
u32 nfe;
1060-
10611059
writel(err_sts, qm->io_base + SEC_CORE_INT_SOURCE);
1062-
nfe = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_NFE_MASK_CAP, qm->cap_ver);
1063-
writel(nfe, qm->io_base + SEC_RAS_NFE_REG);
1060+
}
1061+
1062+
static void sec_disable_error_report(struct hisi_qm *qm, u32 err_type)
1063+
{
1064+
u32 nfe_mask;
1065+
1066+
nfe_mask = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_NFE_MASK_CAP, qm->cap_ver);
1067+
writel(nfe_mask & (~err_type), qm->io_base + SEC_RAS_NFE_REG);
10641068
}
10651069

10661070
static void sec_open_axi_master_ooo(struct hisi_qm *qm)
@@ -1072,6 +1076,27 @@ static void sec_open_axi_master_ooo(struct hisi_qm *qm)
10721076
writel(val | SEC_AXI_SHUTDOWN_ENABLE, qm->io_base + SEC_CONTROL_REG);
10731077
}
10741078

1079+
static enum acc_err_result sec_get_err_result(struct hisi_qm *qm)
1080+
{
1081+
u32 err_status;
1082+
1083+
err_status = sec_get_hw_err_status(qm);
1084+
if (err_status) {
1085+
if (err_status & qm->err_info.ecc_2bits_mask)
1086+
qm->err_status.is_dev_ecc_mbit = true;
1087+
sec_log_hw_error(qm, err_status);
1088+
1089+
if (err_status & qm->err_info.dev_reset_mask) {
1090+
/* Disable the same error reporting until device is recovered. */
1091+
sec_disable_error_report(qm, err_status);
1092+
return ACC_ERR_NEED_RESET;
1093+
}
1094+
sec_clear_hw_err_status(qm, err_status);
1095+
}
1096+
1097+
return ACC_ERR_RECOVERED;
1098+
}
1099+
10751100
static void sec_err_info_init(struct hisi_qm *qm)
10761101
{
10771102
struct hisi_qm_err_info *err_info = &qm->err_info;
@@ -1098,12 +1123,12 @@ static const struct hisi_qm_err_ini sec_err_ini = {
10981123
.hw_err_disable = sec_hw_error_disable,
10991124
.get_dev_hw_err_status = sec_get_hw_err_status,
11001125
.clear_dev_hw_err_status = sec_clear_hw_err_status,
1101-
.log_dev_hw_err = sec_log_hw_error,
11021126
.open_axi_master_ooo = sec_open_axi_master_ooo,
11031127
.open_sva_prefetch = sec_open_sva_prefetch,
11041128
.close_sva_prefetch = sec_close_sva_prefetch,
11051129
.show_last_dfx_regs = sec_show_last_dfx_regs,
11061130
.err_info_init = sec_err_info_init,
1131+
.get_err_result = sec_get_err_result,
11071132
};
11081133

11091134
static int sec_pf_probe_init(struct sec_dev *sec)

drivers/crypto/hisilicon/zip/zip_main.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,11 +1107,15 @@ static u32 hisi_zip_get_hw_err_status(struct hisi_qm *qm)
11071107

11081108
static void hisi_zip_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
11091109
{
1110-
u32 nfe;
1111-
11121110
writel(err_sts, qm->io_base + HZIP_CORE_INT_SOURCE);
1113-
nfe = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);
1114-
writel(nfe, qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
1111+
}
1112+
1113+
static void hisi_zip_disable_error_report(struct hisi_qm *qm, u32 err_type)
1114+
{
1115+
u32 nfe_mask;
1116+
1117+
nfe_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);
1118+
writel(nfe_mask & (~err_type), qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
11151119
}
11161120

11171121
static void hisi_zip_open_axi_master_ooo(struct hisi_qm *qm)
@@ -1141,6 +1145,27 @@ static void hisi_zip_close_axi_master_ooo(struct hisi_qm *qm)
11411145
qm->io_base + HZIP_CORE_INT_SET);
11421146
}
11431147

1148+
static enum acc_err_result hisi_zip_get_err_result(struct hisi_qm *qm)
1149+
{
1150+
u32 err_status;
1151+
1152+
err_status = hisi_zip_get_hw_err_status(qm);
1153+
if (err_status) {
1154+
if (err_status & qm->err_info.ecc_2bits_mask)
1155+
qm->err_status.is_dev_ecc_mbit = true;
1156+
hisi_zip_log_hw_error(qm, err_status);
1157+
1158+
if (err_status & qm->err_info.dev_reset_mask) {
1159+
/* Disable the same error reporting until device is recovered. */
1160+
hisi_zip_disable_error_report(qm, err_status);
1161+
return ACC_ERR_NEED_RESET;
1162+
}
1163+
hisi_zip_clear_hw_err_status(qm, err_status);
1164+
}
1165+
1166+
return ACC_ERR_RECOVERED;
1167+
}
1168+
11441169
static void hisi_zip_err_info_init(struct hisi_qm *qm)
11451170
{
11461171
struct hisi_qm_err_info *err_info = &qm->err_info;
@@ -1168,13 +1193,13 @@ static const struct hisi_qm_err_ini hisi_zip_err_ini = {
11681193
.hw_err_disable = hisi_zip_hw_error_disable,
11691194
.get_dev_hw_err_status = hisi_zip_get_hw_err_status,
11701195
.clear_dev_hw_err_status = hisi_zip_clear_hw_err_status,
1171-
.log_dev_hw_err = hisi_zip_log_hw_error,
11721196
.open_axi_master_ooo = hisi_zip_open_axi_master_ooo,
11731197
.close_axi_master_ooo = hisi_zip_close_axi_master_ooo,
11741198
.open_sva_prefetch = hisi_zip_open_sva_prefetch,
11751199
.close_sva_prefetch = hisi_zip_close_sva_prefetch,
11761200
.show_last_dfx_regs = hisi_zip_show_last_dfx_regs,
11771201
.err_info_init = hisi_zip_err_info_init,
1202+
.get_err_result = hisi_zip_get_err_result,
11781203
};
11791204

11801205
static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)

include/linux/hisi_acc_qm.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ struct hisi_qm_status {
229229

230230
struct hisi_qm;
231231

232+
enum acc_err_result {
233+
ACC_ERR_NONE,
234+
ACC_ERR_NEED_RESET,
235+
ACC_ERR_RECOVERED,
236+
};
237+
232238
struct hisi_qm_err_info {
233239
char *acpi_rst;
234240
u32 msi_wr_port;
@@ -257,9 +263,9 @@ struct hisi_qm_err_ini {
257263
void (*close_axi_master_ooo)(struct hisi_qm *qm);
258264
void (*open_sva_prefetch)(struct hisi_qm *qm);
259265
void (*close_sva_prefetch)(struct hisi_qm *qm);
260-
void (*log_dev_hw_err)(struct hisi_qm *qm, u32 err_sts);
261266
void (*show_last_dfx_regs)(struct hisi_qm *qm);
262267
void (*err_info_init)(struct hisi_qm *qm);
268+
enum acc_err_result (*get_err_result)(struct hisi_qm *qm);
263269
};
264270

265271
struct hisi_qm_cap_info {

0 commit comments

Comments
 (0)