@@ -624,19 +624,20 @@ u64 idpf_ptp_tstamp_extend_32b_to_64b(u64 cached_phc_time, u32 in_timestamp)
624
624
* time stored in the device private PTP structure as the basis for timestamp
625
625
* extension.
626
626
*/
627
- u64 idpf_ptp_extend_ts (struct idpf_adapter * adapter , u32 in_tstamp )
627
+ u64 idpf_ptp_extend_ts (struct idpf_adapter * adapter , u64 in_tstamp )
628
628
{
629
629
unsigned long discard_time ;
630
- u64 ticks ;
630
+ u32 tstamp ;
631
631
632
632
discard_time = adapter -> ptp .cached_phc_jiffies + msecs_to_jiffies (2000 );
633
633
634
634
if (time_is_before_jiffies (discard_time ))
635
635
return 0 ;
636
636
637
- ticks = idpf_ptp_tstamp_extend_32b_to_64b (adapter -> ptp .cached_phc_time ,
638
- in_tstamp );
639
- return ticks ;
637
+ tstamp = lower_32_bits (in_tstamp );
638
+
639
+ return idpf_ptp_tstamp_extend_32b_to_64b (adapter -> ptp .cached_phc_time ,
640
+ tstamp );
640
641
}
641
642
642
643
/**
@@ -654,6 +655,7 @@ s8 idpf_ptp_request_ts(struct idpf_vport *vport, struct sk_buff *skb)
654
655
{
655
656
struct idpf_ptp_tx_tstamp * ptp_tx_tstamp ;
656
657
struct list_head * head ;
658
+ unsigned long flags ;
657
659
u8 idx = -1 ;
658
660
659
661
if (!vport -> tx_tstamp_caps )
@@ -665,24 +667,102 @@ s8 idpf_ptp_request_ts(struct idpf_vport *vport, struct sk_buff *skb)
665
667
return idx ;
666
668
667
669
/* Get the index from the free latches list */
668
- mutex_lock (& vport -> tx_tstamp_caps -> lock_free );
670
+ spin_lock_irqsave (& vport -> tx_tstamp_caps -> lock_free , flags );
669
671
ptp_tx_tstamp = list_first_entry (head , struct idpf_ptp_tx_tstamp ,
670
672
list_member );
671
673
list_del (& ptp_tx_tstamp -> list_member );
672
- mutex_unlock (& vport -> tx_tstamp_caps -> lock_free );
674
+ spin_unlock_irqrestore (& vport -> tx_tstamp_caps -> lock_free , flags );
673
675
674
676
ptp_tx_tstamp -> skb = skb_get (skb );
675
677
skb_shinfo (skb )-> tx_flags |= SKBTX_IN_PROGRESS ;
676
678
677
679
/* Move the element to the used latches list */
678
- mutex_lock (& vport -> tx_tstamp_caps -> lock_in_use );
680
+ spin_lock_irqsave (& vport -> tx_tstamp_caps -> lock_in_use , flags );
679
681
list_add (& ptp_tx_tstamp -> list_member ,
680
682
& vport -> tx_tstamp_caps -> latches_in_use );
681
- mutex_unlock (& vport -> tx_tstamp_caps -> lock_in_use );
683
+ spin_unlock_irqrestore (& vport -> tx_tstamp_caps -> lock_in_use , flags );
682
684
683
685
return ptp_tx_tstamp -> idx ;
684
686
}
685
687
688
+ /**
689
+ * idpf_ptp_get_tx_tstamp - Read the Tx timestamp value
690
+ * @vport: Virtual port structure
691
+ *
692
+ * Read the Tx timestamp value directly - through BAR registers - and provide
693
+ * it back to the skb.
694
+ *
695
+ * Return: 0 on success, negative error code on failure.
696
+ */
697
+ int idpf_ptp_get_tx_tstamp (struct idpf_vport * vport )
698
+ {
699
+ struct idpf_ptp_vport_tx_tstamp_caps * tx_tstamp_caps ;
700
+ u32 tstamp_lo , tstamp_hi , offset_lo , offset_hi ;
701
+ struct skb_shared_hwtstamps shhwtstamps = {};
702
+ struct idpf_ptp_tx_tstamp * ptp_tx_tstamp ;
703
+ struct idpf_ptp_tx_tstamp_status * status ;
704
+ u64 tstamp , extended_tstamp ;
705
+ u8 tstamp_ns_lo_bit , valid ;
706
+ struct list_head * head ;
707
+ bool idx_found = false;
708
+ unsigned long flags ;
709
+ u16 i ;
710
+
711
+ tx_tstamp_caps = vport -> tx_tstamp_caps ;
712
+ head = & tx_tstamp_caps -> latches_in_use ;
713
+
714
+ /* Find a proper idx on the used-latches list */
715
+ spin_lock_irqsave (& tx_tstamp_caps -> lock_in_use , flags );
716
+ list_for_each_entry (ptp_tx_tstamp , head , list_member ) {
717
+ for (i = 0 ; i < tx_tstamp_caps -> num_entries ; i ++ ) {
718
+ status = & tx_tstamp_caps -> tx_tstamp_status [i ];
719
+ if (status -> skb == ptp_tx_tstamp -> skb &&
720
+ status -> state == IDPF_PTP_REQUEST ) {
721
+ status -> state = IDPF_PTP_READ_VALUE ;
722
+ list_del (& ptp_tx_tstamp -> list_member );
723
+ idx_found = true;
724
+ break ;
725
+ }
726
+ }
727
+
728
+ if (idx_found )
729
+ break ;
730
+ }
731
+ spin_unlock_irqrestore (& tx_tstamp_caps -> lock_in_use , flags );
732
+
733
+ if (!idx_found )
734
+ return - EACCES ;
735
+
736
+ offset_lo = ptp_tx_tstamp -> tx_latch_reg_offset_l ;
737
+ offset_hi = ptp_tx_tstamp -> tx_latch_reg_offset_h ;
738
+
739
+ tstamp_lo = readl (idpf_get_reg_addr (vport -> adapter , offset_lo ));
740
+ tstamp_hi = readl (idpf_get_reg_addr (vport -> adapter , offset_hi ));
741
+ tstamp = (u64 )tstamp_hi << 32 | tstamp_lo ;
742
+ valid = tstamp & IDPF_PTP_VALID_BIT ;
743
+
744
+ if (!valid )
745
+ return - EIO ;
746
+
747
+ /* Move tstamp value to skip ns part and the valid bit */
748
+ tstamp_ns_lo_bit = tx_tstamp_caps -> tstamp_ns_lo_bit ;
749
+ tstamp >>= tstamp_ns_lo_bit + 1 ;
750
+
751
+ extended_tstamp = idpf_ptp_extend_ts (vport -> adapter , tstamp );
752
+
753
+ shhwtstamps .hwtstamp = ns_to_ktime (extended_tstamp );
754
+ skb_tstamp_tx (ptp_tx_tstamp -> skb , & shhwtstamps );
755
+ dev_kfree_skb_any (ptp_tx_tstamp -> skb );
756
+
757
+ /* Free the latch index */
758
+ status -> state = IDPF_PTP_FREE ;
759
+ spin_lock_irqsave (& tx_tstamp_caps -> lock_free , flags );
760
+ list_add (& ptp_tx_tstamp -> list_member , & tx_tstamp_caps -> latches_free );
761
+ spin_unlock_irqrestore (& tx_tstamp_caps -> lock_free , flags );
762
+
763
+ return 0 ;
764
+ }
765
+
686
766
/**
687
767
* idpf_set_rx_tstamp - Enable or disable Rx timestamping
688
768
* @vport: Virtual port structure
@@ -694,7 +774,7 @@ static void idpf_ptp_set_rx_tstamp(struct idpf_vport *vport, bool on)
694
774
u16 i ;
695
775
696
776
access = vport -> adapter -> ptp .tx_tstamp_access ;
697
- if (access != IDPF_PTP_MAILBOX )
777
+ if (access == IDPF_PTP_NONE )
698
778
return ;
699
779
700
780
for (i = 0 ; i < vport -> dflt_grp .q_grp .num_rxq ; i ++ )
@@ -887,6 +967,7 @@ static void idpf_ptp_release_tstamp(struct idpf_adapter *adapter)
887
967
{
888
968
struct idpf_ptp_tx_tstamp * ptp_tx_tstamp , * tmp ;
889
969
struct list_head * head ;
970
+ unsigned long flags ;
890
971
int i ;
891
972
892
973
idpf_for_each_vport (adapter , i ) {
@@ -898,28 +979,28 @@ static void idpf_ptp_release_tstamp(struct idpf_adapter *adapter)
898
979
cancel_work_sync (& vport -> tstamp_task );
899
980
900
981
/* Remove list with free latches */
901
- mutex_lock (& vport -> tx_tstamp_caps -> lock_free );
982
+ spin_lock_irqsave (& vport -> tx_tstamp_caps -> lock_free , flags );
902
983
903
984
head = & vport -> tx_tstamp_caps -> latches_free ;
904
985
list_for_each_entry_safe (ptp_tx_tstamp , tmp , head , list_member ) {
905
986
list_del (& ptp_tx_tstamp -> list_member );
906
987
kfree (ptp_tx_tstamp );
907
988
}
908
989
909
- mutex_unlock (& vport -> tx_tstamp_caps -> lock_free );
910
- mutex_destroy ( & vport -> tx_tstamp_caps -> lock_free );
990
+ spin_unlock_irqrestore (& vport -> tx_tstamp_caps -> lock_free ,
991
+ flags );
911
992
912
993
/* Remove list with latches in use */
913
- mutex_lock (& vport -> tx_tstamp_caps -> lock_in_use );
994
+ spin_lock_irqsave (& vport -> tx_tstamp_caps -> lock_in_use , flags );
914
995
915
996
head = & vport -> tx_tstamp_caps -> latches_in_use ;
916
997
list_for_each_entry_safe (ptp_tx_tstamp , tmp , head , list_member ) {
917
998
list_del (& ptp_tx_tstamp -> list_member );
918
999
kfree (ptp_tx_tstamp );
919
1000
}
920
1001
921
- mutex_unlock (& vport -> tx_tstamp_caps -> lock_in_use );
922
- mutex_destroy ( & vport -> tx_tstamp_caps -> lock_in_use );
1002
+ spin_unlock_irqrestore (& vport -> tx_tstamp_caps -> lock_in_use ,
1003
+ flags );
923
1004
924
1005
kfree (vport -> tx_tstamp_caps -> tx_tstamp_status );
925
1006
kfree (vport -> tx_tstamp_caps );
0 commit comments