net/sfc: add Rx datapath method to get pushed buffers count
[dpdk.git] / drivers / net / cnxk / cnxk_ptp.c
index fc31796..449489f 100644 (file)
@@ -4,6 +4,23 @@
 
 #include "cnxk_ethdev.h"
 
+int
+cnxk_nix_read_clock(struct rte_eth_dev *eth_dev, uint64_t *clock)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+
+       /* This API returns the raw PTP HI clock value. Since LFs do not
+        * have direct access to PTP registers and it requires mbox msg
+        * to AF for this value. In fastpath reading this value for every
+        * packet (which involes mbox call) becomes very expensive, hence
+        * we should be able to derive PTP HI clock value from tsc by
+        * using freq_mult and clk_delta calculated during configure stage.
+        */
+       *clock = (rte_get_tsc_cycles() + dev->clk_delta) * dev->clk_freq_mult;
+
+       return 0;
+}
+
 /* This function calculates two parameters "clk_freq_mult" and
  * "clk_delta" which is useful in deriving PTP HI clock from
  * timestamp counter (tsc) value.
@@ -55,6 +72,107 @@ fail:
        return rc;
 }
 
+int
+cnxk_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct roc_nix *nix = &dev->nix;
+       uint64_t clock, ns;
+       int rc;
+
+       rc = roc_nix_ptp_clock_read(nix, &clock, NULL, false);
+       if (rc)
+               return rc;
+
+       ns = rte_timecounter_update(&dev->systime_tc, clock);
+       *ts = rte_ns_to_timespec(ns);
+       return 0;
+}
+
+int
+cnxk_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
+                            const struct timespec *ts)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       uint64_t ns;
+
+       ns = rte_timespec_to_ns(ts);
+       /* Set the time counters to a new value. */
+       dev->systime_tc.nsec = ns;
+       dev->rx_tstamp_tc.nsec = ns;
+       dev->tx_tstamp_tc.nsec = ns;
+
+       return 0;
+}
+
+int
+cnxk_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct roc_nix *nix = &dev->nix;
+       int rc;
+
+       /* Adjust the frequent to make tics increments in 10^9 tics per sec */
+       if (delta < ROC_NIX_PTP_FREQ_ADJUST &&
+           delta > -ROC_NIX_PTP_FREQ_ADJUST) {
+               rc = roc_nix_ptp_sync_time_adjust(nix, delta);
+               if (rc)
+                       return rc;
+
+               /* Since the frequency of PTP comp register is tuned, delta and
+                * freq mult calculation for deriving PTP_HI from timestamp
+                * counter should be done again.
+                */
+               rc = cnxk_nix_tsc_convert(dev);
+               if (rc)
+                       plt_err("Failed to calculate delta and freq mult");
+       }
+
+       dev->systime_tc.nsec += delta;
+       dev->rx_tstamp_tc.nsec += delta;
+       dev->tx_tstamp_tc.nsec += delta;
+
+       return 0;
+}
+
+int
+cnxk_nix_timesync_read_rx_timestamp(struct rte_eth_dev *eth_dev,
+                                   struct timespec *timestamp, uint32_t flags)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct cnxk_timesync_info *tstamp = &dev->tstamp;
+       uint64_t ns;
+
+       PLT_SET_USED(flags);
+
+       if (!tstamp->rx_ready)
+               return -EINVAL;
+
+       ns = rte_timecounter_update(&dev->rx_tstamp_tc, tstamp->rx_tstamp);
+       *timestamp = rte_ns_to_timespec(ns);
+       tstamp->rx_ready = 0;
+       return 0;
+}
+
+int
+cnxk_nix_timesync_read_tx_timestamp(struct rte_eth_dev *eth_dev,
+                                   struct timespec *timestamp)
+{
+       struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+       struct cnxk_timesync_info *tstamp = &dev->tstamp;
+       uint64_t ns;
+
+       if (*tstamp->tx_tstamp == 0)
+               return -EINVAL;
+
+       ns = rte_timecounter_update(&dev->tx_tstamp_tc, *tstamp->tx_tstamp);
+       *timestamp = rte_ns_to_timespec(ns);
+       *tstamp->tx_tstamp = 0;
+       rte_wmb();
+
+       return 0;
+}
+
 int
 cnxk_nix_timesync_enable(struct rte_eth_dev *eth_dev)
 {