e1000e: don't modify SYSTIM registers during SIOCSHWTSTAMP ioctl
authorJacob Keller <jacob.e.keller@intel.com>
Wed, 20 Apr 2016 18:36:42 +0000 (11:36 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 13 May 2016 22:30:44 +0000 (15:30 -0700)
commitaa524b66c5efd1d3220b74168d803e8b2ee1d212
treef6c0b0894d4cfa0debda7066470e480e9e0845ae
parente10715d3e9618901c5ef820a92e6a8e6548b43d3
e1000e: don't modify SYSTIM registers during SIOCSHWTSTAMP ioctl

The e1000e_config_hwtstamp function was incorrectly resetting the SYSTIM
registers every time the ioctl was being run. If you happened to be
running ptp4l and lost the PTP connect (removing cable, or blocking the
UDP traffic for example), then ptp4l will eventually perform a restart
which involves re-requesting timestamp settings. In e1000e this has the
unfortunate and incorrect result of resetting SYSTIME to the kernel
time. Since kernel time is usually in UTC, and PTP time is in TAI, this
results in the leap second being re-applied.

Fix this by extracting the SYSTIME reset out into its own function,
e1000e_ptp_reset, which we call during reset to restore the hardware
registers. This function will (a) restart the timecounter based on the
new system time, (b) restore the previous PPB setting, and (c) restore
the previous hwtstamp settings.

In order to perform (b), I had to modify the adjfreq ptp function
pointer to store the old delta each time it is called. This also has the
side effect of restoring the correct base timinca register correctly.
The driver does not need to explicitly zero the ptp_delta variable since
the entire adapter structure comes zero-initialized.

Reported-by: Brian Walsh <brian@walsh.ws>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Brian Walsh <brian@walsh.ws>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/e1000e/e1000.h
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/e1000e/ptp.c