@@ -110,7 +110,7 @@ static void bnxt_ptp_get_current_time(struct bnxt *bp)
110
110
}
111
111
112
112
static int bnxt_hwrm_port_ts_query (struct bnxt * bp , u32 flags , u64 * ts ,
113
- u32 txts_tmo )
113
+ u32 txts_tmo , int slot )
114
114
{
115
115
struct hwrm_port_ts_query_output * resp ;
116
116
struct hwrm_port_ts_query_input * req ;
@@ -123,7 +123,7 @@ static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts,
123
123
req -> flags = cpu_to_le32 (flags );
124
124
if ((flags & PORT_TS_QUERY_REQ_FLAGS_PATH ) ==
125
125
PORT_TS_QUERY_REQ_FLAGS_PATH_TX ) {
126
- struct bnxt_ptp_tx_req * txts_req = & bp -> ptp_cfg -> txts_req ;
126
+ struct bnxt_ptp_tx_req * txts_req = & bp -> ptp_cfg -> txts_req [ slot ] ;
127
127
u32 tmo_us = txts_tmo * 1000 ;
128
128
129
129
req -> enables = cpu_to_le16 (BNXT_PTP_QTS_TX_ENABLES );
@@ -683,7 +683,7 @@ static u64 bnxt_cc_read(const struct cyclecounter *cc)
683
683
return ns ;
684
684
}
685
685
686
- static int bnxt_stamp_tx_skb (struct bnxt * bp , struct sk_buff * skb )
686
+ static int bnxt_stamp_tx_skb (struct bnxt * bp , int slot )
687
687
{
688
688
struct bnxt_ptp_cfg * ptp = bp -> ptp_cfg ;
689
689
struct skb_shared_hwtstamps timestamp ;
@@ -693,13 +693,13 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
693
693
u32 tmo = 0 ;
694
694
int rc ;
695
695
696
- txts_req = & ptp -> txts_req ;
697
- if (! txts_req -> txts_pending )
698
- txts_req -> abs_txts_tmo = now + msecs_to_jiffies ( ptp -> txts_tmo );
696
+ txts_req = & ptp -> txts_req [ slot ] ;
697
+ /* make sure bnxt_get_tx_ts_p5() has updated abs_txts_tmo */
698
+ smp_rmb ( );
699
699
if (!time_after_eq (now , txts_req -> abs_txts_tmo ))
700
700
tmo = jiffies_to_msecs (txts_req -> abs_txts_tmo - now );
701
701
rc = bnxt_hwrm_port_ts_query (bp , PORT_TS_QUERY_REQ_FLAGS_PATH_TX , & ts ,
702
- tmo );
702
+ tmo , slot );
703
703
if (!rc ) {
704
704
memset (& timestamp , 0 , sizeof (timestamp ));
705
705
spin_lock_bh (& ptp -> ptp_lock );
@@ -709,19 +709,16 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, struct sk_buff *skb)
709
709
skb_tstamp_tx (txts_req -> tx_skb , & timestamp );
710
710
ptp -> stats .ts_pkts ++ ;
711
711
} else {
712
- if (!time_after_eq (jiffies , txts_req -> abs_txts_tmo )) {
713
- txts_req -> txts_pending = true;
712
+ if (!time_after_eq (jiffies , txts_req -> abs_txts_tmo ))
714
713
return - EAGAIN ;
715
- }
714
+
716
715
ptp -> stats .ts_lost ++ ;
717
716
netdev_warn_once (bp -> dev ,
718
717
"TS query for TX timer failed rc = %x\n" , rc );
719
718
}
720
719
721
720
dev_kfree_skb_any (txts_req -> tx_skb );
722
721
txts_req -> tx_skb = NULL ;
723
- atomic_inc (& ptp -> tx_avail );
724
- txts_req -> txts_pending = false;
725
722
726
723
return 0 ;
727
724
}
@@ -732,10 +729,24 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
732
729
ptp_info );
733
730
unsigned long now = jiffies ;
734
731
struct bnxt * bp = ptp -> bp ;
732
+ u16 cons = ptp -> txts_cons ;
733
+ u8 num_requests ;
735
734
int rc = 0 ;
736
735
737
- if (ptp -> txts_req .tx_skb )
738
- rc = bnxt_stamp_tx_skb (bp , ptp -> txts_req .tx_skb );
736
+ num_requests = BNXT_MAX_TX_TS - atomic_read (& ptp -> tx_avail );
737
+ while (num_requests -- ) {
738
+ if (IS_ERR (ptp -> txts_req [cons ].tx_skb ))
739
+ goto next_slot ;
740
+ if (!ptp -> txts_req [cons ].tx_skb )
741
+ break ;
742
+ rc = bnxt_stamp_tx_skb (bp , cons );
743
+ if (rc == - EAGAIN )
744
+ break ;
745
+ next_slot :
746
+ atomic_inc (& ptp -> tx_avail );
747
+ cons = NEXT_TXTS (cons );
748
+ }
749
+ ptp -> txts_cons = cons ;
739
750
740
751
if (!time_after_eq (now , ptp -> next_period )) {
741
752
if (rc == - EAGAIN )
@@ -756,11 +767,16 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info)
756
767
return HZ ;
757
768
}
758
769
759
- void bnxt_get_tx_ts_p5 (struct bnxt * bp , struct sk_buff * skb )
770
+ void bnxt_get_tx_ts_p5 (struct bnxt * bp , struct sk_buff * skb , u16 prod )
760
771
{
761
772
struct bnxt_ptp_cfg * ptp = bp -> ptp_cfg ;
773
+ struct bnxt_ptp_tx_req * txts_req ;
762
774
763
- ptp -> txts_req .tx_skb = skb ;
775
+ txts_req = & ptp -> txts_req [prod ];
776
+ txts_req -> abs_txts_tmo = jiffies + msecs_to_jiffies (ptp -> txts_tmo );
777
+ /* make sure abs_txts_tmo is written first */
778
+ smp_wmb ();
779
+ txts_req -> tx_skb = skb ;
764
780
ptp_schedule_worker (ptp -> ptp_clock , 0 );
765
781
}
766
782
@@ -958,7 +974,7 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
958
974
return rc ;
959
975
} else {
960
976
rc = bnxt_hwrm_port_ts_query (bp , PORT_TS_QUERY_REQ_FLAGS_CURRENT_TIME ,
961
- & ns , 0 );
977
+ & ns , 0 , 0 );
962
978
if (rc )
963
979
return rc ;
964
980
}
@@ -1000,6 +1016,7 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
1000
1016
1001
1017
atomic_set (& ptp -> tx_avail , BNXT_MAX_TX_TS );
1002
1018
spin_lock_init (& ptp -> ptp_lock );
1019
+ spin_lock_init (& ptp -> ptp_tx_lock );
1003
1020
1004
1021
if (BNXT_PTP_USE_RTC (bp )) {
1005
1022
bnxt_ptp_timecounter_init (bp , false);
@@ -1049,6 +1066,7 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
1049
1066
void bnxt_ptp_clear (struct bnxt * bp )
1050
1067
{
1051
1068
struct bnxt_ptp_cfg * ptp = bp -> ptp_cfg ;
1069
+ int i ;
1052
1070
1053
1071
if (!ptp )
1054
1072
return ;
@@ -1060,9 +1078,11 @@ void bnxt_ptp_clear(struct bnxt *bp)
1060
1078
kfree (ptp -> ptp_info .pin_config );
1061
1079
ptp -> ptp_info .pin_config = NULL ;
1062
1080
1063
- if (ptp -> txts_req .tx_skb ) {
1064
- dev_kfree_skb_any (ptp -> txts_req .tx_skb );
1065
- ptp -> txts_req .tx_skb = NULL ;
1081
+ for (i = 0 ; i < BNXT_MAX_TX_TS ; i ++ ) {
1082
+ if (ptp -> txts_req [i ].tx_skb ) {
1083
+ dev_kfree_skb_any (ptp -> txts_req [i ].tx_skb );
1084
+ ptp -> txts_req [i ].tx_skb = NULL ;
1085
+ }
1066
1086
}
1067
1087
1068
1088
bnxt_unmap_ptp_regs (bp );
0 commit comments