]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
and-xgbe: remove the abstraction for hwptp
authorRaju Rangoju <Raju.Rangoju@amd.com>
Fri, 18 Jul 2025 18:56:27 +0000 (00:26 +0530)
committerJakub Kicinski <kuba@kernel.org>
Mon, 21 Jul 2025 23:40:15 +0000 (16:40 -0700)
Remove the hwptp abstraction and associated callbacks from
the struct xgbe_hw_if {}.

The callback structure was only ever assigned a single function, without
null checks. This cleanup inlines the logic and moves all the hwtstamp
realted code a separate file, improving readability and maintainance.

Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
Link: https://patch.msgid.link/20250718185628.4038779-2-Raju.Rangoju@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/amd/xgbe/Makefile
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/amd/xgbe/xgbe-hwtstamp.c [new file with mode: 0644]
drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
drivers/net/ethernet/amd/xgbe/xgbe.h

index 620785ffbd51946d82addf34f8769d7965d214a7..5b0ab6240cf23e247db62cd6adc911d140d27a0a 100644 (file)
@@ -3,7 +3,7 @@ obj-$(CONFIG_AMD_XGBE) += amd-xgbe.o
 
 amd-xgbe-objs := xgbe-main.o xgbe-drv.o xgbe-dev.o \
                 xgbe-desc.o xgbe-ethtool.o xgbe-mdio.o \
-                xgbe-ptp.o \
+                xgbe-hwtstamp.o xgbe-ptp.o \
                 xgbe-i2c.o xgbe-phy-v1.o xgbe-phy-v2.o \
                 xgbe-platform.o
 
index 9e4e79bfe6247be757d13c1b8d183fca9302a641..e5391a2eca51d088018a7a931adbd9a367aae286 100644 (file)
@@ -1558,125 +1558,6 @@ static void xgbe_rx_desc_init(struct xgbe_channel *channel)
        DBGPR("<--rx_desc_init\n");
 }
 
