aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2016-04-20 14:36:42 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2016-05-13 18:30:44 -0400
commitaa524b66c5efd1d3220b74168d803e8b2ee1d212 (patch)
treef6c0b0894d4cfa0debda7066470e480e9e0845ae
parente10715d3e9618901c5ef820a92e6a8e6548b43d3 (diff)
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>
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h1
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c68
-rw-r--r--drivers/net/ethernet/intel/e1000e/ptp.c2
3 files changed, 55 insertions, 16 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index 010e6d61c855..ef96cd11d6d2 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -347,6 +347,7 @@ struct e1000_adapter {
347 struct ptp_clock *ptp_clock; 347 struct ptp_clock *ptp_clock;
348 struct ptp_clock_info ptp_clock_info; 348 struct ptp_clock_info ptp_clock_info;
349 struct pm_qos_request pm_qos_req; 349 struct pm_qos_request pm_qos_req;
350 s32 ptp_delta;
350 351
351 u16 eee_advert; 352 u16 eee_advert;
352}; 353};
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index c597398f2922..75e60897b7e7 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -3580,7 +3580,6 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
3580 bool is_l4 = false; 3580 bool is_l4 = false;
3581 bool is_l2 = false; 3581 bool is_l2 = false;
3582 u32 regval; 3582 u32 regval;
3583 s32 ret_val;
3584 3583
3585 if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP)) 3584 if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
3586 return -EINVAL; 3585 return -EINVAL;
@@ -3719,16 +3718,6 @@ static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
3719 er32(RXSTMPH); 3718 er32(RXSTMPH);
3720 er32(TXSTMPH); 3719 er32(TXSTMPH);
3721 3720
3722 /* Get and set the System Time Register SYSTIM base frequency */
3723 ret_val = e1000e_get_base_timinca(adapter, &regval);
3724 if (ret_val)
3725 return ret_val;
3726 ew32(TIMINCA, regval);
3727
3728 /* reset the ns time counter */
3729 timecounter_init(&adapter->tc, &adapter->cc,
3730 ktime_to_ns(ktime_get_real()));
3731
3732 return 0; 3721 return 0;
3733} 3722}
3734 3723
@@ -3885,6 +3874,53 @@ static void e1000_flush_desc_rings(struct e1000_adapter *adapter)
3885} 3874}
3886 3875
3887/** 3876/**
3877 * e1000e_systim_reset - reset the timesync registers after a hardware reset
3878 * @adapter: board private structure
3879 *
3880 * When the MAC is reset, all hardware bits for timesync will be reset to the
3881 * default values. This function will restore the settings last in place.
3882 * Since the clock SYSTIME registers are reset, we will simply restore the
3883 * cyclecounter to the kernel real clock time.
3884 **/
3885static void e1000e_systim_reset(struct e1000_adapter *adapter)
3886{
3887 struct ptp_clock_info *info = &adapter->ptp_clock_info;
3888 struct e1000_hw *hw = &adapter->hw;
3889 unsigned long flags;
3890 u32 timinca;
3891 s32 ret_val;
3892
3893 if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
3894 return;
3895
3896 if (info->adjfreq) {
3897 /* restore the previous ptp frequency delta */
3898 ret_val = info->adjfreq(info, adapter->ptp_delta);
3899 } else {
3900 /* set the default base frequency if no adjustment possible */
3901 ret_val = e1000e_get_base_timinca(adapter, &timinca);
3902 if (!ret_val)
3903 ew32(TIMINCA, timinca);
3904 }
3905
3906 if (ret_val) {
3907 dev_warn(&adapter->pdev->dev,
3908 "Failed to restore TIMINCA clock rate delta: %d\n",
3909 ret_val);
3910 return;
3911 }
3912
3913 /* reset the systim ns time counter */
3914 spin_lock_irqsave(&adapter->systim_lock, flags);
3915 timecounter_init(&adapter->tc, &adapter->cc,
3916 ktime_to_ns(ktime_get_real()));
3917 spin_unlock_irqrestore(&adapter->systim_lock, flags);
3918
3919 /* restore the previous hwtstamp configuration settings */
3920 e1000e_config_hwtstamp(adapter, &adapter->hwtstamp_config);
3921}
3922
3923/**
3888 * e1000e_reset - bring the hardware into a known good state 3924 * e1000e_reset - bring the hardware into a known good state
3889 * 3925 *
3890 * This function boots the hardware and enables some settings that 3926 * This function boots the hardware and enables some settings that
@@ -4063,8 +4099,8 @@ void e1000e_reset(struct e1000_adapter *adapter)
4063 4099
4064 e1000e_reset_adaptive(hw); 4100 e1000e_reset_adaptive(hw);
4065 4101
4066 /* initialize systim and reset the ns time counter */ 4102 /* restore systim and hwtstamp settings */
4067 e1000e_config_hwtstamp(adapter, &adapter->hwtstamp_config); 4103 e1000e_systim_reset(adapter);
4068 4104
4069 /* Set EEE advertisement as appropriate */ 4105 /* Set EEE advertisement as appropriate */
4070 if (adapter->flags2 & FLAG2_HAS_EEE) { 4106 if (adapter->flags2 & FLAG2_HAS_EEE) {
@@ -7239,6 +7275,9 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7239 adapter->eeprom_vers = 0; 7275 adapter->eeprom_vers = 0;
7240 } 7276 }
7241 7277
7278 /* init PTP hardware clock */
7279 e1000e_ptp_init(adapter);
7280
7242 /* reset the hardware with the new settings */ 7281 /* reset the hardware with the new settings */
7243 e1000e_reset(adapter); 7282 e1000e_reset(adapter);
7244 7283
@@ -7257,9 +7296,6 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7257 /* carrier off reporting is important to ethtool even BEFORE open */ 7296 /* carrier off reporting is important to ethtool even BEFORE open */
7258 netif_carrier_off(netdev); 7297 netif_carrier_off(netdev);
7259 7298
7260 /* init PTP hardware clock */
7261 e1000e_ptp_init(adapter);
7262
7263 e1000_print_device_info(adapter); 7299 e1000_print_device_info(adapter);
7264 7300
7265 if (pci_dev_run_wake(pdev)) 7301 if (pci_dev_run_wake(pdev))
diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c
index e2ff3ef75d5d..2e1b17ad52a3 100644
--- a/drivers/net/ethernet/intel/e1000e/ptp.c
+++ b/drivers/net/ethernet/intel/e1000e/ptp.c
@@ -79,6 +79,8 @@ static int e1000e_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
79 79
80 ew32(TIMINCA, timinca); 80 ew32(TIMINCA, timinca);
81 81
82 adapter->ptp_delta = delta;
83
82 spin_unlock_irqrestore(&adapter->systim_lock, flags); 84 spin_unlock_irqrestore(&adapter->systim_lock, flags);
83 85
84 return 0; 86 return 0;