diff mbox series

[1/2] igc: Disable PTM sequences when interface goes down

Message ID 20230516195121.10933-2-philip.cox@canonical.com
State New
Headers show
Series Raptor Lake: Enable TSN driver | expand

Commit Message

Philip Cox May 16, 2023, 7:51 p.m. UTC
From: Aravindhan Gunasekaran <aravindhan.gunasekaran@intel.com>

BugLink: https://bugs.launchpad.net/bugs/2019222

Kernel hangs or reboots reported in some boards with a
combination of interface up/down or reset. It turns out
that this occurs due to Foxville bus master disabling
when PTM sequences remain enabled.

We do not need to always enable PTM in the reset
sequence as igc_ptp_reset is also called during
interface down. This caused PTM sequences be enabled
but Foxville tries to disable bus mastering before
going through controller reset.

This patch disables PCIe PTM when interface goes down.

Signed-off-by: Aravindhan Gunasekaran <aravindhan.gunasekaran@intel.com>
(back-ported from https://github.com/intel/linux-intel-quilt/tree/mainline-tracking-v5.19-linux-221019T120731Z/patches/0001-igc-Disable-PTM-sequences-when-interface-goes-down.tsn
[context changes])
Signed-off-by: Philip Cox <philip.cox@canonical.com>
---
 drivers/net/ethernet/intel/igc/igc_ptp.c | 50 ++++++++++++++----------
 1 file changed, 29 insertions(+), 21 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
index b1b93e9a4399..993d339205ed 100644
--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
@@ -1109,6 +1109,30 @@  static void igc_ptp_time_restore(struct igc_adapter *adapter)
 	igc_ptp_write_i225(adapter, &ts);
 }
 
+static void igc_ptm_start(struct igc_adapter *adapter)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u32 cycle_ctrl, ctrl;
+
+	wr32(IGC_PCIE_DIG_DELAY, IGC_PCIE_DIG_DELAY_DEFAULT);
+	wr32(IGC_PCIE_PHY_DELAY, IGC_PCIE_PHY_DELAY_DEFAULT);
+
+	cycle_ctrl = IGC_PTM_CYCLE_CTRL_CYC_TIME(IGC_PTM_CYC_TIME_DEFAULT);
+
+	wr32(IGC_PTM_CYCLE_CTRL, cycle_ctrl);
+
+	ctrl = IGC_PTM_CTRL_EN |
+		IGC_PTM_CTRL_START_NOW |
+		IGC_PTM_CTRL_SHRT_CYC(IGC_PTM_SHORT_CYC_DEFAULT) |
+		IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT) |
+		IGC_PTM_CTRL_TRIG;
+
+	wr32(IGC_PTM_CTRL, ctrl);
+
+	/* Force the first cycle to run. */
+	wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);
+}
+
 static void igc_ptm_stop(struct igc_adapter *adapter)
 {
 	struct igc_hw *hw = &adapter->hw;
@@ -1142,10 +1166,8 @@  void igc_ptp_suspend(struct igc_adapter *adapter)
 
 	spin_unlock(&adapter->ptp_tx_lock);
 
-	if (pci_device_is_present(adapter->pdev)) {
+	if (pci_device_is_present(adapter->pdev))
 		igc_ptp_time_save(adapter);
-		igc_ptm_stop(adapter);
-	}
 }
 
 /**
@@ -1174,7 +1196,6 @@  void igc_ptp_stop(struct igc_adapter *adapter)
 void igc_ptp_reset(struct igc_adapter *adapter)
 {
 	struct igc_hw *hw = &adapter->hw;
-	u32 cycle_ctrl, ctrl;
 	unsigned long flags;
 	u32 timadj;
 
@@ -1199,23 +1220,10 @@  void igc_ptp_reset(struct igc_adapter *adapter)
 		if (!igc_is_crosststamp_supported(adapter))
 			break;
 
-		wr32(IGC_PCIE_DIG_DELAY, IGC_PCIE_DIG_DELAY_DEFAULT);
-		wr32(IGC_PCIE_PHY_DELAY, IGC_PCIE_PHY_DELAY_DEFAULT);
-
-		cycle_ctrl = IGC_PTM_CYCLE_CTRL_CYC_TIME(IGC_PTM_CYC_TIME_DEFAULT);
-
-		wr32(IGC_PTM_CYCLE_CTRL, cycle_ctrl);
-
-		ctrl = IGC_PTM_CTRL_EN |
-			IGC_PTM_CTRL_START_NOW |
-			IGC_PTM_CTRL_SHRT_CYC(IGC_PTM_SHORT_CYC_DEFAULT) |
-			IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT) |
-			IGC_PTM_CTRL_TRIG;
-
-		wr32(IGC_PTM_CTRL, ctrl);
-
-		/* Force the first cycle to run. */
-		wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);
+		if (!test_bit(__IGC_DOWN, &adapter->state))
+			igc_ptm_start(adapter);
+		else
+			igc_ptm_stop(adapter);
 
 		break;
 	default: