net/octeontx2: add remaining PTP operations
authorHarman Kalra <hkalra@marvell.com>
Fri, 31 May 2019 08:47:15 +0000 (14:17 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 4 Jul 2019 23:52:01 +0000 (01:52 +0200)
Add remaining PTP configuration/slowpath operations.
Timesync feature is available only for PF devices.

Signed-off-by: Harman Kalra <hkalra@marvell.com>
Signed-off-by: Zyta Szpak <zyta@marvell.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
doc/guides/nics/features/octeontx2.ini
drivers/net/octeontx2/otx2_ethdev.c
drivers/net/octeontx2/otx2_ethdev.h
drivers/net/octeontx2/otx2_ptp.c

index 00feb0c..46fb00b 100644 (file)
@@ -23,6 +23,8 @@ RSS reta update      = Y
 Inner RSS            = Y
 Flow control         = Y
 Packet type parsing  = Y
+Timesync             = Y
+Timestamp offload    = Y
 Rx descriptor status = Y
 Basic stats          = Y
 Stats per queue      = Y
index 6ab8ed7..834b052 100644 (file)
@@ -47,6 +47,7 @@ nix_get_tx_offload_capa(struct otx2_eth_dev *dev)
 
 static const struct otx2_dev_ops otx2_dev_ops = {
        .link_status_update = otx2_eth_dev_link_status_update,
+       .ptp_info_update = otx2_eth_dev_ptp_info_update
 };
 
 static int
@@ -1350,6 +1351,11 @@ static const struct eth_dev_ops otx2_eth_dev_ops = {
        .flow_ctrl_set            = otx2_nix_flow_ctrl_set,
        .timesync_enable          = otx2_nix_timesync_enable,
        .timesync_disable         = otx2_nix_timesync_disable,
+       .timesync_read_rx_timestamp = otx2_nix_timesync_read_rx_timestamp,
+       .timesync_read_tx_timestamp = otx2_nix_timesync_read_tx_timestamp,
+       .timesync_adjust_time     = otx2_nix_timesync_adjust_time,
+       .timesync_read_time       = otx2_nix_timesync_read_time,
+       .timesync_write_time      = otx2_nix_timesync_write_time,
 };
 
 static inline int
index 1ca28ad..8f8d93a 100644 (file)
@@ -430,5 +430,16 @@ void otx2_nix_form_default_desc(struct otx2_eth_txq *txq);
 /* Timesync - PTP routines */
 int otx2_nix_timesync_enable(struct rte_eth_dev *eth_dev);
 int otx2_nix_timesync_disable(struct rte_eth_dev *eth_dev);
+int otx2_nix_timesync_read_rx_timestamp(struct rte_eth_dev *eth_dev,
+                                       struct timespec *timestamp,
+                                       uint32_t flags);
+int otx2_nix_timesync_read_tx_timestamp(struct rte_eth_dev *eth_dev,
+                                       struct timespec *timestamp);
+int otx2_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta);
+int otx2_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
+                                const struct timespec *ts);
+int otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev,
+                               struct timespec *ts);
+int otx2_eth_dev_ptp_info_update(struct otx2_dev *dev, bool ptp_en);
 
 #endif /* __OTX2_ETHDEV_H__ */
index 1050679..5291da2 100644 (file)
@@ -57,6 +57,23 @@ nix_ptp_config(struct rte_eth_dev *eth_dev, int en)
        return otx2_mbox_process(mbox);
 }
 
+int
+otx2_eth_dev_ptp_info_update(struct otx2_dev *dev, bool ptp_en)
+{
+       struct otx2_eth_dev *otx2_dev = (struct otx2_eth_dev *)dev;
+       struct rte_eth_dev *eth_dev = otx2_dev->eth_dev;
+       int i;
+
+       otx2_dev->ptp_en = ptp_en;
+       for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+               struct otx2_eth_rxq *rxq = eth_dev->data->rx_queues[i];
+               rxq->mbuf_initializer =
+                       otx2_nix_rxq_mbuf_setup(otx2_dev,
+                                               eth_dev->data->port_id);
+       }
+       return 0;
+}
+
 int
 otx2_nix_timesync_enable(struct rte_eth_dev *eth_dev)
 {
@@ -133,3 +150,116 @@ otx2_nix_timesync_disable(struct rte_eth_dev *eth_dev)
        }
        return rc;
 }
+
+int
+otx2_nix_timesync_read_rx_timestamp(struct rte_eth_dev *eth_dev,
+                                   struct timespec *timestamp,
+                                   uint32_t __rte_unused flags)
+{
+       struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
+       struct otx2_timesync_info *tstamp = &dev->tstamp;
+       uint64_t ns;
+
+       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;
+
+       otx2_nix_dbg("rx timestamp: %llu sec: %lu nsec %lu",
+                    (unsigned long long)tstamp->rx_tstamp, timestamp->tv_sec,
+                    timestamp->tv_nsec);
+
+       return 0;
+}
+
+int
+otx2_nix_timesync_read_tx_timestamp(struct rte_eth_dev *eth_dev,
+                                   struct timespec *timestamp)
+{
+       struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
+       struct otx2_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);
+
+       otx2_nix_dbg("tx timestamp: %llu sec: %lu nsec %lu",
+                    *(unsigned long long *)tstamp->tx_tstamp,
+                    timestamp->tv_sec, timestamp->tv_nsec);
+
+       *tstamp->tx_tstamp = 0;
+       rte_wmb();
+
+       return 0;
+}
+
+int
+otx2_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta)
+{
+       struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
+       struct otx2_mbox *mbox = dev->mbox;
+       struct ptp_req *req;
+       struct ptp_rsp *rsp;
+       int rc;
+
+       /* Adjust the frequent to make tics increments in 10^9 tics per sec */
+       if (delta < PTP_FREQ_ADJUST && delta > -PTP_FREQ_ADJUST) {
+               req = otx2_mbox_alloc_msg_ptp_op(mbox);
+               req->op = PTP_OP_ADJFINE;
+               req->scaled_ppm = delta;
+
+               rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
+               if (rc)
+                       return rc;
+       }
+       dev->systime_tc.nsec += delta;
+       dev->rx_tstamp_tc.nsec += delta;
+       dev->tx_tstamp_tc.nsec += delta;
+
+       return 0;
+}
+
+int
+otx2_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
+                            const struct timespec *ts)
+{
+       struct otx2_eth_dev *dev = otx2_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
+otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts)
+{
+       struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
+       struct otx2_mbox *mbox = dev->mbox;
+       struct ptp_req *req;
+       struct ptp_rsp *rsp;
+       uint64_t ns;
+       int rc;
+
+       req = otx2_mbox_alloc_msg_ptp_op(mbox);
+       req->op = PTP_OP_GET_CLOCK;
+       rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
+       if (rc)
+               return rc;
+
+       ns = rte_timecounter_update(&dev->systime_tc, rsp->clk);
+       *ts = rte_ns_to_timespec(ns);
+
+       otx2_nix_dbg("PTP time read: %ld.%09ld", ts->tv_sec, ts->tv_nsec);
+
+       return 0;
+}