Skip to content

Commit 8e404ad

Browse files
christopher-s-hallanguy11
authored andcommitted
igc: fix PTM cycle trigger logic
Writing to clear the PTM status 'valid' bit while the PTM cycle is triggered results in unreliable PTM operation. To fix this, clear the PTM 'trigger' and status after each PTM transaction. The issue can be reproduced with the following: $ sudo phc2sys -R 1000 -O 0 -i tsn0 -m Note: 1000 Hz (-R 1000) is unrealistically large, but provides a way to quickly reproduce the issue. PHC2SYS exits with: "ioctl PTP_OFFSET_PRECISE: Connection timed out" when the PTM transaction fails This patch also fixes a hang in igc_probe() when loading the igc driver in the kdump kernel on systems supporting PTM. The igc driver running in the base kernel enables PTM trigger in igc_probe(). Therefore the driver is always in PTM trigger mode, except in brief periods when manually triggering a PTM cycle. When a crash occurs, the NIC is reset while PTM trigger is enabled. Due to a hardware problem, the NIC is subsequently in a bad busmaster state and doesn't handle register reads/writes. When running igc_probe() in the kdump kernel, the first register access to a NIC register hangs driver probing and ultimately breaks kdump. With this patch, igc has PTM trigger disabled most of the time, and the trigger is only enabled for very brief (10 - 100 us) periods when manually triggering a PTM cycle. Chances that a crash occurs during a PTM trigger are not 0, but extremely reduced. Fixes: a90ec84 ("igc: Add support for PTP getcrosststamp()") Reviewed-by: Michal Swiatkowski <[email protected]> Tested-by: Mor Bar-Gabay <[email protected]> Tested-by: Avigail Dahan <[email protected]> Signed-off-by: Christopher S M Hall <[email protected]> Reviewed-by: Corinna Vinschen <[email protected]> Signed-off-by: Jacob Keller <[email protected]> Tested-by: Corinna Vinschen <[email protected]> Acked-by: Vinicius Costa Gomes <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent cfe8246 commit 8e404ad

File tree

2 files changed

+42
-29
lines changed

2 files changed

+42
-29
lines changed

drivers/net/ethernet/intel/igc/igc_defines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@
593593
#define IGC_PTM_STAT_T4M1_OVFL BIT(3) /* T4 minus T1 overflow */
594594
#define IGC_PTM_STAT_ADJUST_1ST BIT(4) /* 1588 timer adjusted during 1st PTM cycle */
595595
#define IGC_PTM_STAT_ADJUST_CYC BIT(5) /* 1588 timer adjusted during non-1st PTM cycle */
596+
#define IGC_PTM_STAT_ALL GENMASK(5, 0) /* Used to clear all status */
596597

597598
/* PCIe PTM Cycle Control */
598599
#define IGC_PTM_CYCLE_CTRL_CYC_TIME(msec) ((msec) & 0x3ff) /* PTM Cycle Time (msec) */

drivers/net/ethernet/intel/igc/igc_ptp.c

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -974,13 +974,40 @@ static void igc_ptm_log_error(struct igc_adapter *adapter, u32 ptm_stat)
974974
}
975975
}
976976

