Skip to content

Commit 7758017

Browse files
jacob-kellerPaolo Abeni
authored andcommitted
ice: restore timestamp configuration after device reset
The driver calls ice_ptp_cfg_timestamp() during ice_ptp_prepare_for_reset() to disable timestamping while the device is resetting. This operation destroys the user requested configuration. While the driver does call ice_ptp_cfg_timestamp in ice_rebuild() to restore some hardware settings after a reset, it unconditionally passes true or false, resulting in failure to restore previous user space configuration. This results in a device reset forcibly disabling timestamp configuration regardless of current user settings. This was not detected previously due to a quirk of the LinuxPTP ptp4l application. If ptp4l detects a missing timestamp, it enters a fault state and performs recovery logic which includes executing SIOCSHWTSTAMP again, restoring the now accidentally cleared configuration. Not every application does this, and for these applications, timestamps will mysteriously stop after a PF reset, without being restored until an application restart. Fix this by replacing ice_ptp_cfg_timestamp() with two new functions: 1) ice_ptp_disable_timestamp_mode() which unconditionally disables the timestamping logic in ice_ptp_prepare_for_reset() and ice_ptp_release() 2) ice_ptp_restore_timestamp_mode() which calls ice_ptp_restore_tx_interrupt() to restore Tx timestamping configuration, calls ice_set_rx_tstamp() to restore Rx timestamping configuration, and issues an immediate TSYN_TX interrupt to ensure that timestamps which may have occurred during the device reset get processed. Modify the ice_ptp_set_timestamp_mode to directly save the user configuration and then call ice_ptp_restore_timestamp_mode. This way, reset no longer destroys the saved user configuration. This obsoletes the ice_set_tx_tstamp() function which can now be safely removed. With this change, all devices should now restore Tx and Rx timestamping functionality correctly after a PF reset without application intervention. Fixes: 77a7811 ("ice: enable receive hardware timestamping") Fixes: ea9b847 ("ice: enable transmit timestamps for E810 devices") Signed-off-by: Jacob Keller <[email protected]> Reviewed-by: Jesse Brandeburg <[email protected]> Reviewed-by: Simon Horman <[email protected]> Tested-by: Pucha Himasekhar Reddy <[email protected]> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 7d606a1 commit 7758017

File tree

3 files changed

+51
-40
lines changed

3 files changed

+51
-40
lines changed

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7401,15 +7401,6 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
74017401
goto err_vsi_rebuild;
74027402
}
74037403

7404-
/* configure PTP timestamping after VSI rebuild */
7405-
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags)) {
7406-
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
7407-
ice_ptp_cfg_timestamp(pf, false);
7408-
else if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL)
7409-
/* for E82x PHC owner always need to have interrupts */
7410-
ice_ptp_cfg_timestamp(pf, true);
7411-
}
7412-
74137404
err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL);
74147405
if (err) {
74157406
dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err);
@@ -7461,6 +7452,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
74617452
ice_plug_aux_dev(pf);
74627453
if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG))
74637454
ice_lag_rebuild(pf);
7455+
7456+
/* Restore timestamp mode settings after VSI rebuild */
7457+
ice_ptp_restore_timestamp_mode(pf);
74647458
return;
74657459

74667460
err_vsi_rebuild:

drivers/net/ethernet/intel/ice/ice_ptp.c

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -294,18 +294,6 @@ static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf)
294294
wr32(hw, PFINT_OICR_ENA, val);
295295
}
296296

297-
/**
298-
* ice_set_tx_tstamp - Enable or disable Tx timestamping
299-
* @pf: The PF pointer to search in
300-
* @on: bool value for whether timestamps are enabled or disabled
301-
*/
302-
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
303-
{
304-
pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
305-
306-
ice_ptp_cfg_tx_interrupt(pf);
307-
}
308-
309297
/**
310298
* ice_set_rx_tstamp - Enable or disable Rx timestamping
311299
* @pf: The PF pointer to search in
@@ -317,7 +305,7 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
317305
u16 i;
318306

319307
vsi = ice_get_main_vsi(pf);
320-
if (!vsi)
308+
if (!vsi || !vsi->rx_rings)
321309
return;
322310

323311
/* Set the timestamp flag for all the Rx rings */
@@ -326,23 +314,50 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
326314
continue;
327315
vsi->rx_rings[i]->ptp_rx = on;
328316
}
317+
}
318+
319+
/**
320+
* ice_ptp_disable_timestamp_mode - Disable current timestamp mode
321+
* @pf: Board private structure
322+
*
323+
* Called during preparation for reset to temporarily disable timestamping on
324+
* the device. Called during remove to disable timestamping while cleaning up
325+
* driver resources.
326+
*/
327+
static void ice_ptp_disable_timestamp_mode(struct ice_pf *pf)
328+
{
329+
struct ice_hw *hw = &pf->hw;
330+
u32 val;
331+
332+
val = rd32(hw, PFINT_OICR_ENA);
333+
val &= ~PFINT_OICR_TSYN_TX_M;
334+
wr32(hw, PFINT_OICR_ENA, val);
329335

330-
pf->ptp.tstamp_config.rx_filter = on ? HWTSTAMP_FILTER_ALL :
331-
HWTSTAMP_FILTER_NONE;
336+
ice_set_rx_tstamp(pf, false);
332337
}
333338

