Skip to content

Commit 5d2d1ee

Browse files
Weili Qianherbertx
authored andcommitted
crypto: hisilicon/qm - reset device before enabling it
Before the device is enabled again, the device may still store the previously processed data. If an error occurs in the previous task, the device may fail to be enabled again. Therefore, before enabling device, reset the device to restore the initial state. Signed-off-by: Weili Qian <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent f5dd7c4 commit 5d2d1ee

File tree

4 files changed

+121
-64
lines changed

4 files changed

+121
-64
lines changed

drivers/crypto/hisilicon/hpre/hpre_main.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ static struct dfx_diff_registers hpre_diff_regs[] = {
358358
},
359359
};
360360

361+
static const struct hisi_qm_err_ini hpre_err_ini;
362+
361363
bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg)
362364
{
363365
u32 cap_val;
@@ -1161,6 +1163,7 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
11611163
qm->qp_num = pf_q_num;
11621164
qm->debug.curr_qm_qp_num = pf_q_num;
11631165
qm->qm_list = &hpre_devices;
1166+
qm->err_ini = &hpre_err_ini;
11641167
if (pf_q_num_flag)
11651168
set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
11661169
}
@@ -1350,8 +1353,6 @@ static int hpre_pf_probe_init(struct hpre *hpre)
13501353

13511354
hpre_open_sva_prefetch(qm);
13521355

1353-
qm->err_ini = &hpre_err_ini;
1354-
qm->err_ini->err_info_init(qm);
13551356
hisi_qm_dev_err_init(qm);
13561357
ret = hpre_show_last_regs_init(qm);
13571358
if (ret)
@@ -1380,6 +1381,18 @@ static int hpre_probe_init(struct hpre *hpre)
13801381
return 0;
13811382
}
13821383

1384+
static void hpre_probe_uninit(struct hisi_qm *qm)
1385+
{
1386+
if (qm->fun_type == QM_HW_VF)
1387+
return;
1388+
1389+
hpre_cnt_regs_clear(qm);
1390+
qm->debug.curr_qm_qp_num = 0;
1391+
hpre_show_last_regs_uninit(qm);
1392+
hpre_close_sva_prefetch(qm);
1393+
hisi_qm_dev_err_uninit(qm);
1394+
}
1395+
13831396
static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
13841397
{
13851398
struct hisi_qm *qm;
@@ -1405,7 +1418,7 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
14051418

14061419
ret = hisi_qm_start(qm);
14071420
if (ret)
1408-
goto err_with_err_init;
1421+
goto err_with_probe_init;
14091422

14101423
ret = hpre_debugfs_init(qm);
14111424
if (ret)
@@ -1444,9 +1457,8 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
14441457
hpre_debugfs_exit(qm);
14451458
hisi_qm_stop(qm, QM_NORMAL);
14461459

1447-
err_with_err_init:
1448-
hpre_show_last_regs_uninit(qm);
1449-
hisi_qm_dev_err_uninit(qm);
1460+
err_with_probe_init:
1461+
hpre_probe_uninit(qm);
14501462

14511463
err_with_qm_init:
14521464
hisi_qm_uninit(qm);
@@ -1468,13 +1480,7 @@ static void hpre_remove(struct pci_dev *pdev)
14681480
hpre_debugfs_exit(qm);
14691481
hisi_qm_stop(qm, QM_NORMAL);
14701482

1471-
if (qm->fun_type == QM_HW_PF) {
1472-
hpre_cnt_regs_clear(qm);
1473-
qm->debug.curr_qm_qp_num = 0;
1474-
hpre_show_last_regs_uninit(qm);
1475-
hisi_qm_dev_err_uninit(qm);
1476-
}
1477-
1483+
hpre_probe_uninit(qm);
14781484
hisi_qm_uninit(qm);
14791485
}
14801486

drivers/crypto/hisilicon/qm.c

Lines changed: 80 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ static struct qm_typical_qos_table shaper_cbs_s[] = {
450450
};
451451

