From: Jacob Keller <jacob.e.keller@intel.com>
To ensure that the E825 PHY timer begins in a clean state, initiate a PHY
soft reset prior to programming the PHY. This ensures that we clear any
outstanding Tx timestamp memory, and ensures that the PHY internal state
including its timestamp counter has been reset.
Note that despite the name, this PHY soft reset only impacts the timer
block of the PHY, and not its regular Tx/Rx functionality. Additionally,
many configuration registers such as the PHY_REG_TS_INT_CONFIG and
PHY_REG_TX_OFFSET_READY are not reset.
Since the E825 PHY restart procedure now performs a soft reset, flush the
outstanding timestamps instead of marking them as stale. This avoids
keeping those indexes locked in software unnecessarily for 2 seconds. This
is safe because the soft reset procedure will restore the timestamp state
and clear any desync.
Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products")
Reviewed-by: Maciek Machnikowski <redacted>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ice/ice_ptp.c | 5 +++--
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 12 +++++++++---
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
index 365cff9c1017..32be908373c3 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
@@ -756,7 +756,8 @@ ice_ptp_alloc_tx_tracker(struct ice_ptp_tx *tx)
* @pf: Board private structure
* @tx: the tracker to flush
*
- * Called during teardown when a Tx tracker is being removed.
+ * Called to immediately discard any outstanding Tx timestamps, including when
+ * tearing down the Tx tracker, and on E825 when restarting the PHY.
*/
static void
ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
@@ -1327,7 +1328,7 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
ptp_port->tx.calibrating = true;
spin_unlock_irqrestore(&ptp_port->tx.lock, flags);
- ice_ptp_mark_tx_tracker_stale(&ptp_port->tx);
+ ice_ptp_flush_tx_tracker(pf, &ptp_port->tx);
err = ice_start_phy_timer_eth56g(hw, port);
if (err)
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
index 38d0ded1d0cc..51442b26516e 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
@@ -2128,9 +2128,11 @@ int ice_stop_phy_timer_eth56g(struct ice_hw *hw, u8 port)
* @hw: pointer to the HW struct
* @port: the PHY port to start
*
- * Start the clock of a PHY port. This must be done as part of the flow to
- * re-calibrate Tx and Rx timestamping offsets whenever the clock time is
- * initialized or when link speed changes.
+ * Perform a PHY soft reset and then start the clock for the PHY port.
+ *
+ * This must be done as part of the flow to re-calibrate Tx and Rx
+ * timestamping offsets whenever the clock time is initialized or when link
+ * speed changes.
*
* Return:
* * %0 - success
@@ -2150,6 +2152,10 @@ int ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port)
if (err)
return err;
+ err = ice_ptp_phy_soft_reset_eth56g(hw, port);
+ if (err)
+ return err;
+
ice_ptp_src_cmd(hw, ICE_PTP_NOP);
err = ice_phy_cfg_parpcs_eth56g(hw, port);
--
2.47.1