]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
net: eqos: handle rollover of PHC
authorabhijit <abhijit@nvidia.com>
Tue, 13 Jun 2017 17:17:41 +0000 (22:47 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Mon, 19 Jun 2017 09:04:46 +0000 (02:04 -0700)
Issue: ptp get_systime is not handling the rollover of nsec counter.

Fix: Handle the nsec rollover by reading the nsec counter twice. if
second read value is lower than first value, read the sec counter
again to handle rollover.

Bug 200317864

Change-Id: Ie9d09203d388656ebf8c18dd263d2d08e5c52467
Reviewed-on: http://git-master/r/1500673
(cherry picked from commit 567d97e7bfeec20cb6a196b0d874d2e0f14f3fa9)
Reviewed-on: http://git-master/r/1503234
GVS: Gerrit_Virtual_Submit
Tested-by: Abhijit . <abhijit@nvidia.com>
Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
drivers/net/ethernet/nvidia/eqos/dev.c

index afb9036949e98b215cc2dabffee63905e4a94cbc..a47da472d68a73b0262cc6afad89f17b2686df96 100644 (file)
@@ -29,7 +29,7 @@
  * DAMAGE.
  * ========================================================================= */
 /*
- * Copyright (c) 2015-2016, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2015-2017, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -795,15 +795,26 @@ static INT config_sub_second_increment(ULONG ptp_clock)
 
 static ULONG_LONG get_systime(void)
 {
-       ULONG_LONG ns;
+       ULONG_LONG ns1, ns2, ns;
        ULONG varmac_stnsr;
        ULONG varmac_stsr;
 
        MAC_STNSR_RD(varmac_stnsr);
-       ns = GET_VALUE(varmac_stnsr, MAC_STNSR_TSSS_LPOS, MAC_STNSR_TSSS_HPOS);
-       /* convert sec/high time value to nanosecond */
+       ns1 = GET_VALUE(varmac_stnsr, MAC_STNSR_TSSS_LPOS, MAC_STNSR_TSSS_HPOS);
+
        MAC_STSR_RD(varmac_stsr);
-       ns = ns + (varmac_stsr * 1000000000ull);
+
+       MAC_STNSR_RD(varmac_stnsr);
+       ns2 = GET_VALUE(varmac_stnsr, MAC_STNSR_TSSS_LPOS, MAC_STNSR_TSSS_HPOS);
+
+       if (ns1 >= ns2) {
+               MAC_STSR_RD(varmac_stsr);
+               /* convert sec/high time value to nanosecond */
+               ns = ns2 + (varmac_stsr * 1000000000ull);
+       } else {
+               /* convert sec/high time value to nanosecond */
+               ns = ns1 + (varmac_stsr * 1000000000ull);
+       }
 
        return ns;
 }