452452
static void qm_irqs_unregister(struct hisi_qm *qm);
453+
static int qm_reset_device(struct hisi_qm *qm);
453454

454455
static u32 qm_get_hw_error_status(struct hisi_qm *qm)
455456
{
@@ -4108,6 +4109,22 @@ static int qm_controller_reset_prepare(struct hisi_qm *qm)
41084109
return 0;
41094110
}
41104111

4112+
static int qm_master_ooo_check(struct hisi_qm *qm)
4113+
{
4114+
u32 val;
4115+
int ret;
4116+
4117+
/* Check the ooo register of the device before resetting the device. */
4118+
writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN, qm->io_base + ACC_MASTER_GLOBAL_CTRL);
4119+
ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
4120+
val, (val == ACC_MASTER_TRANS_RETURN_RW),
4121+
POLL_PERIOD, POLL_TIMEOUT);
4122+
if (ret)
4123+
pci_warn(qm->pdev, "Bus lock! Please reset system.\n");
4124+
4125+
return ret;
4126+
}
4127+
41114128
static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
41124129
{
41134130
u32 nfe_enb = 0;
@@ -4130,11 +4147,10 @@ static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
41304147
}
41314148
}
41324149

4133-
static int qm_soft_reset(struct hisi_qm *qm)
4150+
static int qm_soft_reset_prepare(struct hisi_qm *qm)
41344151
{
41354152
struct pci_dev *pdev = qm->pdev;
41364153
int ret;
4137-
u32 val;
41384154

41394155
/* Ensure all doorbells and mailboxes received by QM */
41404156
ret = qm_check_req_recv(qm);
@@ -4156,29 +4172,23 @@ static int qm_soft_reset(struct hisi_qm *qm)
41564172
}
41574173

41584174
qm_dev_ecc_mbit_handle(qm);
4159-
4160-
/* OOO register set and check */
4161-
writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN,
4162-
qm->io_base + ACC_MASTER_GLOBAL_CTRL);
4163-
4164-
/* If bus lock, reset chip */
4165-
ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
4166-
val,
4167-
(val == ACC_MASTER_TRANS_RETURN_RW),
4168-
POLL_PERIOD, POLL_TIMEOUT);
4169-
if (ret) {
4170-
pci_emerg(pdev, "Bus lock! Please reset system.\n");
4175+
ret = qm_master_ooo_check(qm);
4176+
if (ret)
41714177
return ret;
4172-
}
41734178

41744179
if (qm->err_ini->close_sva_prefetch)
41754180
qm->err_ini->close_sva_prefetch(qm);
41764181

41774182
ret = qm_set_pf_mse(qm, false);
4178-
if (ret) {
4183+
if (ret)
41794184
pci_err(pdev, "Fails to disable pf MSE bit.\n");
4180-
return ret;
4181-
}
4185+
4186+
return ret;
4187+
}
4188+
4189+
static int qm_reset_device(struct hisi_qm *qm)
4190+
{
4191+
struct pci_dev *pdev = qm->pdev;
41824192

41834193
/* The reset related sub-control registers are not in PCI BAR */
41844194
if (ACPI_HANDLE(&pdev->dev)) {
@@ -4197,12 +4207,23 @@ static int qm_soft_reset(struct hisi_qm *qm)
41974207
pci_err(pdev, "Reset step %llu failed!\n", value);
41984208
return -EIO;
41994209
}
4200-
} else {
4201-
pci_err(pdev, "No reset method!\n");
4202-
return -EINVAL;
4210+
4211+
return 0;
42034212
}
42044213

4205-
return 0;
4214+
pci_err(pdev, "No reset method!\n");
4215+
return -EINVAL;
4216+
}
4217+
4218+
static int qm_soft_reset(struct hisi_qm *qm)
4219+
{
4220+
int ret;
4221+
4222+
ret = qm_soft_reset_prepare(qm);
4223+
if (ret)
4224+
return ret;
4225+
4226+
return qm_reset_device(qm);
42064227
}
42074228

