return -1;
 }
 
+/**
+ * wx_ptp_overflow_check - watchdog task to detect SYSTIME overflow
+ * @wx: pointer to wx struct
+ *
+ * this watchdog task periodically reads the timecounter
+ * in order to prevent missing when the system time registers wrap
+ * around. This needs to be run approximately twice a minute for the fastest
+ * overflowing hardware. We run it for all hardware since it shouldn't have a
+ * large impact.
+ */
+static void wx_ptp_overflow_check(struct wx *wx)
+{
+       bool timeout = time_is_before_jiffies(wx->last_overflow_check +
+                                             WX_OVERFLOW_PERIOD);
+       unsigned long flags;
+
+       if (timeout) {
+               /* Update the timecounter */
+               write_seqlock_irqsave(&wx->hw_tc_lock, flags);
+               timecounter_read(&wx->hw_tc);
+               write_sequnlock_irqrestore(&wx->hw_tc_lock, flags);
+
+               wx->last_overflow_check = jiffies;
+       }
+}
+
+/**
+ * wx_ptp_rx_hang - detect error case when Rx timestamp registers latched
+ * @wx: pointer to wx struct
+ *
+ * this watchdog task is scheduled to detect error case where hardware has
+ * dropped an Rx packet that was timestamped when the ring is full. The
+ * particular error is rare but leaves the device in a state unable to
+ * timestamp any future packets.
+ */
+static void wx_ptp_rx_hang(struct wx *wx)
+{
+       struct wx_ring *rx_ring;
+       unsigned long rx_event;
+       u32 tsyncrxctl;
+       int n;
+
+       tsyncrxctl = rd32(wx, WX_PSR_1588_CTL);
+
+       /* if we don't have a valid timestamp in the registers, just update the
+        * timeout counter and exit
+        */
+       if (!(tsyncrxctl & WX_PSR_1588_CTL_VALID)) {
+               wx->last_rx_ptp_check = jiffies;
+               return;
+       }
+
+       /* determine the most recent watchdog or rx_timestamp event */
+       rx_event = wx->last_rx_ptp_check;
+       for (n = 0; n < wx->num_rx_queues; n++) {
+               rx_ring = wx->rx_ring[n];
+               if (time_after(rx_ring->last_rx_timestamp, rx_event))
+                       rx_event = rx_ring->last_rx_timestamp;
+       }
+
+       /* only need to read the high RXSTMP register to clear the lock */
+       if (time_is_before_jiffies(rx_event + 5 * HZ)) {
+               rd32(wx, WX_PSR_1588_STMPH);
+               wx->last_rx_ptp_check = jiffies;
+
+               wx->rx_hwtstamp_cleared++;
+               dev_warn(&wx->pdev->dev, "clearing RX Timestamp hang");
+       }
+}
+
+/**
+ * wx_ptp_tx_hang - detect error case where Tx timestamp never finishes
+ * @wx: private network wx structure
+ */
+static void wx_ptp_tx_hang(struct wx *wx)
+{
+       bool timeout = time_is_before_jiffies(wx->ptp_tx_start +
+                                             WX_PTP_TX_TIMEOUT);
+
+       if (!wx->ptp_tx_skb)
+               return;
+
+       if (!test_bit(WX_STATE_PTP_TX_IN_PROGRESS, wx->state))
+               return;
+
+       /* If we haven't received a timestamp within the timeout, it is
+        * reasonable to assume that it will never occur, so we can unlock the
+        * timestamp bit when this occurs.
+        */
+       if (timeout) {
+               wx_ptp_clear_tx_timestamp(wx);
+               wx->tx_hwtstamp_timeouts++;
+               dev_warn(&wx->pdev->dev, "clearing Tx timestamp hang\n");
+       }
+}
+
 static long wx_ptp_do_aux_work(struct ptp_clock_info *ptp)
 {
        struct wx *wx = container_of(ptp, struct wx, ptp_caps);
 
        ts_done = wx_ptp_tx_hwtstamp_work(wx);
 
+       wx_ptp_overflow_check(wx);
+       if (unlikely(test_bit(WX_FLAG_RX_HWTSTAMP_IN_REGISTER,
+                             wx->flags)))
+               wx_ptp_rx_hang(wx);
+       wx_ptp_tx_hang(wx);
+
        return ts_done ? 1 : HZ;
 }
 
        timecounter_init(&wx->hw_tc, &wx->hw_cc,
                         ktime_to_ns(ktime_get_real()));
        write_sequnlock_irqrestore(&wx->hw_tc_lock, flags);
+
+       wx->last_overflow_check = jiffies;
+       ptp_schedule_worker(wx->ptp_clock, HZ);
 }
 EXPORT_SYMBOL(wx_ptp_reset);