@@ -79,6 +79,7 @@ static int sja1105_change_rxtstamping(struct sja1105_private *priv,
7979 priv -> tagger_data .stampable_skb = NULL ;
8080 }
8181 ptp_cancel_worker_sync (ptp_data -> clock );
82+ skb_queue_purge (& ptp_data -> skb_txtstamp_queue );
8283 skb_queue_purge (& ptp_data -> skb_rxtstamp_queue );
8384
8485 return sja1105_static_config_reload (priv , SJA1105_RX_HWTSTAMPING );
@@ -397,7 +398,7 @@ static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp)
397398
398399 * shwt = (struct skb_shared_hwtstamps ) {0 };
399400
400- ts = SJA1105_SKB_CB (skb )-> meta_tstamp ;
401+ ts = SJA1105_SKB_CB (skb )-> tstamp ;
401402 ts = sja1105_tstamp_reconstruct (ds , ticks , ts );
402403
403404 shwt -> hwtstamp = ns_to_ktime (sja1105_ticks_to_ns (ts ));
@@ -413,9 +414,7 @@ static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp)
413414 return -1 ;
414415}
415416
416- /* Called from dsa_skb_defer_rx_timestamp */
417- bool sja1105_port_rxtstamp (struct dsa_switch * ds , int port ,
418- struct sk_buff * skb , unsigned int type )
417+ bool sja1105_rxtstamp (struct dsa_switch * ds , int port , struct sk_buff * skb )
419418{
420419 struct sja1105_private * priv = ds -> priv ;
421420 struct sja1105_ptp_data * ptp_data = & priv -> ptp_data ;
@@ -431,6 +430,89 @@ bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
431430 return true;
432431}
433432
433+ bool sja1110_rxtstamp (struct dsa_switch * ds , int port , struct sk_buff * skb )
434+ {
435+ struct skb_shared_hwtstamps * shwt = skb_hwtstamps (skb );
436+ u64 ts = SJA1105_SKB_CB (skb )-> tstamp ;
437+
438+ * shwt = (struct skb_shared_hwtstamps ) {0 };
439+
440+ shwt -> hwtstamp = ns_to_ktime (sja1105_ticks_to_ns (ts ));
441+
442+ /* Don't defer */
443+ return false;
444+ }
445+
446+ /* Called from dsa_skb_defer_rx_timestamp */
447+ bool sja1105_port_rxtstamp (struct dsa_switch * ds , int port ,
448+ struct sk_buff * skb , unsigned int type )
449+ {
450+ struct sja1105_private * priv = ds -> priv ;
451+
452+ return priv -> info -> rxtstamp (ds , port , skb );
453+ }
454+
455+ void sja1110_process_meta_tstamp (struct dsa_switch * ds , int port , u8 ts_id ,
456+ enum sja1110_meta_tstamp dir , u64 tstamp )
457+ {
458+ struct sja1105_private * priv = ds -> priv ;
459+ struct sja1105_ptp_data * ptp_data = & priv -> ptp_data ;
460+ struct sk_buff * skb , * skb_tmp , * skb_match = NULL ;
461+ struct skb_shared_hwtstamps shwt = {0 };
462+
463+ /* We don't care about RX timestamps on the CPU port */
464+ if (dir == SJA1110_META_TSTAMP_RX )
465+ return ;
466+
467+ spin_lock (& ptp_data -> skb_txtstamp_queue .lock );
468+
469+ skb_queue_walk_safe (& ptp_data -> skb_txtstamp_queue , skb , skb_tmp ) {
470+ if (SJA1105_SKB_CB (skb )-> ts_id != ts_id )
471+ continue ;
472+
473+ __skb_unlink (skb , & ptp_data -> skb_txtstamp_queue );
474+ skb_match = skb ;
475+
476+ break ;
477+ }
478+
479+ spin_unlock (& ptp_data -> skb_txtstamp_queue .lock );
480+
481+ if (WARN_ON (!skb_match ))
482+ return ;
483+
484+ shwt .hwtstamp = ns_to_ktime (sja1105_ticks_to_ns (tstamp ));
485+ skb_complete_tx_timestamp (skb_match , & shwt );
486+ }
487+ EXPORT_SYMBOL_GPL (sja1110_process_meta_tstamp );
488+
489+ /* In addition to cloning the skb which is done by the common
490+ * sja1105_port_txtstamp, we need to generate a timestamp ID and save the
491+ * packet to the TX timestamping queue.
492+ */
493+ void sja1110_txtstamp (struct dsa_switch * ds , int port , struct sk_buff * skb )
494+ {
495+ struct sk_buff * clone = SJA1105_SKB_CB (skb )-> clone ;
496+ struct sja1105_private * priv = ds -> priv ;
497+ struct sja1105_ptp_data * ptp_data = & priv -> ptp_data ;
498+ struct sja1105_port * sp = & priv -> ports [port ];
499+ u8 ts_id ;
500+
501+ skb_shinfo (skb )-> tx_flags |= SKBTX_IN_PROGRESS ;
502+
503+ spin_lock (& sp -> data -> meta_lock );
504+
505+ ts_id = sp -> data -> ts_id ;
506+ /* Deal automatically with 8-bit wraparound */
507+ sp -> data -> ts_id ++ ;
508+
509+ SJA1105_SKB_CB (clone )-> ts_id = ts_id ;
510+
511+ spin_unlock (& sp -> data -> meta_lock );
512+
513+ skb_queue_tail (& ptp_data -> skb_txtstamp_queue , clone );
514+ }
515+
434516/* Called from dsa_skb_tx_timestamp. This callback is just to clone
435517 * the skb and have it available in SJA1105_SKB_CB in the .port_deferred_xmit
436518 * callback, where we will timestamp it synchronously.
@@ -449,6 +531,9 @@ void sja1105_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
449531 return ;
450532
451533 SJA1105_SKB_CB (skb )-> clone = clone ;
534+
535+ if (priv -> info -> txtstamp )
536+ priv -> info -> txtstamp (ds , port , skb );
452537}
453538
454539static int sja1105_ptp_reset (struct dsa_switch * ds )
@@ -865,7 +950,10 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds)
865950 .n_per_out = 1 ,
866951 };
867952
953+ /* Only used on SJA1105 */
868954 skb_queue_head_init (& ptp_data -> skb_rxtstamp_queue );
955+ /* Only used on SJA1110 */
956+ skb_queue_head_init (& ptp_data -> skb_txtstamp_queue );
869957 spin_lock_init (& tagger_data -> meta_lock );
870958
871959 ptp_data -> clock = ptp_clock_register (& ptp_data -> caps , ds -> dev );
@@ -890,6 +978,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
890978
891979 del_timer_sync (& ptp_data -> extts_timer );
892980 ptp_cancel_worker_sync (ptp_data -> clock );
981+ skb_queue_purge (& ptp_data -> skb_txtstamp_queue );
893982 skb_queue_purge (& ptp_data -> skb_rxtstamp_queue );
894983 ptp_clock_unregister (ptp_data -> clock );
895984 ptp_data -> clock = NULL ;
0 commit comments