#include <linux/iopoll.h>
 #include <linux/phy/phy.h>
 #include <linux/pm_runtime.h>
+#include <linux/ptp_classify.h>
 #include <linux/reset.h>
 #include "macb.h"
 
        spin_unlock_irqrestore(&bp->lock, flags);
 }
 
+static bool ptp_one_step_sync(struct sk_buff *skb)
+{
+       struct ptp_header *hdr;
+       unsigned int ptp_class;
+       u8 msgtype;
+
+       /* No need to parse packet if PTP TS is not involved */
+       if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)))
+               goto not_oss;
+
+       /* Identify and return whether PTP one step sync is being processed */
+       ptp_class = ptp_classify_raw(skb);
+       if (ptp_class == PTP_CLASS_NONE)
+               goto not_oss;
+
+       hdr = ptp_parse_header(skb, ptp_class);
+       if (!hdr)
+               goto not_oss;
+
+       if (hdr->flag_field[0] & PTP_FLAG_TWOSTEP)
+               goto not_oss;
+
+       msgtype = ptp_get_msgtype(hdr, ptp_class);
+       if (msgtype == PTP_MSGTYPE_SYNC)
+               return true;
+
+not_oss:
+       return false;
+}
+
 static void macb_tx_interrupt(struct macb_queue *queue)
 {
        unsigned int tail;
 
                        /* First, update TX stats if needed */
                        if (skb) {
-                               if (unlikely(skb_shinfo(skb)->tx_flags &
-                                            SKBTX_HW_TSTAMP) &&
+                               if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+                                   !ptp_one_step_sync(skb) &&
                                    gem_ptp_do_txstamp(queue, skb, desc) == 0) {
                                        /* skb now belongs to timestamp buffer
                                         * and will be removed later
                        ctrl |= MACB_BF(TX_LSO, lso_ctrl);
                        ctrl |= MACB_BF(TX_TCP_SEQ_SRC, seq_ctrl);
                        if ((bp->dev->features & NETIF_F_HW_CSUM) &&
-                           skb->ip_summed != CHECKSUM_PARTIAL && !lso_ctrl)
+                           skb->ip_summed != CHECKSUM_PARTIAL && !lso_ctrl &&
+                           !ptp_one_step_sync(skb))
                                ctrl |= MACB_BIT(TX_NOCRC);
                } else
                        /* Only set MSS/MFS on payload descriptors
 
        if (!(ndev->features & NETIF_F_HW_CSUM) ||
            !((*skb)->ip_summed != CHECKSUM_PARTIAL) ||
-           skb_shinfo(*skb)->gso_size) /* Not available for GSO */
+           skb_shinfo(*skb)->gso_size || ptp_one_step_sync(*skb))
                return 0;
 
        if (padlen <= 0) {