42084229
static int qm_vf_reset_done(struct hisi_qm *qm)
@@ -5155,6 +5176,35 @@ static int qm_get_pci_res(struct hisi_qm *qm)
51555176
return ret;
51565177
}
51575178

5179+
static int qm_clear_device(struct hisi_qm *qm)
5180+
{
5181+
acpi_handle handle = ACPI_HANDLE(&qm->pdev->dev);
5182+
int ret;
5183+
5184+
if (qm->fun_type == QM_HW_VF)
5185+
return 0;
5186+
5187+
/* Device does not support reset, return */
5188+
if (!qm->err_ini->err_info_init)
5189+
return 0;
5190+
qm->err_ini->err_info_init(qm);
5191+
5192+
if (!handle)
5193+
return 0;
5194+
5195+
/* No reset method, return */
5196+
if (!acpi_has_method(handle, qm->err_info.acpi_rst))
5197+
return 0;
5198+
5199+
ret = qm_master_ooo_check(qm);
5200+
if (ret) {
5201+
writel(0x0, qm->io_base + ACC_MASTER_GLOBAL_CTRL);
5202+
return ret;
5203+
}
5204+
5205+
return qm_reset_device(qm);
5206+
}
5207+
51585208
static int hisi_qm_pci_init(struct hisi_qm *qm)
51595209
{
51605210
struct pci_dev *pdev = qm->pdev;
@@ -5184,8 +5234,14 @@ static int hisi_qm_pci_init(struct hisi_qm *qm)
51845234
goto err_get_pci_res;
51855235
}
51865236

5237+
ret = qm_clear_device(qm);
5238+
if (ret)
5239+
goto err_free_vectors;
5240+
51875241
return 0;
51885242

5243+
err_free_vectors:
5244+
pci_free_irq_vectors(pdev);
51895245
err_get_pci_res:
51905246
qm_put_pci_res(qm);
51915247
err_disable_pcidev:
@@ -5486,26 +5542,16 @@ static int qm_prepare_for_suspend(struct hisi_qm *qm)
54865542
{
54875543
struct pci_dev *pdev = qm->pdev;
54885544
int ret;
5489-
u32 val;
54905545

54915546
ret = qm->ops->set_msi(qm, false);
54925547
if (ret) {
54935548
pci_err(pdev, "failed to disable MSI before suspending!\n");
54945549
return ret;
54955550
}
54965551

5497-
/* shutdown OOO register */
5498-
writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN,
5499-
qm->io_base + ACC_MASTER_GLOBAL_CTRL);
5500-
5501-
ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
5502-
val,
5503-
(val == ACC_MASTER_TRANS_RETURN_RW),
5504-
POLL_PERIOD, POLL_TIMEOUT);
5505-
if (ret) {
5506-
pci_emerg(pdev, "Bus lock! Please reset system.\n");
5552+
ret = qm_master_ooo_check(qm);
5553+
if (ret)
55075554
return ret;
5508-
}
55095555

55105556
ret = qm_set_pf_mse(qm, false);
55115557
if (ret)

drivers/crypto/hisilicon/sec2/sec_main.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,9 +1065,6 @@ static int sec_pf_probe_init(struct sec_dev *sec)
10651065
struct hisi_qm *qm = &sec->qm;
10661066
int ret;
10671067

1068-
qm->err_ini = &sec_err_ini;
1069-
qm->err_ini->err_info_init(qm);
1070-
10711068
ret = sec_set_user_domain_and_cache(qm);
10721069
if (ret)
10731070
return ret;
@@ -1122,6 +1119,7 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
11221119
qm->qp_num = pf_q_num;
11231120
qm->debug.curr_qm_qp_num = pf_q_num;
11241121
qm->qm_list = &sec_devices;
1122+
qm->err_ini = &sec_err_ini;
11251123
if (pf_q_num_flag)
11261124
set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
11271125
} else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {
@@ -1186,6 +1184,12 @@ static int sec_probe_init(struct sec_dev *sec)
11861184

11871185
static void sec_probe_uninit(struct hisi_qm *qm)
11881186
{
1187+
if (qm->fun_type == QM_HW_VF)
1188+
return;
1189+
1190+
sec_debug_regs_clear(qm);
1191+
sec_show_last_regs_uninit(qm);
1192+
sec_close_sva_prefetch(qm);
11891193
hisi_qm_dev_err_uninit(qm);
11901194
}
11911195

@@ -1274,7 +1278,6 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id)
12741278
sec_debugfs_exit(qm);
12751279
hisi_qm_stop(qm, QM_NORMAL);
12761280
err_probe_uninit:
1277-
sec_show_last_regs_uninit(qm);
12781281
sec_probe_uninit(qm);
12791282
err_qm_uninit:
12801283
sec_qm_uninit(qm);
@@ -1296,11 +1299,6 @@ static void sec_remove(struct pci_dev *pdev)
12961299
sec_debugfs_exit(qm);
12971300

