Skip to content

Commit ee14cc9

Browse files
vcgomesanguy11
authored andcommitted
igb: Fix missing time sync events
Fix "double" clearing of interrupts, which can cause external events or timestamps to be missed. The E1000_TSIRC Time Sync Interrupt Cause register can be cleared in two ways, by either reading it or by writing '1' into the specific cause bit. This is documented in section 8.16.1. The following flow was used: 1. read E1000_TSIRC into 'tsicr'; 2. handle the interrupts present into 'tsirc' and mark them in 'ack'; 3. write 'ack' into E1000_TSICR; As both (1) and (3) will clear the interrupt cause, if the same interrupt happens again between (1) and (3) it will be ignored, causing events to be missed. Remove the extra clear in (3). Fixes: 00c6557 ("igb: enable internal PPS for the i210") Acked-by: Richard Cochran <[email protected]> Signed-off-by: Vinicius Costa Gomes <[email protected]> Tested-by: Pucha Himasekhar Reddy <[email protected]> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <[email protected]>
1 parent 244ae99 commit ee14cc9

File tree

1 file changed

+5
-18
lines changed

1 file changed

+5
-18
lines changed

drivers/net/ethernet/intel/igb/igb_main.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6985,44 +6985,31 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)
69856985
static void igb_tsync_interrupt(struct igb_adapter *adapter)
69866986
{
69876987
struct e1000_hw *hw = &adapter->hw;
6988-
u32 ack = 0, tsicr = rd32(E1000_TSICR);
6988+
u32 tsicr = rd32(E1000_TSICR);
69896989
struct ptp_clock_event event;
69906990

69916991
if (tsicr & TSINTR_SYS_WRAP) {
69926992
event.type = PTP_CLOCK_PPS;
69936993
if (adapter->ptp_caps.pps)
69946994
ptp_clock_event(adapter->ptp_clock, &event);
6995-
ack |= TSINTR_SYS_WRAP;
69966995
}
69976996

69986997
if (tsicr & E1000_TSICR_TXTS) {
69996998
/* retrieve hardware timestamp */
70006999
schedule_work(&adapter->ptp_tx_work);
7001-
ack |= E1000_TSICR_TXTS;
70027000
}
70037001

7004-
if (tsicr & TSINTR_TT0) {
7002+
if (tsicr & TSINTR_TT0)
70057003
igb_perout(adapter, 0);
7006-
ack |= TSINTR_TT0;
7007-
}
70087004

7009-
if (tsicr & TSINTR_TT1) {
7005+
if (tsicr & TSINTR_TT1)
70107006
igb_perout(adapter, 1);
7011-
ack |= TSINTR_TT1;
7012-
}
70137007

7014-
if (tsicr & TSINTR_AUTT0) {
7008+
if (tsicr & TSINTR_AUTT0)
70157009
igb_extts(adapter, 0);
7016-
ack |= TSINTR_AUTT0;
7017-
}
70187010

7019-
if (tsicr & TSINTR_AUTT1) {
7011+
if (tsicr & TSINTR_AUTT1)
70207012
igb_extts(adapter, 1);
7021-
ack |= TSINTR_AUTT1;
7022-
}
7023-
7024-
/* acknowledge the interrupts */
7025-
wr32(E1000_TSICR, ack);
70267013
}
70277014

70287015
static irqreturn_t igb_msix_other(int irq, void *data)

0 commit comments

Comments
 (0)