return vsc85xx_dt_led_modes_get(phydev, default_mode);
 }
 
+static void vsc85xx_remove(struct phy_device *phydev)
+{
+       struct vsc8531_private *priv = phydev->priv;
+
+       skb_queue_purge(&priv->rx_skbs_list);
+}
+
 /* Microsemi VSC85xx PHYs */
 static struct phy_driver vsc85xx_driver[] = {
 {
        .config_intr    = &vsc85xx_config_intr,
        .suspend        = &genphy_suspend,
        .resume         = &genphy_resume,
+       .remove         = &vsc85xx_remove,
        .probe          = &vsc8574_probe,
        .set_wol        = &vsc85xx_wol_set,
        .get_wol        = &vsc85xx_wol_get,
        .config_intr    = &vsc85xx_config_intr,
        .suspend        = &genphy_suspend,
        .resume         = &genphy_resume,
+       .remove         = &vsc85xx_remove,
        .probe          = &vsc8574_probe,
        .set_wol        = &vsc85xx_wol_set,
        .get_wol        = &vsc85xx_wol_get,
        .config_intr    = &vsc85xx_config_intr,
        .suspend        = &genphy_suspend,
        .resume         = &genphy_resume,
+       .remove         = &vsc85xx_remove,
        .probe          = &vsc8584_probe,
        .get_tunable    = &vsc85xx_get_tunable,
        .set_tunable    = &vsc85xx_set_tunable,
        .config_intr    = &vsc85xx_config_intr,
        .suspend        = &genphy_suspend,
        .resume         = &genphy_resume,
+       .remove         = &vsc85xx_remove,
        .probe          = &vsc8584_probe,
        .get_tunable    = &vsc85xx_get_tunable,
        .set_tunable    = &vsc85xx_set_tunable,
        .config_intr    = &vsc85xx_config_intr,
        .suspend        = &genphy_suspend,
        .resume         = &genphy_resume,
+       .remove         = &vsc85xx_remove,
        .probe          = &vsc8584_probe,
        .get_tunable    = &vsc85xx_get_tunable,
        .set_tunable    = &vsc85xx_set_tunable,
 
 {
        struct vsc8531_private *vsc8531 =
                container_of(mii_ts, struct vsc8531_private, mii_ts);
-       struct skb_shared_hwtstamps *shhwtstamps = NULL;
        struct vsc85xx_ptphdr *ptphdr;
-       struct timespec64 ts;
        unsigned long ns;
 
        if (!vsc8531->ptp->configured)
            type == PTP_CLASS_NONE)
                return false;
 
-       vsc85xx_gettime(&vsc8531->ptp->caps, &ts);
-
        ptphdr = get_ptp_header_rx(skb, vsc8531->ptp->rx_filter);
        if (!ptphdr)
                return false;
 
-       shhwtstamps = skb_hwtstamps(skb);
-       memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
-
        ns = ntohl(ptphdr->rsrvd2);
 
-       /* nsec is in reserved field */
-       if (ts.tv_nsec < ns)
-               ts.tv_sec--;
+       VSC8531_SKB_CB(skb)->ns = ns;
+       skb_queue_tail(&vsc8531->rx_skbs_list, skb);
 
-       shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ns);
-       netif_rx(skb);
+       ptp_schedule_worker(vsc8531->ptp->ptp_clock, 0);
 
        return true;
 }
 
+static long vsc85xx_do_aux_work(struct ptp_clock_info *info)
+{
+       struct vsc85xx_ptp *ptp = container_of(info, struct vsc85xx_ptp, caps);
+       struct skb_shared_hwtstamps *shhwtstamps = NULL;
+       struct phy_device *phydev = ptp->phydev;
+       struct vsc8531_private *priv = phydev->priv;
+       struct sk_buff_head received;
+       struct sk_buff *rx_skb;
+       struct timespec64 ts;
+       unsigned long flags;
+
+       __skb_queue_head_init(&received);
+       spin_lock_irqsave(&priv->rx_skbs_list.lock, flags);
+       skb_queue_splice_tail_init(&priv->rx_skbs_list, &received);
+       spin_unlock_irqrestore(&priv->rx_skbs_list.lock, flags);
+
+       vsc85xx_gettime(info, &ts);
+       while ((rx_skb = __skb_dequeue(&received)) != NULL) {
+               shhwtstamps = skb_hwtstamps(rx_skb);
+               memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+
+               if (ts.tv_nsec < VSC8531_SKB_CB(rx_skb)->ns)
+                       ts.tv_sec--;
+
+               shhwtstamps->hwtstamp = ktime_set(ts.tv_sec,
+                                                 VSC8531_SKB_CB(rx_skb)->ns);
+               netif_rx(rx_skb);
+       }
+
+       return -1;
+}
+
 static const struct ptp_clock_info vsc85xx_clk_caps = {
        .owner          = THIS_MODULE,
        .name           = "VSC85xx timer",
        .adjfine        = &vsc85xx_adjfine,
        .gettime64      = &vsc85xx_gettime,
        .settime64      = &vsc85xx_settime,
+       .do_aux_work    = &vsc85xx_do_aux_work,
 };
 
 static struct vsc8531_private *vsc8584_base_priv(struct phy_device *phydev)
 
        mutex_init(&vsc8531->phc_lock);
        mutex_init(&vsc8531->ts_lock);
+       skb_queue_head_init(&vsc8531->rx_skbs_list);
 
        /* Retrieve the shared load/save GPIO. Request it as non exclusive as
         * the same GPIO can be requested by all the PHYs of the same package.