-static void xgbe_update_tstamp_addend(struct xgbe_prv_data *pdata,
-                                     unsigned int addend)
-{
-       unsigned int count = 10000;
-
-       /* Set the addend register value and tell the device */
-       XGMAC_IOWRITE(pdata, MAC_TSAR, addend);
-       XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSADDREG, 1);
-
-       /* Wait for addend update to complete */
-       while (--count && XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSADDREG))
-               udelay(5);
-
-       if (!count)
-               netdev_err(pdata->netdev,
-                          "timed out updating timestamp addend register\n");
-}
-
-static void xgbe_set_tstamp_time(struct xgbe_prv_data *pdata, unsigned int sec,
-                                unsigned int nsec)
-{
-       unsigned int count = 10000;
-
-       /* Set the time values and tell the device */
-       XGMAC_IOWRITE(pdata, MAC_STSUR, sec);
-       XGMAC_IOWRITE(pdata, MAC_STNUR, nsec);
-       XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSINIT, 1);
-
-       /* Wait for time update to complete */
-       while (--count && XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSINIT))
-               udelay(5);
-
-       if (!count)
-               netdev_err(pdata->netdev, "timed out initializing timestamp\n");
-}
-
-static u64 xgbe_get_tstamp_time(struct xgbe_prv_data *pdata)
-{
-       u64 nsec;
-
-       nsec = XGMAC_IOREAD(pdata, MAC_STSR);
-       nsec *= NSEC_PER_SEC;
-       nsec += XGMAC_IOREAD(pdata, MAC_STNR);
-
-       return nsec;
-}
-
-static u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata)
-{
-       unsigned int tx_snr, tx_ssr;
-       u64 nsec;
-
-       if (pdata->vdata->tx_tstamp_workaround) {
-               tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
-               tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
-       } else {
-               tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
-               tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
-       }
-
-       if (XGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS))
-               return 0;
-
-       nsec = tx_ssr;
-       nsec *= NSEC_PER_SEC;
-       nsec += tx_snr;
-
-       return nsec;
-}
-
-static void xgbe_get_rx_tstamp(struct xgbe_packet_data *packet,
-                              struct xgbe_ring_desc *rdesc)
-{
-       u64 nsec;
-
-       if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSA) &&
-           !XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSD)) {
-               nsec = le32_to_cpu(rdesc->desc1);
-               nsec <<= 32;
-               nsec |= le32_to_cpu(rdesc->desc0);
-               if (nsec != 0xffffffffffffffffULL) {
-                       packet->rx_tstamp = nsec;
-                       XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
-                                      RX_TSTAMP, 1);
-               }
-       }
-}
-
-static int xgbe_config_tstamp(struct xgbe_prv_data *pdata,
-                             unsigned int mac_tscr)
-{
-       /* Set one nano-second accuracy */
-       XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCTRLSSR, 1);
-
-       /* Set fine timestamp update */
-       XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCFUPDT, 1);
-
-       /* Overwrite earlier timestamps */
-       XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TXTSSTSM, 1);
-
-       XGMAC_IOWRITE(pdata, MAC_TSCR, mac_tscr);
-
-       /* Exit if timestamping is not enabled */
-       if (!XGMAC_GET_BITS(mac_tscr, MAC_TSCR, TSENA))
-               return 0;
-
-       /* Initialize time registers */
-       XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SSINC, XGBE_TSTAMP_SSINC);
-       XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SNSINC, XGBE_TSTAMP_SNSINC);
-       xgbe_update_tstamp_addend(pdata, pdata->tstamp_addend);
-       xgbe_set_tstamp_time(pdata, 0, 0);
-
-       /* Initialize the timecounter */
-       timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc,
-                        ktime_to_ns(ktime_get_real()));
-
-       return 0;
-}
-
 static void xgbe_tx_start_xmit(struct xgbe_channel *channel,
                               struct xgbe_ring *ring)
 {
@@ -3671,13 +3552,6 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
        hw_if->rx_mmc_int = xgbe_rx_mmc_int;
        hw_if->read_mmc_stats = xgbe_read_mmc_stats;
 
-       /* For PTP config */
-       hw_if->config_tstamp = xgbe_config_tstamp;
-       hw_if->update_tstamp_addend = xgbe_update_tstamp_addend;
-       hw_if->set_tstamp_time = xgbe_set_tstamp_time;
-       hw_if->get_tstamp_time = xgbe_get_tstamp_time;
-       hw_if->get_tx_tstamp = xgbe_get_tx_tstamp;
-
        /* For Data Center Bridging config */
        hw_if->config_tc = xgbe_config_tc;
        hw_if->config_dcb_tc = xgbe_config_dcb_tc;
index 65447f9a0a59d90babede08da8655c769891ff63..20d688a1962c1a10e58bd6a332486b00dbc26eb7 100644 (file)
@@ -448,7 +448,7 @@ static void xgbe_isr_bh_work(struct work_struct *work)
                        if (XGMAC_GET_BITS(mac_tssr, MAC_TSSR, TXTSC)) {
                                /* Read Tx Timestamp to clear interrupt */
                                pdata->tx_tstamp =
-                                       hw_if->get_tx_tstamp(pdata);
+                                       xgbe_get_tx_tstamp(pdata);
                                queue_work(pdata->dev_workqueue,
                                           &pdata->tx_tstamp_work);
                        }
@@ -1371,199 +1371,6 @@ static void xgbe_restart(struct work_struct *work)
        rtnl_unlock();
 }
 
