Sync some bugfix from upstreaming about hns3 reset and modifies are as follow: - net/hns3: fix VF reset handler interruption - net/hns3: fix reset event status - net/hns3: fix ignored reset event Signed-off-by: Dengdui Huang <huangdengdui@huawei.com> (cherry picked from commit 2199d0077da75744fc56a92a534607f5583205ee)
119 lines
3.9 KiB
Diff
119 lines
3.9 KiB
Diff
From 5357c47f664cd3f7b7fd375016afe70884d86677 Mon Sep 17 00:00:00 2001
|
|
From: Dengdui Huang <huangdengdui@huawei.com>
|
|
Date: Mon, 27 Nov 2023 21:39:03 +0800
|
|
Subject: [PATCH 397/397] net/hns3: fix VF reset handler interruption
|
|
|
|
[ upstream commit 94cf4db1603fe9074b5275cc4b63685fc91fdac5 ]
|
|
|
|
Currently, the VF reset interrupt is enabled before the reset
|
|
process is completed. If the VF reset is triggered by an IMP
|
|
reset, the initialization of IMP is may not completed, and the
|
|
VF reset interrupt may continue to be reported. In this scenario,
|
|
the VF reset being performed by the driver does not need to be
|
|
interrupted. Therefore, for VF reset, the driver has to enable
|
|
the interrupt after the end of reset.
|
|
|
|
Fixes: a5475d61fa34 ("net/hns3: support VF")
|
|
Cc: stable@dpdk.org
|
|
|
|
Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
|
|
Acked-by: Jie Hai <haijie1@huawei.com>
|
|
---
|
|
drivers/net/hns3/hns3_ethdev.h | 12 ++++++++++++
|
|
drivers/net/hns3/hns3_ethdev_vf.c | 19 +++++++++++++++++--
|
|
drivers/net/hns3/hns3_intr.c | 6 ++----
|
|
3 files changed, 31 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
|
|
index 668f141e32..12d8299def 100644
|
|
--- a/drivers/net/hns3/hns3_ethdev.h
|
|
+++ b/drivers/net/hns3/hns3_ethdev.h
|
|
@@ -1035,6 +1035,7 @@ void hns3vf_update_link_status(struct hns3_hw *hw, uint8_t link_status,
|
|
uint32_t link_speed, uint8_t link_duplex);
|
|
void hns3vf_update_push_lsc_cap(struct hns3_hw *hw, bool supported);
|
|
void hns3_clear_reset_event(struct hns3_hw *hw);
|
|
+void hns3vf_clear_reset_event(struct hns3_hw *hw);
|
|
|
|
const char *hns3_get_media_type_name(uint8_t media_type);
|
|
|
|
@@ -1049,4 +1050,15 @@ is_reset_pending(struct hns3_adapter *hns)
|
|
return ret;
|
|
}
|
|
|
|
+static inline void
|
|
+hns3_clear_reset_status(struct hns3_hw *hw)
|
|
+{
|
|
+ struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
|
|
+
|
|
+ if (hns->is_vf)
|
|
+ hns3vf_clear_reset_event(hw);
|
|
+ else
|
|
+ hns3_clear_reset_event(hw);
|
|
+}
|
|
+
|
|
#endif /* HNS3_ETHDEV_H */
|
|
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
|
|
index db1a30aff0..a4ac659205 100644
|
|
--- a/drivers/net/hns3/hns3_ethdev_vf.c
|
|
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
|
|
@@ -612,6 +612,19 @@ hns3vf_enable_irq0(struct hns3_hw *hw)
|
|
hns3_write_dev(hw, HNS3_MISC_VECTOR_REG_BASE, 1);
|
|
}
|
|
|
|
+void
|
|
+hns3vf_clear_reset_event(struct hns3_hw *hw)
|
|
+{
|
|
+ uint32_t clearval;
|
|
+ uint32_t cmdq_stat_reg;
|
|
+
|
|
+ cmdq_stat_reg = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_STAT_REG);
|
|
+ clearval = cmdq_stat_reg & ~BIT(HNS3_VECTOR0_RST_INT_B);
|
|
+ hns3_write_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG, clearval);
|
|
+
|
|
+ hns3vf_enable_irq0(hw);
|
|
+}
|
|
+
|
|
static enum hns3vf_evt_cause
|
|
hns3vf_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval)
|
|
{
|
|
@@ -686,8 +699,10 @@ hns3vf_interrupt_handler(void *param)
|
|
break;
|
|
}
|
|
|
|
- /* Enable interrupt */
|
|
- hns3vf_enable_irq0(hw);
|
|
+ /* Enable interrupt if it is not caused by reset */
|
|
+ if (event_cause == HNS3VF_VECTOR0_EVENT_MBX ||
|
|
+ event_cause == HNS3VF_VECTOR0_EVENT_OTHER)
|
|
+ hns3vf_enable_irq0(hw);
|
|
}
|
|
|
|
void
|
|
diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c
|
|
index 9d8dddfcc9..60a0f0d53d 100644
|
|
--- a/drivers/net/hns3/hns3_intr.c
|
|
+++ b/drivers/net/hns3/hns3_intr.c
|
|
@@ -2727,8 +2727,7 @@ hns3_reset_post(struct hns3_adapter *hns)
|
|
/* IMP will wait ready flag before reset */
|
|
hns3_notify_reset_ready(hw, false);
|
|
hns3_clear_reset_level(hw, &hw->reset.pending);
|
|
- if (!hns->is_vf)
|
|
- hns3_clear_reset_event(hw);
|
|
+ hns3_clear_reset_status(hw);
|
|
__atomic_store_n(&hns->hw.reset.resetting, 0, __ATOMIC_RELAXED);
|
|
hw->reset.attempts = 0;
|
|
hw->reset.stats.success_cnt++;
|
|
@@ -2777,8 +2776,7 @@ hns3_reset_fail_handle(struct hns3_adapter *hns)
|
|
struct timeval tv;
|
|
|
|
hns3_clear_reset_level(hw, &hw->reset.pending);
|
|
- if (!hns->is_vf)
|
|
- hns3_clear_reset_event(hw);
|
|
+ hns3_clear_reset_status(hw);
|
|
if (hns3_reset_err_handle(hns)) {
|
|
hw->reset.stage = RESET_STAGE_PREWAIT;
|
|
hns3_schedule_reset(hns);
|
|
--
|
|
2.33.0
|
|
|