Skip to content

Commit e50a806

Browse files
author
Paolo Abeni
committed
Merge branch 'ice-restore-timestamp-config-after-reset'
Tony Nguyen says: ==================== ice: restore timestamp config after reset Jake Keller says: We recently discovered during internal validation that the ice driver has not been properly restoring Tx timestamp configuration after a device reset, which resulted in application failures after a device reset. After some digging, it turned out this problem is two-fold. Since the introduction of the PTP support the driver has been clobbering the storage of the current timestamp configuration during reset. Thus after a reset, the driver will no longer perform Tx or Rx timestamps, and will report timestamp configuration as disabled if SIOCGHWTSTAMP ioctl is issued. In addition, the recently merged auxiliary bus support code missed that PFINT_TSYN_MSK must be reprogrammed on the clock owner for E822 devices. Failure to restore this register configuration results in the driver no longer responding to interrupts from other ports. Depending on the traffic pattern, this can either result in increased latency responding to timestamps on the non-owner ports, or it can result in the driver never reporting any timestamps. The configuration of PFINT_TSYN_MSK was only done during initialization. Due to this, the Tx timestamp issue persists even if userspace reconfigures timestamping. This series fixes both issues, as well as removes a redundant Tx ring field since we can rely on the skb flag as the primary detector for a Tx timestamp request. Note that I don't think this series will directly apply to older stable releases (even v6.6) as we recently refactored a lot of the PTP code to support auxiliary bus. Patch 2/3 only matters for the post-auxiliary bus implementation. The principle of patch 1/3 and 3/3 could apply as far back as the initial PTP support, but I don't think it will apply cleanly as-is. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents d9775fb + 7758017 commit e50a806

File tree

5 files changed

+83
-82
lines changed

5 files changed

+83
-82
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: 78 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -256,48 +256,42 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin,
256256
}
257257

258258
/**
259-
* ice_ptp_configure_tx_tstamp - Enable or disable Tx timestamp interrupt
260-
* @pf: The PF pointer to search in
261-
* @on: bool value for whether timestamp interrupt is enabled or disabled
259+
* ice_ptp_cfg_tx_interrupt - Configure Tx timestamp interrupt for the device
260+
* @pf: Board private structure
261+
*
262+
* Program the device to respond appropriately to the Tx timestamp interrupt
263+
* cause.
262264
*/
263-
static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on)
265+
static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf)
264266
{
267+
struct ice_hw *hw = &pf->hw;
268+
bool enable;
265269
u32 val;
266270

271+
switch (pf->ptp.tx_interrupt_mode) {
272+
case ICE_PTP_TX_INTERRUPT_ALL:
273+
/* React to interrupts across all quads. */
274+
wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
275+
enable = true;
276+
break;
277+
case ICE_PTP_TX_INTERRUPT_NONE:
278+
/* Do not react to interrupts on any quad. */
279+
wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
280+
enable = false;
281+
break;
282+
case ICE_PTP_TX_INTERRUPT_SELF:
283+
default:
284+
enable = pf->ptp.tstamp_config.tx_type == HWTSTAMP_TX_ON;
285+
break;
286+
}
287+
267288
/* Configure the Tx timestamp interrupt */
268-
val = rd32(&pf->hw, PFINT_OICR_ENA);
269-
if (on)
289+
val = rd32(hw, PFINT_OICR_ENA);
290+
if (enable)
270291
val |= PFINT_OICR_TSYN_TX_M;
271292
else
272293
val &= ~PFINT_OICR_TSYN_TX_M;
273-
wr32(&pf->hw, PFINT_OICR_ENA, val);
274-
}
275-
276-
/**
277-
* ice_set_tx_tstamp - Enable or disable Tx timestamping
278-
* @pf: The PF pointer to search in
279-
* @on: bool value for whether timestamps are enabled or disabled
280-
*/
281-
static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)
282-
{
283-
struct ice_vsi *vsi;
284-
u16 i;
285-
286-
vsi = ice_get_main_vsi(pf);
287-
if (!vsi)
288-
return;
289-
290-
/* Set the timestamp enable flag for all the Tx rings */
291-
ice_for_each_txq(vsi, i) {
292-
if (!vsi->tx_rings[i])
293-
continue;
294-
vsi->tx_rings[i]->ptp_tx = on;
295-
}
296-
297-
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF)
298-
ice_ptp_configure_tx_tstamp(pf, on);
299-
300-
pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
294+
wr32(hw, PFINT_OICR_ENA, val);
301295
}
302296

303297
/**
@@ -311,7 +305,7 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
311305
u16 i;
312306

313307
vsi = ice_get_main_vsi(pf);
314-
if (!vsi)
308+
if (!vsi || !vsi->rx_rings)
315309
return;
316310

317311
/* Set the timestamp flag for all the Rx rings */
@@ -320,23 +314,50 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on)
320314
continue;
321315
vsi->rx_rings[i]->ptp_rx = on;
322316
}
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);
323335

324-
pf->ptp.tstamp_config.rx_filter = on ? HWTSTAMP_FILTER_ALL :
325-
HWTSTAMP_FILTER_NONE;
336+
ice_set_rx_tstamp(pf, false);
326337
}
327338