-static void xgbe_tx_tstamp(struct work_struct *work)
-{
-       struct xgbe_prv_data *pdata = container_of(work,
-                                                  struct xgbe_prv_data,
-                                                  tx_tstamp_work);
-       struct skb_shared_hwtstamps hwtstamps;
-       u64 nsec;
-       unsigned long flags;
-
-       spin_lock_irqsave(&pdata->tstamp_lock, flags);
-       if (!pdata->tx_tstamp_skb)
-               goto unlock;
-
-       if (pdata->tx_tstamp) {
-               nsec = timecounter_cyc2time(&pdata->tstamp_tc,
-                                           pdata->tx_tstamp);
-
-               memset(&hwtstamps, 0, sizeof(hwtstamps));
-               hwtstamps.hwtstamp = ns_to_ktime(nsec);
-               skb_tstamp_tx(pdata->tx_tstamp_skb, &hwtstamps);
-       }
-
-       dev_kfree_skb_any(pdata->tx_tstamp_skb);
-
-       pdata->tx_tstamp_skb = NULL;
-
-unlock:
-       spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
-}
-
-static int xgbe_get_hwtstamp_settings(struct xgbe_prv_data *pdata,
-                                     struct ifreq *ifreq)
-{
-       if (copy_to_user(ifreq->ifr_data, &pdata->tstamp_config,
-                        sizeof(pdata->tstamp_config)))
-               return -EFAULT;
-
-       return 0;
-}
-
-static int xgbe_set_hwtstamp_settings(struct xgbe_prv_data *pdata,
-                                     struct ifreq *ifreq)
-{
-       struct hwtstamp_config config;
-       unsigned int mac_tscr;
-
-       if (copy_from_user(&config, ifreq->ifr_data, sizeof(config)))
-               return -EFAULT;
-
-       mac_tscr = 0;
-
-       switch (config.tx_type) {
-       case HWTSTAMP_TX_OFF:
-               break;
-
-       case HWTSTAMP_TX_ON:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       default:
-               return -ERANGE;
-       }
-
-       switch (config.rx_filter) {
-       case HWTSTAMP_FILTER_NONE:
-               break;
-
-       case HWTSTAMP_FILTER_NTP_ALL:
-       case HWTSTAMP_FILTER_ALL:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENALL, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       /* PTP v2, UDP, any kind of event packet */
-       case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-               fallthrough;    /* to PTP v1, UDP, any kind of event packet */
-       case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       /* PTP v2, UDP, Sync packet */
-       case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-               fallthrough;    /* to PTP v1, UDP, Sync packet */
-       case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       /* PTP v2, UDP, Delay_req packet */
-       case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-               fallthrough;    /* to PTP v1, UDP, Delay_req packet */
-       case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       /* 802.AS1, Ethernet, any kind of event packet */
-       case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       /* 802.AS1, Ethernet, Sync packet */
-       case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       /* 802.AS1, Ethernet, Delay_req packet */
-       case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       /* PTP v2/802.AS1, any layer, any kind of event packet */
-       case HWTSTAMP_FILTER_PTP_V2_EVENT:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       /* PTP v2/802.AS1, any layer, Sync packet */
-       case HWTSTAMP_FILTER_PTP_V2_SYNC:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       /* PTP v2/802.AS1, any layer, Delay_req packet */
-       case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
-               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
-               break;
-
-       default:
-               return -ERANGE;
-       }
-
-       pdata->hw_if.config_tstamp(pdata, mac_tscr);
-
-       memcpy(&pdata->tstamp_config, &config, sizeof(config));
-
-       return 0;
-}
-
-static void xgbe_prep_tx_tstamp(struct xgbe_prv_data *pdata,
-                               struct sk_buff *skb,
-                               struct xgbe_packet_data *packet)
-{
-       unsigned long flags;
-
-       if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP)) {
-               spin_lock_irqsave(&pdata->tstamp_lock, flags);
-               if (pdata->tx_tstamp_skb) {
-                       /* Another timestamp in progress, ignore this one */
-                       XGMAC_SET_BITS(packet->attributes,
-                                      TX_PACKET_ATTRIBUTES, PTP, 0);
-               } else {
-                       pdata->tx_tstamp_skb = skb_get(skb);
-                       skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
-               }
-               spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
-       }
-
-       skb_tx_timestamp(skb);
-}
-
 static void xgbe_prep_vlan(struct sk_buff *skb, struct xgbe_packet_data *packet)
 {
        if (skb_vlan_tag_present(skb))
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-hwtstamp.c b/drivers/net/ethernet/amd/xgbe/xgbe-hwtstamp.c
new file mode 100644 (file)
index 0000000..3ee641a
--- /dev/null
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
+/*
+ * Copyright (c) 2014-2025, Advanced Micro Devices, Inc.
+ * Copyright (c) 2014, Synopsys, Inc.
+ * All rights reserved
+ *
+ * Author: Raju Rangoju <Raju.Rangoju@amd.com>
+ */
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+void xgbe_update_tstamp_addend(struct xgbe_prv_data *pdata,
+                              unsigned int addend)
+{
+       unsigned int count = 10000;
+
+       /* Set the addend register value and tell the device */
+       XGMAC_IOWRITE(pdata, MAC_TSAR, addend);
+       XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSADDREG, 1);
+
+       /* Wait for addend update to complete */
+       while (--count && XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSADDREG))
+               udelay(5);
+
+       if (!count)
+               netdev_err(pdata->netdev,
+                          "timed out updating timestamp addend register\n");
+}
+
+void xgbe_set_tstamp_time(struct xgbe_prv_data *pdata, unsigned int sec,
+                         unsigned int nsec)
+{
+       unsigned int count = 10000;
+
+       /* Set the time values and tell the device */
+       XGMAC_IOWRITE(pdata, MAC_STSUR, sec);
+       XGMAC_IOWRITE(pdata, MAC_STNUR, nsec);
+       XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSINIT, 1);
+
+       /* Wait for time update to complete */
+       while (--count && XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSINIT))
+               udelay(5);
+
+       if (!count)
+               netdev_err(pdata->netdev, "timed out initializing timestamp\n");
+}
+
+u64 xgbe_get_tstamp_time(struct xgbe_prv_data *pdata)
+{
+       u64 nsec;
+
+       nsec = XGMAC_IOREAD(pdata, MAC_STSR);
+       nsec *= NSEC_PER_SEC;
+       nsec += XGMAC_IOREAD(pdata, MAC_STNR);
+
+       return nsec;
+}
+
+u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata)
+{
+       unsigned int tx_snr, tx_ssr;
+       u64 nsec;
+
+       if (pdata->vdata->tx_tstamp_workaround) {
+               tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
+               tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
+       } else {
+               tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
+               tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
+       }
+
+       if (XGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS))
+               return 0;
+
+       nsec = tx_ssr;
+       nsec *= NSEC_PER_SEC;
+       nsec += tx_snr;
+
+       return nsec;
+}
+
+void xgbe_get_rx_tstamp(struct xgbe_packet_data *packet,
+                       struct xgbe_ring_desc *rdesc)
+{
+       u64 nsec;
+
+       if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSA) &&
+           !XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSD)) {
+               nsec = le32_to_cpu(rdesc->desc1);
+               nsec <<= 32;
+               nsec |= le32_to_cpu(rdesc->desc0);
+               if (nsec != 0xffffffffffffffffULL) {
+                       packet->rx_tstamp = nsec;
+                       XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+                                      RX_TSTAMP, 1);
+               }
+       }
+}
+
+int xgbe_config_tstamp(struct xgbe_prv_data *pdata, unsigned int mac_tscr)
+{
+       /* Set one nano-second accuracy */
+       XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCTRLSSR, 1);
+
+       /* Set fine timestamp update */
+       XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCFUPDT, 1);
+
+       /* Overwrite earlier timestamps */
+       XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TXTSSTSM, 1);
+
+       XGMAC_IOWRITE(pdata, MAC_TSCR, mac_tscr);
+
+       /* Exit if timestamping is not enabled */
+       if (!XGMAC_GET_BITS(mac_tscr, MAC_TSCR, TSENA))
+               return 0;
+
+       /* Initialize time registers */
+       XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SSINC, XGBE_TSTAMP_SSINC);
+       XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SNSINC, XGBE_TSTAMP_SNSINC);
+       xgbe_update_tstamp_addend(pdata, pdata->tstamp_addend);
+       xgbe_set_tstamp_time(pdata, 0, 0);
+
+       /* Initialize the timecounter */
+       timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc,
+                        ktime_to_ns(ktime_get_real()));
+
+       return 0;
+}
+
+void xgbe_tx_tstamp(struct work_struct *work)
+{
+       struct xgbe_prv_data *pdata = container_of(work,
+                                                  struct xgbe_prv_data,
+                                                  tx_tstamp_work);
+       struct skb_shared_hwtstamps hwtstamps;
+       unsigned long flags;
+       u64 nsec;
+
+       spin_lock_irqsave(&pdata->tstamp_lock, flags);
+       if (!pdata->tx_tstamp_skb)
+               goto unlock;
+
+       if (pdata->tx_tstamp) {
+               nsec = timecounter_cyc2time(&pdata->tstamp_tc,
+                                           pdata->tx_tstamp);
+
+               memset(&hwtstamps, 0, sizeof(hwtstamps));
+               hwtstamps.hwtstamp = ns_to_ktime(nsec);
+               skb_tstamp_tx(pdata->tx_tstamp_skb, &hwtstamps);
+       }
+
+       dev_kfree_skb_any(pdata->tx_tstamp_skb);
+
+       pdata->tx_tstamp_skb = NULL;
+
+unlock:
+       spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
+}
+
+int xgbe_get_hwtstamp_settings(struct xgbe_prv_data *pdata, struct ifreq *ifreq)
+{
+       if (copy_to_user(ifreq->ifr_data, &pdata->tstamp_config,
+                        sizeof(pdata->tstamp_config)))
+               return -EFAULT;
+
+       return 0;
+}
+
+int xgbe_set_hwtstamp_settings(struct xgbe_prv_data *pdata, struct ifreq *ifreq)
+{
+       struct hwtstamp_config config;
+       unsigned int mac_tscr;
+
+       if (copy_from_user(&config, ifreq->ifr_data, sizeof(config)))
+               return -EFAULT;
+
+       mac_tscr = 0;
+
+       switch (config.tx_type) {
+       case HWTSTAMP_TX_OFF:
+               break;
+
+       case HWTSTAMP_TX_ON:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+       default:
+               return -ERANGE;
+       }
+
+       switch (config.rx_filter) {
+       case HWTSTAMP_FILTER_NONE:
+               break;
+
+       case HWTSTAMP_FILTER_NTP_ALL:
+       case HWTSTAMP_FILTER_ALL:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENALL, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+               /* PTP v2, UDP, any kind of event packet */
+       case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+               fallthrough;    /* to PTP v1, UDP, any kind of event packet */
+       case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+               /* PTP v2, UDP, Sync packet */
+       case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+               fallthrough;    /* to PTP v1, UDP, Sync packet */
+       case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+               /* PTP v2, UDP, Delay_req packet */
+       case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+               fallthrough;    /* to PTP v1, UDP, Delay_req packet */
+       case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+               /* 802.AS1, Ethernet, any kind of event packet */
+       case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+               /* 802.AS1, Ethernet, Sync packet */
+       case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+               /* 802.AS1, Ethernet, Delay_req packet */
+       case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+               /* PTP v2/802.AS1, any layer, any kind of event packet */
+       case HWTSTAMP_FILTER_PTP_V2_EVENT:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+               /* PTP v2/802.AS1, any layer, Sync packet */
+       case HWTSTAMP_FILTER_PTP_V2_SYNC:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+               /* PTP v2/802.AS1, any layer, Delay_req packet */
+       case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+               XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+               break;
+
+       default:
+               return -ERANGE;
+       }
+
+       xgbe_config_tstamp(pdata, mac_tscr);
+
+       memcpy(&pdata->tstamp_config, &config, sizeof(config));
+
+       return 0;
+}
+
+void xgbe_prep_tx_tstamp(struct xgbe_prv_data *pdata,
+                        struct sk_buff *skb,
+                        struct xgbe_packet_data *packet)
+{
+       unsigned long flags;
+
+       if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP)) {
+               spin_lock_irqsave(&pdata->tstamp_lock, flags);
+               if (pdata->tx_tstamp_skb) {
+                       /* Another timestamp in progress, ignore this one */
+                       XGMAC_SET_BITS(packet->attributes,
+                                      TX_PACKET_ATTRIBUTES, PTP, 0);
+               } else {
+                       pdata->tx_tstamp_skb = skb_get(skb);
+                       skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+               }
+               spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
+       }
+
+       skb_tx_timestamp(skb);
+}
index 978c4dd01fa0a505b40a8c5b4a195eb452f235e0..3b8b4de8f91f58ca3b244b22a5914ca6a6312c02 100644 (file)
@@ -20,7 +20,7 @@ static u64 xgbe_cc_read(const struct cyclecounter *cc)
                                                   tstamp_cc);
        u64 nsec;
 