334339
/**
335-
* ice_ptp_cfg_timestamp - Configure timestamp for init/deinit
340+
* ice_ptp_restore_timestamp_mode - Restore timestamp configuration
336341
* @pf: Board private structure
337-
* @ena: bool value to enable or disable time stamp
338342
*
339-
* This function will configure timestamping during PTP initialization
340-
* and deinitialization
343+
* Called at the end of rebuild to restore timestamp configuration after
344+
* a device reset.
341345
*/
342-
void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena)
346+
void ice_ptp_restore_timestamp_mode(struct ice_pf *pf)
343347
{
344-
ice_set_tx_tstamp(pf, ena);
345-
ice_set_rx_tstamp(pf, ena);
348+
struct ice_hw *hw = &pf->hw;
349+
bool enable_rx;
350+
351+
ice_ptp_cfg_tx_interrupt(pf);
352+
353+
enable_rx = pf->ptp.tstamp_config.rx_filter == HWTSTAMP_FILTER_ALL;
354+
ice_set_rx_tstamp(pf, enable_rx);
355+
356+
/* Trigger an immediate software interrupt to ensure that timestamps
357+
* which occurred during reset are handled now.
358+
*/
359+
wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
360+
ice_flush(hw);
346361
}
347362

348363
/**
@@ -2043,18 +2058,18 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
20432058
{
20442059
switch (config->tx_type) {
20452060
case HWTSTAMP_TX_OFF:
2046-
ice_set_tx_tstamp(pf, false);
2061+
pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_OFF;
20472062
break;
20482063
case HWTSTAMP_TX_ON:
2049-
ice_set_tx_tstamp(pf, true);
2064+
pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_ON;
20502065
break;
20512066
default:
20522067
return -ERANGE;
20532068
}
20542069

20552070
switch (config->rx_filter) {
20562071
case HWTSTAMP_FILTER_NONE:
2057-
ice_set_rx_tstamp(pf, false);
2072+
pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
20582073
break;
20592074
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
20602075
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
@@ -2070,12 +2085,15 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
20702085
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
20712086
case HWTSTAMP_FILTER_NTP_ALL:
20722087
case HWTSTAMP_FILTER_ALL:
2073-
ice_set_rx_tstamp(pf, true);
2088+
pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_ALL;
20742089
break;
20752090
default:
20762091
return -ERANGE;
20772092
}
20782093

2094+
/* Immediately update the device timestamping mode */
2095+
ice_ptp_restore_timestamp_mode(pf);
2096+
20792097
return 0;
20802098
}
20812099

@@ -2743,7 +2761,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
27432761
clear_bit(ICE_FLAG_PTP, pf->flags);
27442762

27452763
/* Disable timestamping for both Tx and Rx */
2746-
ice_ptp_cfg_timestamp(pf, false);
2764+
ice_ptp_disable_timestamp_mode(pf);
27472765

27482766
kthread_cancel_delayed_work_sync(&ptp->work);
27492767

@@ -3061,7 +3079,7 @@ void ice_ptp_release(struct ice_pf *pf)
30613079
return;
30623080

30633081
/* Disable timestamping for both Tx and Rx */
3064-
ice_ptp_cfg_timestamp(pf, false);
3082+
ice_ptp_disable_timestamp_mode(pf);
30653083

30663084
ice_ptp_remove_auxbus_device(pf);
30673085

drivers/net/ethernet/intel/ice/ice_ptp.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ int ice_ptp_clock_index(struct ice_pf *pf);
292292
struct ice_pf;
293293
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr);
294294
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
295-
void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena);
295+
void ice_ptp_restore_timestamp_mode(struct ice_pf *pf);
296296

297297
void ice_ptp_extts_event(struct ice_pf *pf);
298298
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
@@ -317,8 +317,7 @@ static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
317317
return -EOPNOTSUPP;
318318
}
319319

320-
static inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { }
321-
320+
static inline void ice_ptp_restore_timestamp_mode(struct ice_pf *pf) { }
322321
static inline void ice_ptp_extts_event(struct ice_pf *pf) { }
323322
static inline s8
324323
ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)

0 commit comments

Comments
 (0)