9
9
#include <linux/ptp_classify.h>
10
10
#include <linux/clocksource.h>
11
11
#include <linux/ktime.h>
12
+ #include <linux/delay.h>
13
+ #include <linux/iopoll.h>
12
14
13
15
#define INCVALUE_MASK 0x7fffffff
14
16
#define ISGN 0x80000000
15
17
16
18
#define IGC_SYSTIM_OVERFLOW_PERIOD (HZ * 60 * 9)
17
19
#define IGC_PTP_TX_TIMEOUT (HZ * 15)
18
20
21
+ #define IGC_PTM_STAT_SLEEP 2
22
+ #define IGC_PTM_STAT_TIMEOUT 100
23
+
19
24
/* SYSTIM read access for I225 */
20
25
void igc_ptp_read (struct igc_adapter * adapter , struct timespec64 * ts )
21
26
{
@@ -752,6 +757,147 @@ int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
752
757
- EFAULT : 0 ;
753
758
}
754
759
760
+ /* The two conditions below must be met for cross timestamping via
761
+ * PCIe PTM:
762
+ *
763
+ * 1. We have an way to convert the timestamps in the PTM messages
764
+ * to something related to the system clocks (right now, only
765
+ * X86 systems with support for the Always Running Timer allow that);
766
+ *
767
+ * 2. We have PTM enabled in the path from the device to the PCIe root port.
768
+ */
769
+ static bool igc_is_crosststamp_supported (struct igc_adapter * adapter )
770
+ {
771
+ return IS_ENABLED (CONFIG_X86_TSC ) ? pcie_ptm_enabled (adapter -> pdev ) : false;
772
+ }
773
+
774
+ static struct system_counterval_t igc_device_tstamp_to_system (u64 tstamp )
775
+ {
776
+ #if IS_ENABLED (CONFIG_X86_TSC )
777
+ return convert_art_ns_to_tsc (tstamp );
778
+ #else
779
+ return (struct system_counterval_t ) { };
780
+ #endif
781
+ }
782
+
783
+ static void igc_ptm_log_error (struct igc_adapter * adapter , u32 ptm_stat )
784
+ {
785
+ struct net_device * netdev = adapter -> netdev ;
786
+
787
+ switch (ptm_stat ) {
788
+ case IGC_PTM_STAT_RET_ERR :
789
+ netdev_err (netdev , "PTM Error: Root port timeout\n" );
790
+ break ;
791
+ case IGC_PTM_STAT_BAD_PTM_RES :
792
+ netdev_err (netdev , "PTM Error: Bad response, PTM Response Data expected\n" );
793
+ break ;
794
+ case IGC_PTM_STAT_T4M1_OVFL :
795
+ netdev_err (netdev , "PTM Error: T4 minus T1 overflow\n" );
796
+ break ;
797
+ case IGC_PTM_STAT_ADJUST_1ST :
798
+ netdev_err (netdev , "PTM Error: 1588 timer adjusted during first PTM cycle\n" );
799
+ break ;
800
+ case IGC_PTM_STAT_ADJUST_CYC :
801
+ netdev_err (netdev , "PTM Error: 1588 timer adjusted during non-first PTM cycle\n" );
802
+ break ;
803
+ default :
804
+ netdev_err (netdev , "PTM Error: Unknown error (%#x)\n" , ptm_stat );
805
+ break ;
806
+ }
807
+ }
808
+
809
+ static int igc_phc_get_syncdevicetime (ktime_t * device ,
810
+ struct system_counterval_t * system ,
811
+ void * ctx )
812
+ {
813
+ u32 stat , t2_curr_h , t2_curr_l , ctrl ;
814
+ struct igc_adapter * adapter = ctx ;
815
+ struct igc_hw * hw = & adapter -> hw ;
816
+ int err , count = 100 ;
817
+ ktime_t t1 , t2_curr ;
818
+
819
+ /* Get a snapshot of system clocks to use as historic value. */
820
+ ktime_get_snapshot (& adapter -> snapshot );
821
+
822
+ do {
823
+ /* Doing this in a loop because in the event of a
824
+ * badly timed (ha!) system clock adjustment, we may
825
+ * get PTM errors from the PCI root, but these errors
826
+ * are transitory. Repeating the process returns valid
827
+ * data eventually.
828
+ */
829
+
830
+ /* To "manually" start the PTM cycle we need to clear and
831
+ * then set again the TRIG bit.
832
+ */
833
+ ctrl = rd32 (IGC_PTM_CTRL );
834
+ ctrl &= ~IGC_PTM_CTRL_TRIG ;
835
+ wr32 (IGC_PTM_CTRL , ctrl );
836
+ ctrl |= IGC_PTM_CTRL_TRIG ;
837
+ wr32 (IGC_PTM_CTRL , ctrl );
838
+
839
+ /* The cycle only starts "for real" when software notifies
840
+ * that it has read the registers, this is done by setting
841
+ * VALID bit.
842
+ */
843
+ wr32 (IGC_PTM_STAT , IGC_PTM_STAT_VALID );
844
+
845
+ err = readx_poll_timeout (rd32 , IGC_PTM_STAT , stat ,
846
+ stat , IGC_PTM_STAT_SLEEP ,
847
+ IGC_PTM_STAT_TIMEOUT );
848
+ if (err < 0 ) {
849
+ netdev_err (adapter -> netdev , "Timeout reading IGC_PTM_STAT register\n" );
850
+ return err ;
851
+ }
852
+
853
+ if ((stat & IGC_PTM_STAT_VALID ) == IGC_PTM_STAT_VALID )
854
+ break ;
855
+
856
+ if (stat & ~IGC_PTM_STAT_VALID ) {
857
+ /* An error occurred, log it. */
858
+ igc_ptm_log_error (adapter , stat );
859
+ /* The STAT register is write-1-to-clear (W1C),
860
+ * so write the previous error status to clear it.
861
+ */
862
+ wr32 (IGC_PTM_STAT , stat );
863
+ continue ;
864
+ }
865
+ } while (-- count );
866
+
867
+ if (!count ) {
868
+ netdev_err (adapter -> netdev , "Exceeded number of tries for PTM cycle\n" );
869
+ return - ETIMEDOUT ;
870
+ }
871
+
872
+ t1 = ktime_set (rd32 (IGC_PTM_T1_TIM0_H ), rd32 (IGC_PTM_T1_TIM0_L ));
873
+
874
+ t2_curr_l = rd32 (IGC_PTM_CURR_T2_L );
875
+ t2_curr_h = rd32 (IGC_PTM_CURR_T2_H );
876
+
877
+ /* FIXME: When the register that tells the endianness of the
878
+ * PTM registers are implemented, check them here and add the
879
+ * appropriate conversion.
880
+ */
881
+ t2_curr_h = swab32 (t2_curr_h );
882
+
883
+ t2_curr = ((s64 )t2_curr_h << 32 | t2_curr_l );
884
+
885
+ * device = t1 ;
886
+ * system = igc_device_tstamp_to_system (t2_curr );
887
+
888
+ return 0 ;
889
+ }
890
+
891
+ static int igc_ptp_getcrosststamp (struct ptp_clock_info * ptp ,
892
+ struct system_device_crosststamp * cts )
893
+ {
894
+ struct igc_adapter * adapter = container_of (ptp , struct igc_adapter ,
895
+ ptp_caps );
896
+
897
+ return get_device_system_crosststamp (igc_phc_get_syncdevicetime ,
898
+ adapter , & adapter -> snapshot , cts );
899
+ }
900
+
755
901
/**
756
902
* igc_ptp_init - Initialize PTP functionality
757
903
* @adapter: Board private structure
@@ -788,6 +934,11 @@ void igc_ptp_init(struct igc_adapter *adapter)
788
934
adapter -> ptp_caps .n_per_out = IGC_N_PEROUT ;
789
935
adapter -> ptp_caps .n_pins = IGC_N_SDP ;
790
936
adapter -> ptp_caps .verify = igc_ptp_verify_pin ;
937
+
938
+ if (!igc_is_crosststamp_supported (adapter ))
939
+ break ;
940
+
941
+ adapter -> ptp_caps .getcrosststamp = igc_ptp_getcrosststamp ;
791
942
break ;
792
943
default :
793
944
adapter -> ptp_clock = NULL ;
@@ -878,7 +1029,9 @@ void igc_ptp_stop(struct igc_adapter *adapter)
878
1029
void igc_ptp_reset (struct igc_adapter * adapter )
879
1030
{
880
1031
struct igc_hw * hw = & adapter -> hw ;
1032
+ u32 cycle_ctrl , ctrl ;
881
1033
unsigned long flags ;
1034
+ u32 timadj ;
882
1035
883
1036
/* reset the tstamp_config */
884
1037
igc_ptp_set_timestamp_mode (adapter , & adapter -> tstamp_config );
@@ -887,12 +1040,38 @@ void igc_ptp_reset(struct igc_adapter *adapter)
887
1040
888
1041
switch (adapter -> hw .mac .type ) {
889
1042
case igc_i225 :
1043
+ timadj = rd32 (IGC_TIMADJ );
1044
+ timadj |= IGC_TIMADJ_ADJUST_METH ;
1045
+ wr32 (IGC_TIMADJ , timadj );
1046
+
890
1047
wr32 (IGC_TSAUXC , 0x0 );
891
1048
wr32 (IGC_TSSDP , 0x0 );
892
1049
wr32 (IGC_TSIM ,
893
1050
IGC_TSICR_INTERRUPTS |
894
1051
(adapter -> pps_sys_wrap_on ? IGC_TSICR_SYS_WRAP : 0 ));
895
1052
wr32 (IGC_IMS , IGC_IMS_TS );
1053
+
1054
+ if (!igc_is_crosststamp_supported (adapter ))
1055
+ break ;
1056
+
1057
+ wr32 (IGC_PCIE_DIG_DELAY , IGC_PCIE_DIG_DELAY_DEFAULT );
1058
+ wr32 (IGC_PCIE_PHY_DELAY , IGC_PCIE_PHY_DELAY_DEFAULT );
1059
+
1060
+ cycle_ctrl = IGC_PTM_CYCLE_CTRL_CYC_TIME (IGC_PTM_CYC_TIME_DEFAULT );
1061
+
1062
+ wr32 (IGC_PTM_CYCLE_CTRL , cycle_ctrl );
1063
+
1064
+ ctrl = IGC_PTM_CTRL_EN |
1065
+ IGC_PTM_CTRL_START_NOW |
1066
+ IGC_PTM_CTRL_SHRT_CYC (IGC_PTM_SHORT_CYC_DEFAULT ) |
1067
+ IGC_PTM_CTRL_PTM_TO (IGC_PTM_TIMEOUT_DEFAULT ) |
1068
+ IGC_PTM_CTRL_TRIG ;
1069
+
1070
+ wr32 (IGC_PTM_CTRL , ctrl );
1071
+
1072
+ /* Force the first cycle to run. */
1073
+ wr32 (IGC_PTM_STAT , IGC_PTM_STAT_VALID );
1074
+
896
1075
break ;
897
1076
default :
898
1077
/* No work to do. */
0 commit comments