@@ -573,6 +573,9 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
573573 pf = ptp_port_to_pf (ptp_port );
574574 hw = & pf -> hw ;
575575
576+ if (!tx -> init )
577+ return ;
578+
576579 /* Read the Tx ready status first */
577580 if (tx -> has_ready_bitmap ) {
578581 err = ice_get_phy_tx_tstamp_ready (hw , tx -> block , & tstamp_ready );
@@ -674,14 +677,9 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
674677 pf -> ptp .tx_hwtstamp_good += tstamp_good ;
675678}
676679
677- /**
678- * ice_ptp_tx_tstamp_owner - Process Tx timestamps for all ports on the device
679- * @pf: Board private structure
680- */
681- static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner (struct ice_pf * pf )
680+ static void ice_ptp_tx_tstamp_owner (struct ice_pf * pf )
682681{
683682 struct ice_ptp_port * port ;
684- unsigned int i ;
685683
686684 mutex_lock (& pf -> adapter -> ports .lock );
687685 list_for_each_entry (port , & pf -> adapter -> ports .ports , list_node ) {
@@ -693,49 +691,6 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf)
693691 ice_ptp_process_tx_tstamp (tx );
694692 }
695693 mutex_unlock (& pf -> adapter -> ports .lock );
696-
697- for (i = 0 ; i < ICE_GET_QUAD_NUM (pf -> hw .ptp .num_lports ); i ++ ) {
698- u64 tstamp_ready ;
699- int err ;
700-
701- /* Read the Tx ready status first */
702- err = ice_get_phy_tx_tstamp_ready (& pf -> hw , i , & tstamp_ready );
703- if (err )
704- break ;
705- else if (tstamp_ready )
706- return ICE_TX_TSTAMP_WORK_PENDING ;
707- }
708-
709- return ICE_TX_TSTAMP_WORK_DONE ;
710- }
711-
712- /**
713- * ice_ptp_tx_tstamp - Process Tx timestamps for this function.
714- * @tx: Tx tracking structure to initialize
715- *
716- * Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding incomplete
717- * Tx timestamps, or ICE_TX_TSTAMP_WORK_DONE otherwise.
718- */
719- static enum ice_tx_tstamp_work ice_ptp_tx_tstamp (struct ice_ptp_tx * tx )
720- {
721- bool more_timestamps ;
722- unsigned long flags ;
723-
724- if (!tx -> init )
725- return ICE_TX_TSTAMP_WORK_DONE ;
726-
727- /* Process the Tx timestamp tracker */
728- ice_ptp_process_tx_tstamp (tx );
729-
730- /* Check if there are outstanding Tx timestamps */
731- spin_lock_irqsave (& tx -> lock , flags );
732- more_timestamps = tx -> init && !bitmap_empty (tx -> in_use , tx -> len );
733- spin_unlock_irqrestore (& tx -> lock , flags );
734-
735- if (more_timestamps )
736- return ICE_TX_TSTAMP_WORK_PENDING ;
737-
738- return ICE_TX_TSTAMP_WORK_DONE ;
739694}
740695
741696/**
@@ -1347,9 +1302,12 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
13471302 /* Do not reconfigure E810 or E830 PHY */
13481303 return ;
13491304 case ICE_MAC_GENERIC :
1350- case ICE_MAC_GENERIC_3K_E825 :
13511305 ice_ptp_port_phy_restart (ptp_port );
13521306 return ;
1307+ case ICE_MAC_GENERIC_3K_E825 :
1308+ if (linkup )
1309+ ice_ptp_port_phy_restart (ptp_port );
1310+ return ;
13531311 default :
13541312 dev_warn (ice_pf_to_dev (pf ), "%s: Unknown PHY type\n" , __func__ );
13551313 }
@@ -2663,30 +2621,92 @@ s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb)
26632621 return idx + tx -> offset ;
26642622}
26652623
2666- /**
2667- * ice_ptp_process_ts - Process the PTP Tx timestamps
2668- * @pf: Board private structure
2669- *
2670- * Returns: ICE_TX_TSTAMP_WORK_PENDING if there are any outstanding Tx
2671- * timestamps that need processing, and ICE_TX_TSTAMP_WORK_DONE otherwise.
2672- */
2673- enum ice_tx_tstamp_work ice_ptp_process_ts (struct ice_pf * pf )
2624+ void ice_ptp_process_ts (struct ice_pf * pf )
26742625{
26752626 switch (pf -> ptp .tx_interrupt_mode ) {
26762627 case ICE_PTP_TX_INTERRUPT_NONE :
26772628 /* This device has the clock owner handle timestamps for it */
2678- return ICE_TX_TSTAMP_WORK_DONE ;
2629+ return ;
26792630 case ICE_PTP_TX_INTERRUPT_SELF :
26802631 /* This device handles its own timestamps */
2681- return ice_ptp_tx_tstamp (& pf -> ptp .port .tx );
2632+ ice_ptp_process_tx_tstamp (& pf -> ptp .port .tx );
2633+ return ;
26822634 case ICE_PTP_TX_INTERRUPT_ALL :
26832635 /* This device handles timestamps for all ports */
2684- return ice_ptp_tx_tstamp_owner (pf );
2636+ ice_ptp_tx_tstamp_owner (pf );
2637+ return ;
2638+ default :
2639+ WARN_ONCE (1 , "Unexpected Tx timestamp interrupt mode %u\n" ,
2640+ pf -> ptp .tx_interrupt_mode );
2641+ return ;
2642+ }
2643+ }
2644+
2645+ static bool ice_port_has_timestamps (struct ice_ptp_tx * tx )
2646+ {
2647+ bool more_timestamps ;
2648+
2649+ scoped_guard (spinlock_irqsave , & tx -> lock ) {
2650+ if (!tx -> init )
2651+ return false;
2652+
2653+ more_timestamps = !bitmap_empty (tx -> in_use , tx -> len );
2654+ }
2655+
2656+ return more_timestamps ;
2657+ }
2658+
2659+ static bool ice_any_port_has_timestamps (struct ice_pf * pf )
2660+ {
2661+ struct ice_ptp_port * port ;
2662+
2663+ scoped_guard (mutex , & pf -> adapter -> ports .lock ) {
2664+ list_for_each_entry (port , & pf -> adapter -> ports .ports ,
2665+ list_node ) {
2666+ struct ice_ptp_tx * tx = & port -> tx ;
2667+
2668+ if (ice_port_has_timestamps (tx ))
2669+ return true;
2670+ }
2671+ }
2672+
2673+ return false;
2674+ }
2675+
2676+ bool ice_ptp_tx_tstamps_pending (struct ice_pf * pf )
2677+ {
2678+ struct ice_hw * hw = & pf -> hw ;
2679+ unsigned int i ;
2680+
2681+ /* Check software indicator */
2682+ switch (pf -> ptp .tx_interrupt_mode ) {
2683+ case ICE_PTP_TX_INTERRUPT_NONE :
2684+ return false;
2685+ case ICE_PTP_TX_INTERRUPT_SELF :
2686+ if (ice_port_has_timestamps (& pf -> ptp .port .tx ))
2687+ return true;
2688+ break ;
2689+ case ICE_PTP_TX_INTERRUPT_ALL :
2690+ if (ice_any_port_has_timestamps (pf ))
2691+ return true;
2692+ break ;
26852693 default :
26862694 WARN_ONCE (1 , "Unexpected Tx timestamp interrupt mode %u\n" ,
26872695 pf -> ptp .tx_interrupt_mode );
2688- return ICE_TX_TSTAMP_WORK_DONE ;
2696+ break ;
2697+ }
2698+
2699+ /* Check hardware indicator */
2700+ for (i = 0 ; i < ICE_GET_QUAD_NUM (hw -> ptp .num_lports ); i ++ ) {
2701+ u64 tstamp_ready = 0 ;
2702+ int err ;
2703+
2704+ err = ice_get_phy_tx_tstamp_ready (& pf -> hw , i , & tstamp_ready );
2705+ if (err || tstamp_ready )
2706+ return true;
26892707 }
2708+
2709+ return false;
26902710}
26912711
26922712/**
@@ -2738,7 +2758,9 @@ irqreturn_t ice_ptp_ts_irq(struct ice_pf *pf)
27382758 return IRQ_WAKE_THREAD ;
27392759 case ICE_MAC_E830 :
27402760 /* E830 can read timestamps in the top half using rd32() */
2741- if (ice_ptp_process_ts (pf ) == ICE_TX_TSTAMP_WORK_PENDING ) {
2761+ ice_ptp_process_ts (pf );
2762+
2763+ if (ice_ptp_tx_tstamps_pending (pf )) {
27422764 /* Process outstanding Tx timestamps. If there
27432765 * is more work, re-arm the interrupt to trigger again.
27442766 */
@@ -2817,6 +2839,20 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
28172839 msecs_to_jiffies (err ? 10 : 500 ));
28182840}
28192841
2842+ /**
2843+ * ice_ptp_queue_work - Queue PTP periodic work for a PF
2844+ * @pf: Board private structure
2845+ *
2846+ * Helper function to queue PTP periodic work after VSI rebuild completes.
2847+ * This ensures that PTP work only runs when VSI structures are ready.
2848+ */
2849+ void ice_ptp_queue_work (struct ice_pf * pf )
2850+ {
2851+ if (test_bit (ICE_FLAG_PTP_SUPPORTED , pf -> flags ) &&
2852+ pf -> ptp .state == ICE_PTP_READY )
2853+ kthread_queue_delayed_work (pf -> ptp .kworker , & pf -> ptp .work , 0 );
2854+ }
2855+
28202856/**
28212857 * ice_ptp_prepare_rebuild_sec - Prepare second NAC for PTP reset or rebuild
28222858 * @pf: Board private structure
@@ -2835,10 +2871,15 @@ static void ice_ptp_prepare_rebuild_sec(struct ice_pf *pf, bool rebuild,
28352871 struct ice_pf * peer_pf = ptp_port_to_pf (port );
28362872
28372873 if (!ice_is_primary (& peer_pf -> hw )) {
2838- if (rebuild )
2874+ if (rebuild ) {
2875+ /* TODO: When implementing rebuild=true:
2876+ * 1. Ensure secondary PFs' VSIs are rebuilt
2877+ * 2. Call ice_ptp_queue_work(peer_pf) after VSI rebuild
2878+ */
28392879 ice_ptp_rebuild (peer_pf , reset_type );
2840- else
2880+ } else {
28412881 ice_ptp_prepare_for_reset (peer_pf , reset_type );
2882+ }
28422883 }
28432884 }
28442885}
@@ -2984,9 +3025,6 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
29843025
29853026 ptp -> state = ICE_PTP_READY ;
29863027
2987- /* Start periodic work going */
2988- kthread_queue_delayed_work (ptp -> kworker , & ptp -> work , 0 );
2989-
29903028 dev_info (ice_pf_to_dev (pf ), "PTP reset successful\n" );
29913029 return ;
29923030
@@ -3191,8 +3229,9 @@ static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf)
31913229{
31923230 switch (pf -> hw .mac_type ) {
31933231 case ICE_MAC_GENERIC :
3194- /* E822 based PHY has the clock owner process the interrupt
3195- * for all ports.
3232+ case ICE_MAC_GENERIC_3K_E825 :
3233+ /* E82x hardware has the clock owner process timestamps for
3234+ * all ports.
31963235 */
31973236 if (ice_pf_src_tmr_owned (pf ))
31983237 pf -> ptp .tx_interrupt_mode = ICE_PTP_TX_INTERRUPT_ALL ;
0 commit comments