]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: macb: Fix PTP one step sync support
authorHarini Katakam <harini.katakam@xilinx.com>
Wed, 18 May 2022 17:07:56 +0000 (22:37 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Jun 2022 08:25:56 +0000 (10:25 +0200)
[ Upstream commit 5cebb40bc9554aafcc492431181f43c6231b0459 ]

PTP one step sync packets cannot have CSUM padding and insertion in
SW since time stamp is inserted on the fly by HW.
In addition, ptp4l version 3.0 and above report an error when skb
timestamps are reported for packets that not processed for TX TS
after transmission.
Add a helper to identify PTP one step sync and fix the above two
errors. Add a common mask for PTP header flag field "twoStepflag".
Also reset ptp OSS bit when one step is not selected.

Fixes: ab91f0a9b5f4 ("net: macb: Add hardware PTP support")
Fixes: 653e92a9175e ("net: macb: add support for padding and fcs computation")
Signed-off-by: Harini Katakam <harini.katakam@xilinx.com>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Link: https://lore.kernel.org/r/20220518170756.7752-1-harini.katakam@xilinx.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/cadence/macb_ptp.c
include/linux/ptp_classify.h

index c1100af5666b4336d65561034cd942c520ec322d..52ee4a825c255d1b2ec8f50a6f6613c3d329c0f6 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/tcp.h>
 #include <linux/iopoll.h>
 #include <linux/pm_runtime.h>
+#include <linux/ptp_classify.h>
 #include "macb.h"
 
 /* This structure is only used for MACB on SiFive FU540 devices */
@@ -1122,6 +1123,36 @@ static void macb_tx_error_task(struct work_struct *work)
        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;
@@ -1166,8 +1197,8 @@ static void macb_tx_interrupt(struct macb_queue *queue)
 
                        /* 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
@@ -1997,7 +2028,8 @@ static unsigned int macb_tx_map(struct macb *bp,
                        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
@@ -2095,7 +2127,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
 
        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) {
index fb6b27f46b153c717f6e1fd3a3c1f02a97c5c95d..9559c16078f95b974bd8d99b7ece3a82d5379b4b 100644 (file)
@@ -470,8 +470,10 @@ int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd)
        case HWTSTAMP_TX_ONESTEP_SYNC:
                if (gem_ptp_set_one_step_sync(bp, 1) != 0)
                        return -ERANGE;
-               fallthrough;
+               tx_bd_control = TSTAMP_ALL_FRAMES;
+               break;
        case HWTSTAMP_TX_ON:
+               gem_ptp_set_one_step_sync(bp, 0);
                tx_bd_control = TSTAMP_ALL_FRAMES;
                break;
        default:
index 9afd34a2d36c5c693d63707fa9a7a08c83c7a9db..b760373524febe48da4a26883fc7e8de351ccfe1 100644 (file)
@@ -43,6 +43,9 @@
 #define OFF_PTP_SOURCE_UUID    22 /* PTPv1 only */
 #define OFF_PTP_SEQUENCE_ID    30
 
+/* PTP header flag fields */
+#define PTP_FLAG_TWOSTEP       BIT(1)
+
 /* Below defines should actually be removed at some point in time. */
 #define IP6_HLEN       40
 #define UDP_HLEN       8