328339
/**
329-
* ice_ptp_cfg_timestamp - Configure timestamp for init/deinit
340+
* ice_ptp_restore_timestamp_mode - Restore timestamp configuration
330341
* @pf: Board private structure
331-
* @ena: bool value to enable or disable time stamp
332342
*
333-
* This function will configure timestamping during PTP initialization
334-
* and deinitialization
343+
* Called at the end of rebuild to restore timestamp configuration after
344+
* a device reset.
335345
*/
336-
void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena)
346+
void ice_ptp_restore_timestamp_mode(struct ice_pf *pf)
337347
{
338-
ice_set_tx_tstamp(pf, ena);
339-
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);
340361
}
341362

342363
/**
@@ -2037,18 +2058,18 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
20372058
{
20382059
switch (config->tx_type) {
20392060
case HWTSTAMP_TX_OFF:
2040-
ice_set_tx_tstamp(pf, false);
2061+
pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_OFF;
20412062
break;
20422063
case HWTSTAMP_TX_ON:
2043-
ice_set_tx_tstamp(pf, true);
2064+
pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_ON;
20442065
break;
20452066
default:
20462067
return -ERANGE;
20472068
}
20482069

20492070
switch (config->rx_filter) {
20502071
case HWTSTAMP_FILTER_NONE:
2051-
ice_set_rx_tstamp(pf, false);
2072+
pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
20522073
break;
20532074
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
20542075
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
@@ -2064,12 +2085,15 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config)
20642085
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
20652086
case HWTSTAMP_FILTER_NTP_ALL:
20662087
case HWTSTAMP_FILTER_ALL:
2067-
ice_set_rx_tstamp(pf, true);
2088+
pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_ALL;
20682089
break;
20692090
default:
20702091
return -ERANGE;
20712092
}
20722093

2094+
/* Immediately update the device timestamping mode */
2095+
ice_ptp_restore_timestamp_mode(pf);
2096+
20732097
return 0;
20742098
}
20752099

@@ -2737,7 +2761,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf)
27372761
clear_bit(ICE_FLAG_PTP, pf->flags);
27382762

27392763
/* Disable timestamping for both Tx and Rx */
2740-
ice_ptp_cfg_timestamp(pf, false);
2764+
ice_ptp_disable_timestamp_mode(pf);
27412765

27422766
kthread_cancel_delayed_work_sync(&ptp->work);
27432767

@@ -2803,15 +2827,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
28032827
/* Release the global hardware lock */
28042828
ice_ptp_unlock(hw);
28052829

2806-
if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) {
2807-
/* The clock owner for this device type handles the timestamp
2808-
* interrupt for all ports.
2809-
*/
2810-
ice_ptp_configure_tx_tstamp(pf, true);
2811-
2812-
/* React on all quads interrupts for E82x */
2813-
wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f);
2814-
2830+
if (!ice_is_e810(hw)) {
28152831
/* Enable quad interrupts */
28162832
err = ice_ptp_tx_ena_intr(pf, true, itr);
28172833
if (err)
@@ -2881,13 +2897,6 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port)
28812897
case ICE_PHY_E810:
28822898
return ice_ptp_init_tx_e810(pf, &ptp_port->tx);
28832899
case ICE_PHY_E822:
2884-
/* Non-owner PFs don't react to any interrupts on E82x,
2885-
* neither on own quad nor on others
2886-
*/
2887-
if (!ice_ptp_pf_handles_tx_interrupt(pf)) {
2888-
ice_ptp_configure_tx_tstamp(pf, false);
2889-
wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0);
2890-
}
28912900
kthread_init_delayed_work(&ptp_port->ov_work,
28922901
ice_ptp_wait_for_offsets);
28932902

@@ -3032,6 +3041,9 @@ void ice_ptp_init(struct ice_pf *pf)
30323041
/* Start the PHY timestamping block */
30333042
ice_ptp_reset_phy_timestamping(pf);
30343043

3044+
/* Configure initial Tx interrupt settings */
3045+
ice_ptp_cfg_tx_interrupt(pf);
3046+
30353047
set_bit(ICE_FLAG_PTP, pf->flags);
30363048
err = ice_ptp_init_work(pf, ptp);
30373049
if (err)
@@ -3067,7 +3079,7 @@ void ice_ptp_release(struct ice_pf *pf)
30673079
return;
30683080

30693081
/* Disable timestamping for both Tx and Rx */
3070-
ice_ptp_cfg_timestamp(pf, false);
3082+
ice_ptp_disable_timestamp_mode(pf);
30713083

30723084
ice_ptp_remove_auxbus_device(pf);
30733085

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)

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2306,9 +2306,6 @@ ice_tstamp(struct ice_tx_ring *tx_ring, struct sk_buff *skb,
23062306
if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)))
23072307
return;
23082308

2309-
if (!tx_ring->ptp_tx)
2310-
return;
2311-
23122309
/* Tx timestamps cannot be sampled when doing TSO */
23132310
if (first->tx_flags & ICE_TX_FLAGS_TSO)
23142311
return;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,6 @@ struct ice_tx_ring {
380380
#define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2)
381381
u8 flags;
382382
u8 dcb_tc; /* Traffic class of ring */
383-
u8 ptp_tx;
384383
} ____cacheline_internodealigned_in_smp;
385384

386385
static inline bool ice_ring_uses_build_skb(struct ice_rx_ring *ring)

0 commit comments

Comments
 (0)