-       nsec = pdata->hw_if.get_tstamp_time(pdata);
+       nsec = xgbe_get_tstamp_time(pdata);
 
        return nsec;
 }
@@ -37,7 +37,7 @@ static int xgbe_adjfine(struct ptp_clock_info *info, long scaled_ppm)
 
        spin_lock_irqsave(&pdata->tstamp_lock, flags);
 
-       pdata->hw_if.update_tstamp_addend(pdata, addend);
+       xgbe_update_tstamp_addend(pdata, addend);
 
        spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
 
index 70169ea23c7fa3a35d031ffc6fa0cd592e8ba3d0..2341c7d213a73180d3ff920179c6a1e972289861 100644 (file)
@@ -741,14 +741,6 @@ struct xgbe_hw_if {
        void (*tx_mmc_int)(struct xgbe_prv_data *);
        void (*read_mmc_stats)(struct xgbe_prv_data *);
 
-       /* For Timestamp config */
-       int (*config_tstamp)(struct xgbe_prv_data *, unsigned int);
-       void (*update_tstamp_addend)(struct xgbe_prv_data *, unsigned int);
-       void (*set_tstamp_time)(struct xgbe_prv_data *, unsigned int sec,
-                               unsigned int nsec);
-       u64 (*get_tstamp_time)(struct xgbe_prv_data *);
-       u64 (*get_tx_tstamp)(struct xgbe_prv_data *);
-
        /* For Data Center Bridging config */
        void (*config_tc)(struct xgbe_prv_data *);
        void (*config_dcb_tc)(struct xgbe_prv_data *);
@@ -1277,6 +1269,28 @@ void xgbe_init_tx_coalesce(struct xgbe_prv_data *);
 void xgbe_restart_dev(struct xgbe_prv_data *pdata);
 void xgbe_full_restart_dev(struct xgbe_prv_data *pdata);
 
+/* For Timestamp config */
+int xgbe_config_tstamp(struct xgbe_prv_data *pdata, unsigned int mac_tscr);
+u64 xgbe_get_tstamp_time(struct xgbe_prv_data *pdata);
+u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata);
+void xgbe_get_rx_tstamp(struct xgbe_packet_data *packet,
+                       struct xgbe_ring_desc *rdesc);
+void xgbe_get_rx_tstamp(struct xgbe_packet_data *packet,
+                       struct xgbe_ring_desc *rdesc);
+void xgbe_update_tstamp_addend(struct xgbe_prv_data *pdata,
+                              unsigned int addend);
+void xgbe_set_tstamp_time(struct xgbe_prv_data *pdata, unsigned int sec,
+                         unsigned int nsec);
+int xgbe_config_tstamp(struct xgbe_prv_data *pdata, unsigned int mac_tscr);
+void xgbe_tx_tstamp(struct work_struct *work);
+int xgbe_get_hwtstamp_settings(struct xgbe_prv_data *pdata,
+                              struct ifreq *ifreq);
+int xgbe_set_hwtstamp_settings(struct xgbe_prv_data *pdata,
+                              struct ifreq *ifreq);
+void xgbe_prep_tx_tstamp(struct xgbe_prv_data *pdata,
+                        struct sk_buff *skb,
+                        struct xgbe_packet_data *packet);
+
 #ifdef CONFIG_DEBUG_FS
 void xgbe_debugfs_init(struct xgbe_prv_data *);
 void xgbe_debugfs_exit(struct xgbe_prv_data *);