sfc: Tidy up PTP synchronization code
authorLaurence Evans <levans@solarflare.com>
Thu, 21 Nov 2013 10:38:24 +0000 (10:38 +0000)
committerBen Hutchings <bhutchings@solarflare.com>
Thu, 12 Dec 2013 22:07:08 +0000 (22:07 +0000)
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
drivers/net/ethernet/sfc/ptp.c

index 82d8e27..361d7ce 100644 (file)
@@ -435,7 +435,6 @@ efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf),
                MCDI_VAR_ARRAY_LEN(response_length,
                                   PTP_OUT_SYNCHRONIZE_TIMESET);
        unsigned i;
-       unsigned total;
        unsigned ngood = 0;
        unsigned last_good = 0;
        struct efx_ptp_data *ptp = efx->ptp_data;
@@ -446,33 +445,38 @@ efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf),
        if (number_readings == 0)
                return -EAGAIN;
 
-       /* Read the set of results and increment stats for any results that
-        * appera to be erroneous.
+       /* Read the set of results and find the last good host-MC
+        * synchronization result. The MC times when it finishes reading the
+        * host time so the corrected window time should be fairly constant
+        * for a given platform.
         */
        for (i = 0; i < number_readings; i++) {
+               s32 window, corrected;
+
                efx_ptp_read_timeset(
                        MCDI_ARRAY_STRUCT_PTR(synch_buf,
                                              PTP_OUT_SYNCHRONIZE_TIMESET, i),
                        &ptp->timeset[i]);
-       }
 
-       /* Find the last good host-MC synchronization result. The MC times
-        * when it finishes reading the host time so the corrected window time
-        * should be fairly constant for a given platform.
-        */
-       total = 0;
-       for (i = 0; i < number_readings; i++)
-               if (ptp->timeset[i].window > ptp->timeset[i].waitns) {
-                       unsigned win;
-
-                       win = ptp->timeset[i].window - ptp->timeset[i].waitns;
-                       if (win >= MIN_SYNCHRONISATION_NS &&
-                           win < MAX_SYNCHRONISATION_NS) {
-                               total += ptp->timeset[i].window;
-                               ngood++;
-                               last_good = i;
-                       }
+               window = ptp->timeset[i].window;
+               corrected = window - ptp->timeset[i].waitns;
+
+               /* We expect the uncorrected synchronization window to be at
+                * least as large as the interval between host start and end
+                * times. If it is smaller than this then this is mostly likely
+                * to be a consequence of the host's time being adjusted.
+                * Check that the corrected sync window is in a reasonable
+                * range. If it is out of range it is likely to be because an
+                * interrupt or other delay occurred between reading the system
+                * time and writing it to MC memory.
+                */
+               if (window >= SYNCHRONISATION_GRANULARITY_NS &&
+                   corrected < MAX_SYNCHRONISATION_NS &&
+                   corrected >= MIN_SYNCHRONISATION_NS) {
+                       ngood++;
+                       last_good = i;
                }
+       }
 
        if (ngood == 0) {
                netif_warn(efx, drv, efx->net_dev,