diff options
Diffstat (limited to 'drivers/crypto')
| -rw-r--r-- | drivers/crypto/hisilicon/hpre/hpre_main.c | 10 | ||||
| -rw-r--r-- | drivers/crypto/hisilicon/qm.c | 128 | ||||
| -rw-r--r-- | drivers/crypto/hisilicon/sec2/sec_main.c | 10 | ||||
| -rw-r--r-- | drivers/crypto/hisilicon/zip/zip_main.c | 10 |
4 files changed, 128 insertions, 30 deletions
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c index 357ab5e5887e..a484381f522a 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_main.c +++ b/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -1631,12 +1631,10 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_qm_del_list; } - if (qm->uacce) { - ret = uacce_register(qm->uacce); - if (ret) { - pci_err(pdev, "failed to register uacce (%d)!\n", ret); - goto err_with_alg_register; - } + ret = hisi_qm_register_uacce(qm); + if (ret) { + pci_err(pdev, "failed to register uacce (%d)!\n", ret); + goto err_with_alg_register; } if (qm->fun_type == QM_HW_PF && vfs_num) { diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 3ca47e2a9719..9cf52873a891 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -246,6 +246,10 @@ #define QM_QOS_MAX_CIR_U 6 #define QM_AUTOSUSPEND_DELAY 3000 +/* qm isolation state mask */ +#define QM_ISOLATED_STATE BIT(31) +#define QM_ISOLATED_THRESHOLD_MASK GENMASK(15, 0) + /* abnormal status value for stopping queue */ #define QM_STOP_QUEUE_FAIL 1 #define QM_DUMP_SQC_FAIL 3 @@ -286,6 +290,20 @@ enum qm_alg_type { ALG_TYPE_1, }; +/* + * Message format for QM_VF_GET_ISOLATE and QM_PF_SET_ISOLATE commands + * + * These commands use a 32-bit command field (cmd) and 32-bit data field (data) + * + * Command behavior: + * - QM_VF_GET_ISOLATE: VF requests isolation status and threshold + * - QM_PF_SET_ISOLATE: PF sets isolation status and threshold + * + * Data field bit layout: + * - bit31 (MSB): Isolation status flag (1 = isolated, 0 = non-isolated) + * - bit15-0 (16 LSB): Isolation threshold value + * - bit30-16 (15 bits): Reserved + */ enum qm_ifc_cmd { QM_PF_FLR_PREPARE = 0x01, QM_PF_SRST_PREPARE, @@ -296,6 +314,8 @@ enum qm_ifc_cmd { QM_VF_START_FAIL, QM_PF_SET_QOS, QM_VF_GET_QOS, + QM_VF_GET_ISOLATE, + QM_PF_SET_ISOLATE, }; enum qm_basic_type { @@ -1734,7 +1754,7 @@ err_unlock: return ret; } -static int qm_ping_all_vfs(struct hisi_qm *qm, enum qm_ifc_cmd cmd) +static int qm_ping_all_vfs(struct hisi_qm *qm, enum qm_ifc_cmd cmd, u32 data) { struct device *dev = &qm->pdev->dev; u32 vfs_num = qm->vfs_num; @@ -1743,7 +1763,7 @@ static int qm_ping_all_vfs(struct hisi_qm *qm, enum qm_ifc_cmd cmd) int ret; u32 i; - ret = qm->ops->set_ifc_begin(qm, cmd, 0, QM_MB_PING_ALL_VFS); + ret = qm->ops->set_ifc_begin(qm, cmd, data, QM_MB_PING_ALL_VFS); if (ret) { dev_err(dev, "failed to send command(0x%x) to all vfs!\n", cmd); qm->ops->set_ifc_end(qm); @@ -2779,6 +2799,7 @@ static enum uacce_dev_state hisi_qm_get_isolate_state(struct uacce_device *uacce static int hisi_qm_isolate_threshold_write(struct uacce_device *uacce, u32 num) { struct hisi_qm *qm = uacce->priv; + int ret; /* Must be set by PF */ if (uacce->is_vf) @@ -2792,6 +2813,18 @@ static int hisi_qm_isolate_threshold_write(struct uacce_device *uacce, u32 num) /* After the policy is updated, need to reset the hardware err list */ qm_hw_err_destroy(qm); + + if (!qm->vfs_num) { + mutex_unlock(&qm->isolate_data.isolate_lock); + return 0; + } + + /* Notify all VFs to update the isolation threshold. */ + if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) { + ret = qm_ping_all_vfs(qm, QM_PF_SET_ISOLATE, qm->isolate_data.err_threshold); + if (ret) + dev_err(&qm->pdev->dev, "failed to send command to all VFs set isolate!\n"); + } mutex_unlock(&qm->isolate_data.isolate_lock); return 0; @@ -2802,7 +2835,7 @@ static u32 hisi_qm_isolate_threshold_read(struct uacce_device *uacce) struct hisi_qm *qm = uacce->priv; struct hisi_qm *pf_qm; - if (uacce->is_vf) { + if (uacce->is_vf && !test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) { pf_qm = pci_get_drvdata(pci_physfn(qm->pdev)); return pf_qm->isolate_data.err_threshold; } @@ -2889,7 +2922,10 @@ static int qm_alloc_uacce(struct hisi_qm *qm) return -EINVAL; } - uacce->is_vf = pdev->is_virtfn; + if (qm->fun_type == QM_HW_PF) + uacce->is_vf = false; + else + uacce->is_vf = true; uacce->priv = qm; if (qm->ver == QM_HW_V1) @@ -2918,6 +2954,25 @@ static int qm_alloc_uacce(struct hisi_qm *qm) return 0; } +int hisi_qm_register_uacce(struct hisi_qm *qm) +{ + int ret; + + if (!qm->uacce) + return 0; + + dev_info(&qm->pdev->dev, "qm register to uacce\n"); + + if (qm->fun_type == QM_HW_VF && test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) { + ret = qm_ping_pf(qm, QM_VF_GET_ISOLATE); + if (ret) + dev_err(&qm->pdev->dev, "failed to send cmd to PF to get isolate!\n"); + } + + return uacce_register(qm->uacce); +} +EXPORT_SYMBOL_GPL(hisi_qm_register_uacce); + /** * qm_frozen() - Try to froze QM to cut continuous queue request. If * there is user on the QM, return failure without doing anything. @@ -4484,7 +4539,7 @@ static int qm_try_stop_vfs(struct hisi_qm *qm, enum qm_ifc_cmd cmd, /* Kunpeng930 supports to notify VFs to stop before PF reset */ if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) { - ret = qm_ping_all_vfs(qm, cmd); + ret = qm_ping_all_vfs(qm, cmd, 0); if (ret) pci_err(pdev, "failed to send command to all VFs before PF reset!\n"); } else { @@ -4671,6 +4726,7 @@ restart_fail: static int qm_try_start_vfs(struct hisi_qm *qm, enum qm_ifc_cmd cmd) { struct pci_dev *pdev = qm->pdev; + u32 data; int ret; if (!qm->vfs_num) @@ -4684,7 +4740,11 @@ static int qm_try_start_vfs(struct hisi_qm *qm, enum qm_ifc_cmd cmd) /* Kunpeng930 supports to notify VFs to start after PF reset. */ if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) { - ret = qm_ping_all_vfs(qm, cmd); + data = qm->isolate_data.err_threshold; + if (qm->isolate_data.is_isolate) + data |= QM_ISOLATED_STATE; + /* Broadcasting isolate info via RAS to all VFs. */ + ret = qm_ping_all_vfs(qm, cmd, data); if (ret) pci_warn(pdev, "failed to send cmd to all VFs after PF reset!\n"); } else { @@ -5131,10 +5191,22 @@ static void qm_pf_reset_vf_done(struct hisi_qm *qm) qm_reset_bit_clear(qm); } -static int qm_wait_pf_reset_finish(struct hisi_qm *qm) +static void qm_vf_update_isolate_info(struct hisi_qm *qm, u32 data) +{ + /* Updating the local isolation status. */ + mutex_lock(&qm->isolate_data.isolate_lock); + if (data & QM_ISOLATED_STATE) + qm->isolate_data.is_isolate = true; + else + qm->isolate_data.is_isolate = false; + qm->isolate_data.err_threshold = data & QM_ISOLATED_THRESHOLD_MASK; + mutex_unlock(&qm->isolate_data.isolate_lock); +} + +static int qm_wait_pf_reset_finish(struct hisi_qm *qm, enum qm_stop_reason stop_reason) { struct device *dev = &qm->pdev->dev; - u32 val, cmd; + u32 val, cmd, data; int ret; /* Wait for reset to finish */ @@ -5151,7 +5223,7 @@ static int qm_wait_pf_reset_finish(struct hisi_qm *qm) * Whether message is got successfully, * VF needs to ack PF by clearing the interrupt. */ - ret = qm->ops->get_ifc(qm, &cmd, NULL, 0); + ret = qm->ops->get_ifc(qm, &cmd, &data, 0); qm_clear_cmd_interrupt(qm, 0); if (ret) { dev_err(dev, "failed to get command from PF in reset done!\n"); @@ -5160,10 +5232,14 @@ static int qm_wait_pf_reset_finish(struct hisi_qm *qm) if (cmd != QM_PF_RESET_DONE) { dev_err(dev, "the command(0x%x) is not reset done!\n", cmd); - ret = -EINVAL; + return -EINVAL; } - return ret; + /* The VF processes the device isolation information received from the RAS reset. */ + if (stop_reason == QM_SOFT_RESET) + qm_vf_update_isolate_info(qm, data); + + return 0; } static void qm_pf_reset_vf_process(struct hisi_qm *qm, @@ -5178,7 +5254,7 @@ static void qm_pf_reset_vf_process(struct hisi_qm *qm, qm_cmd_uninit(qm); qm_pf_reset_vf_prepare(qm, stop_reason); - ret = qm_wait_pf_reset_finish(qm); + ret = qm_wait_pf_reset_finish(qm, stop_reason); if (ret) goto err_get_status; @@ -5189,10 +5265,31 @@ static void qm_pf_reset_vf_process(struct hisi_qm *qm, return; err_get_status: + if (stop_reason == QM_SOFT_RESET) { + /* Update local isolation status on PF-VF reset failure. */ + mutex_lock(&qm->isolate_data.isolate_lock); + qm->isolate_data.is_isolate = true; + mutex_unlock(&qm->isolate_data.isolate_lock); + } qm_cmd_init(qm); qm_reset_bit_clear(qm); } +static void qm_vf_get_isolate_data(struct hisi_qm *qm, u32 fun_num) +{ + u32 data = qm->isolate_data.err_threshold; + struct device *dev = &qm->pdev->dev; + int ret; + + if (qm->isolate_data.is_isolate) + data |= QM_ISOLATED_STATE; + + ret = qm_ping_single_vf(qm, QM_PF_SET_ISOLATE, data, fun_num); + if (ret) + dev_err(dev, "failed to send command(0x%x) to VF(%u)!\n", + (unsigned int)QM_PF_SET_ISOLATE, fun_num); +} + static void qm_handle_cmd_msg(struct hisi_qm *qm, u32 fun_num) { struct device *dev = &qm->pdev->dev; @@ -5224,6 +5321,13 @@ static void qm_handle_cmd_msg(struct hisi_qm *qm, u32 fun_num) case QM_PF_SET_QOS: qm->mb_qos = data; break; + case QM_VF_GET_ISOLATE: + /* Read the isolation policy of the PF during VF initialization. */ + qm_vf_get_isolate_data(qm, fun_num); + break; + case QM_PF_SET_ISOLATE: + qm_vf_update_isolate_info(qm, data); + break; default: dev_err(dev, "unsupported command(0x%x) sent by function(%u)!\n", cmd, fun_num); break; diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index 056bd8f4da5a..e8bea1e496f7 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -1449,12 +1449,10 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_qm_del_list; } - if (qm->uacce) { - ret = uacce_register(qm->uacce); - if (ret) { - pci_err(pdev, "failed to register uacce (%d)!\n", ret); - goto err_alg_unregister; - } + ret = hisi_qm_register_uacce(qm); + if (ret) { + pci_err(pdev, "failed to register uacce (%d)!\n", ret); + goto err_alg_unregister; } if (qm->fun_type == QM_HW_PF && vfs_num) { diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c index 44df9c859bd8..5135b3028cb2 100644 --- a/drivers/crypto/hisilicon/zip/zip_main.c +++ b/drivers/crypto/hisilicon/zip/zip_main.c @@ -1559,12 +1559,10 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_qm_del_list; } - if (qm->uacce) { - ret = uacce_register(qm->uacce); - if (ret) { - pci_err(pdev, "failed to register uacce (%d)!\n", ret); - goto err_qm_alg_unregister; - } + ret = hisi_qm_register_uacce(qm); + if (ret) { + pci_err(pdev, "failed to register uacce (%d)!\n", ret); + goto err_qm_alg_unregister; } if (qm->fun_type == QM_HW_PF && vfs_num > 0) { |