12981301
(void)hisi_qm_stop(qm, QM_NORMAL);
1299-
1300-
if (qm->fun_type == QM_HW_PF)
1301-
sec_debug_regs_clear(qm);
1302-
sec_show_last_regs_uninit(qm);
1303-
13041302
sec_probe_uninit(qm);
13051303

13061304
sec_qm_uninit(qm);

drivers/crypto/hisilicon/zip/zip_main.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,8 +1141,6 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
11411141

11421142
hisi_zip->ctrl = ctrl;
11431143
ctrl->hisi_zip = hisi_zip;
1144-
qm->err_ini = &hisi_zip_err_ini;
1145-
qm->err_ini->err_info_init(qm);
11461144

11471145
ret = hisi_zip_set_user_domain_and_cache(qm);
11481146
if (ret)
@@ -1203,6 +1201,7 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
12031201
qm->qp_num = pf_q_num;
12041202
qm->debug.curr_qm_qp_num = pf_q_num;
12051203
qm->qm_list = &zip_devices;
1204+
qm->err_ini = &hisi_zip_err_ini;
12061205
if (pf_q_num_flag)
12071206
set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
12081207
} else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {
@@ -1269,6 +1268,16 @@ static int hisi_zip_probe_init(struct hisi_zip *hisi_zip)
12691268
return 0;
12701269
}
12711270

1271+
static void hisi_zip_probe_uninit(struct hisi_qm *qm)
1272+
{
1273+
if (qm->fun_type == QM_HW_VF)
1274+
return;
1275+
1276+
hisi_zip_show_last_regs_uninit(qm);
1277+
hisi_zip_close_sva_prefetch(qm);
1278+
hisi_qm_dev_err_uninit(qm);
1279+
}
1280+
12721281
static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
12731282
{
12741283
struct hisi_zip *hisi_zip;
@@ -1295,7 +1304,7 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
12951304

12961305
ret = hisi_qm_start(qm);
12971306
if (ret)
1298-
goto err_dev_err_uninit;
1307+
goto err_probe_uninit;
12991308

13001309
ret = hisi_zip_debugfs_init(qm);
13011310
if (ret)
@@ -1334,9 +1343,8 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
13341343
hisi_zip_debugfs_exit(qm);
13351344
hisi_qm_stop(qm, QM_NORMAL);
13361345

1337-
err_dev_err_uninit:
1338-
hisi_zip_show_last_regs_uninit(qm);
1339-
hisi_qm_dev_err_uninit(qm);
1346+
err_probe_uninit:
1347+
hisi_zip_probe_uninit(qm);
13401348

13411349
err_qm_uninit:
13421350
hisi_zip_qm_uninit(qm);
@@ -1358,8 +1366,7 @@ static void hisi_zip_remove(struct pci_dev *pdev)
13581366

13591367
hisi_zip_debugfs_exit(qm);
13601368
hisi_qm_stop(qm, QM_NORMAL);
1361-
hisi_zip_show_last_regs_uninit(qm);
1362-
hisi_qm_dev_err_uninit(qm);
1369+
hisi_zip_probe_uninit(qm);
13631370
hisi_zip_qm_uninit(qm);
13641371
}
13651372

0 commit comments

Comments
 (0)