net: hns3: Fix for hclge_reset running repeatly problem
When hardware sends the HCLGE_VECTOR0_EVENT_RST event through
hclge_misc_irq_handle, currently driver enables misc_vector in
the interrupt handle, and hardware generates the same interrupt
for the same reset event again and again until the reset is
complete, which causes hclge_reset running repeatly problem.
This patch fixes by enabling the misc_vector after reset is
complete.
Fixes: 4ed340ab8f
("net: hns3: Add reset process in hclge_main")
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f5be79673f
commit
cd8c5c269b
|
@ -2587,9 +2587,11 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we should clear the source of interrupt */
|
/* clear the source of interrupt if it is not cause by reset */
|
||||||
hclge_clear_event_cause(hdev, event_cause, clearval);
|
if (event_cause != HCLGE_VECTOR0_EVENT_RST) {
|
||||||
hclge_enable_vector(&hdev->misc_vector, true);
|
hclge_clear_event_cause(hdev, event_cause, clearval);
|
||||||
|
hclge_enable_vector(&hdev->misc_vector, true);
|
||||||
|
}
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
@ -2777,6 +2779,33 @@ static enum hnae3_reset_type hclge_get_reset_level(struct hclge_dev *hdev,
|
||||||
return rst_level;
|
return rst_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hclge_clear_reset_cause(struct hclge_dev *hdev)
|
||||||
|
{
|
||||||
|
u32 clearval = 0;
|
||||||
|
|
||||||
|
switch (hdev->reset_type) {
|
||||||
|
case HNAE3_IMP_RESET:
|
||||||
|
clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B);
|
||||||
|
break;
|
||||||
|
case HNAE3_GLOBAL_RESET:
|
||||||
|
clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B);
|
||||||
|
break;
|
||||||
|
case HNAE3_CORE_RESET:
|
||||||
|
clearval = BIT(HCLGE_VECTOR0_CORERESET_INT_B);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_warn(&hdev->pdev->dev, "Unsupported reset event to clear:%d",
|
||||||
|
hdev->reset_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clearval)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, clearval);
|
||||||
|
hclge_enable_vector(&hdev->misc_vector, true);
|
||||||
|
}
|
||||||
|
|
||||||
static void hclge_reset(struct hclge_dev *hdev)
|
static void hclge_reset(struct hclge_dev *hdev)
|
||||||
{
|
{
|
||||||
/* perform reset of the stack & ae device for a client */
|
/* perform reset of the stack & ae device for a client */
|
||||||
|
@ -2789,6 +2818,8 @@ static void hclge_reset(struct hclge_dev *hdev)
|
||||||
hclge_reset_ae_dev(hdev->ae_dev);
|
hclge_reset_ae_dev(hdev->ae_dev);
|
||||||
hclge_notify_client(hdev, HNAE3_INIT_CLIENT);
|
hclge_notify_client(hdev, HNAE3_INIT_CLIENT);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
|
hclge_clear_reset_cause(hdev);
|
||||||
} else {
|
} else {
|
||||||
/* schedule again to check pending resets later */
|
/* schedule again to check pending resets later */
|
||||||
set_bit(hdev->reset_type, &hdev->reset_pending);
|
set_bit(hdev->reset_type, &hdev->reset_pending);
|
||||||
|
@ -5661,9 +5692,6 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable MISC vector(vector0) */
|
|
||||||
hclge_enable_vector(&hdev->misc_vector, true);
|
|
||||||
|
|
||||||
dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n",
|
dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n",
|
||||||
HCLGE_DRIVER_NAME);
|
HCLGE_DRIVER_NAME);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue