crypto: hisilicon/qm - disable queue when 'CQ' error
If the hardware reports the 'CQ' overflow or 'CQE' error by the abnormal interrupt, disable the queue and stop tasks send to hardware. Signed-off-by: Weili Qian <qianweili@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
95f0b6d536
commit
696645d25b
@ -89,7 +89,10 @@
|
|||||||
|
|
||||||
#define QM_AEQE_PHASE(aeqe) ((le32_to_cpu((aeqe)->dw0) >> 16) & 0x1)
|
#define QM_AEQE_PHASE(aeqe) ((le32_to_cpu((aeqe)->dw0) >> 16) & 0x1)
|
||||||
#define QM_AEQE_TYPE_SHIFT 17
|
#define QM_AEQE_TYPE_SHIFT 17
|
||||||
|
#define QM_AEQE_CQN_MASK GENMASK(15, 0)
|
||||||
|
#define QM_CQ_OVERFLOW 0
|
||||||
#define QM_EQ_OVERFLOW 1
|
#define QM_EQ_OVERFLOW 1
|
||||||
|
#define QM_CQE_ERROR 2
|
||||||
|
|
||||||
#define QM_DOORBELL_CMD_SQ 0
|
#define QM_DOORBELL_CMD_SQ 0
|
||||||
#define QM_DOORBELL_CMD_CQ 1
|
#define QM_DOORBELL_CMD_CQ 1
|
||||||
@ -989,6 +992,15 @@ static void qm_set_qp_disable(struct hisi_qp *qp, int offset)
|
|||||||
mb();
|
mb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qm_disable_qp(struct hisi_qm *qm, u32 qp_id)
|
||||||
|
{
|
||||||
|
struct hisi_qp *qp = &qm->qp_array[qp_id];
|
||||||
|
|
||||||
|
qm_set_qp_disable(qp, QM_RESET_STOP_TX_OFFSET);
|
||||||
|
hisi_qm_stop_qp(qp);
|
||||||
|
qm_set_qp_disable(qp, QM_RESET_STOP_RX_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
static void qm_reset_function(struct hisi_qm *qm)
|
static void qm_reset_function(struct hisi_qm *qm)
|
||||||
{
|
{
|
||||||
struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(qm->pdev));
|
struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(qm->pdev));
|
||||||
@ -1022,16 +1034,24 @@ static irqreturn_t qm_aeq_thread(int irq, void *data)
|
|||||||
{
|
{
|
||||||
struct hisi_qm *qm = data;
|
struct hisi_qm *qm = data;
|
||||||
struct qm_aeqe *aeqe = qm->aeqe + qm->status.aeq_head;
|
struct qm_aeqe *aeqe = qm->aeqe + qm->status.aeq_head;
|
||||||
u32 type;
|
u32 type, qp_id;
|
||||||
|
|
||||||
while (QM_AEQE_PHASE(aeqe) == qm->status.aeqc_phase) {
|
while (QM_AEQE_PHASE(aeqe) == qm->status.aeqc_phase) {
|
||||||
type = le32_to_cpu(aeqe->dw0) >> QM_AEQE_TYPE_SHIFT;
|
type = le32_to_cpu(aeqe->dw0) >> QM_AEQE_TYPE_SHIFT;
|
||||||
|
qp_id = le32_to_cpu(aeqe->dw0) & QM_AEQE_CQN_MASK;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QM_EQ_OVERFLOW:
|
case QM_EQ_OVERFLOW:
|
||||||
dev_err(&qm->pdev->dev, "eq overflow, reset function\n");
|
dev_err(&qm->pdev->dev, "eq overflow, reset function\n");
|
||||||
qm_reset_function(qm);
|
qm_reset_function(qm);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
case QM_CQ_OVERFLOW:
|
||||||
|
dev_err(&qm->pdev->dev, "cq overflow, stop qp(%u)\n",
|
||||||
|
qp_id);
|
||||||
|
fallthrough;
|
||||||
|
case QM_CQE_ERROR:
|
||||||
|
qm_disable_qp(qm, qp_id);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(&qm->pdev->dev, "unknown error type %u\n",
|
dev_err(&qm->pdev->dev, "unknown error type %u\n",
|
||||||
type);
|
type);
|
||||||
|
Loading…
Reference in New Issue
Block a user