977+
static void igc_ptm_trigger(struct igc_hw *hw)
978+
{
979+
u32 ctrl;
980+
981+
/* To "manually" start the PTM cycle we need to set the
982+
* trigger (TRIG) bit
983+
*/
984+
ctrl = rd32(IGC_PTM_CTRL);
985+
ctrl |= IGC_PTM_CTRL_TRIG;
986+
wr32(IGC_PTM_CTRL, ctrl);
987+
/* Perform flush after write to CTRL register otherwise
988+
* transaction may not start
989+
*/
990+
wrfl();
991+
}
992+
993+
static void igc_ptm_reset(struct igc_hw *hw)
994+
{
995+
u32 ctrl;
996+
997+
ctrl = rd32(IGC_PTM_CTRL);
998+
ctrl &= ~IGC_PTM_CTRL_TRIG;
999+
wr32(IGC_PTM_CTRL, ctrl);
1000+
/* Write to clear all status */
1001+
wr32(IGC_PTM_STAT, IGC_PTM_STAT_ALL);
1002+
}
1003+
9771004
static int igc_phc_get_syncdevicetime(ktime_t *device,
9781005
struct system_counterval_t *system,
9791006
void *ctx)
9801007
{
981-
u32 stat, t2_curr_h, t2_curr_l, ctrl;
9821008
struct igc_adapter *adapter = ctx;
9831009
struct igc_hw *hw = &adapter->hw;
1010+
u32 stat, t2_curr_h, t2_curr_l;
9841011
int err, count = 100;
9851012
ktime_t t1, t2_curr;
9861013

@@ -994,25 +1021,13 @@ static int igc_phc_get_syncdevicetime(ktime_t *device,
9941021
* are transitory. Repeating the process returns valid
9951022
* data eventually.
9961023
*/
997-
998-
/* To "manually" start the PTM cycle we need to clear and
999-
* then set again the TRIG bit.
1000-
*/
1001-
ctrl = rd32(IGC_PTM_CTRL);
1002-
ctrl &= ~IGC_PTM_CTRL_TRIG;
1003-
wr32(IGC_PTM_CTRL, ctrl);
1004-
ctrl |= IGC_PTM_CTRL_TRIG;
1005-
wr32(IGC_PTM_CTRL, ctrl);
1006-
1007-
/* The cycle only starts "for real" when software notifies
1008-
* that it has read the registers, this is done by setting
1009-
* VALID bit.
1010-
*/
1011-
wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);
1024+
igc_ptm_trigger(hw);
10121025

10131026
err = readx_poll_timeout(rd32, IGC_PTM_STAT, stat,
10141027
stat, IGC_PTM_STAT_SLEEP,
10151028
IGC_PTM_STAT_TIMEOUT);
1029+
igc_ptm_reset(hw);
1030+
10161031
if (err < 0) {
10171032
netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");
10181033
return err;
@@ -1021,15 +1036,7 @@ static int igc_phc_get_syncdevicetime(ktime_t *device,
10211036
if ((stat & IGC_PTM_STAT_VALID) == IGC_PTM_STAT_VALID)
10221037
break;
10231038

1024-
if (stat & ~IGC_PTM_STAT_VALID) {
1025-
/* An error occurred, log it. */
1026-
igc_ptm_log_error(adapter, stat);
1027-
/* The STAT register is write-1-to-clear (W1C),
1028-
* so write the previous error status to clear it.
1029-
*/
1030-
wr32(IGC_PTM_STAT, stat);
1031-
continue;
1032-
}
1039+
igc_ptm_log_error(adapter, stat);
10331040
} while (--count);
10341041

10351042
if (!count) {
@@ -1255,7 +1262,7 @@ void igc_ptp_stop(struct igc_adapter *adapter)
12551262
void igc_ptp_reset(struct igc_adapter *adapter)
12561263
{
12571264
struct igc_hw *hw = &adapter->hw;
1258-
u32 cycle_ctrl, ctrl;
1265+
u32 cycle_ctrl, ctrl, stat;
12591266
unsigned long flags;
12601267
u32 timadj;
12611268

@@ -1290,14 +1297,19 @@ void igc_ptp_reset(struct igc_adapter *adapter)
12901297
ctrl = IGC_PTM_CTRL_EN |
12911298
IGC_PTM_CTRL_START_NOW |
12921299
IGC_PTM_CTRL_SHRT_CYC(IGC_PTM_SHORT_CYC_DEFAULT) |
1293-
IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT) |
1294-
IGC_PTM_CTRL_TRIG;
1300+
IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT);
12951301

12961302
wr32(IGC_PTM_CTRL, ctrl);
12971303

12981304
/* Force the first cycle to run. */
1299-
wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);
1305+
igc_ptm_trigger(hw);
1306+
1307+
if (readx_poll_timeout_atomic(rd32, IGC_PTM_STAT, stat,
1308+
stat, IGC_PTM_STAT_SLEEP,
1309+
IGC_PTM_STAT_TIMEOUT))
1310+
netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");
13001311

1312+
igc_ptm_reset(hw);
13011313
break;
13021314
default:
13031315
/* No work to do. */

0 commit comments

Comments
 (0)