From: Vanshika Shukla <vanshika.shu...@nxp.com>

This patch adds the support for the ethdev APIs
to enable/disable and read/write/adjust IEEE1588
PTP timestamps for DPAA platform.

Signed-off-by: Vanshika Shukla <vanshika.shu...@nxp.com>
---
 doc/guides/nics/dpaa.rst          |  1 +
 doc/guides/nics/features/dpaa.ini |  1 +
 drivers/bus/dpaa/base/fman/fman.c | 15 ++++++
 drivers/bus/dpaa/include/fman.h   | 45 +++++++++++++++++
 drivers/net/dpaa/dpaa_ethdev.c    |  5 ++
 drivers/net/dpaa/dpaa_ethdev.h    | 16 +++++++
 drivers/net/dpaa/dpaa_ptp.c       | 80 ++++++++++++++++++++++++++++++-
 7 files changed, 161 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/dpaa.rst b/doc/guides/nics/dpaa.rst
index acf4daab02..ea86e6146c 100644
--- a/doc/guides/nics/dpaa.rst
+++ b/doc/guides/nics/dpaa.rst
@@ -148,6 +148,7 @@ Features
   - Packet type information
   - Checksum offload
   - Promiscuous mode
+  - IEEE1588 PTP
 
 DPAA Mempool Driver
 ~~~~~~~~~~~~~~~~~~~
diff --git a/doc/guides/nics/features/dpaa.ini 
b/doc/guides/nics/features/dpaa.ini
index 4196dd800c..4f31b61de1 100644
--- a/doc/guides/nics/features/dpaa.ini
+++ b/doc/guides/nics/features/dpaa.ini
@@ -19,6 +19,7 @@ Flow control         = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
 Packet type parsing  = Y
+Timesync             = Y
 Timestamp offload    = Y
 Basic stats          = Y
 Extended stats       = Y
diff --git a/drivers/bus/dpaa/base/fman/fman.c 
b/drivers/bus/dpaa/base/fman/fman.c
index e39bc8c252..e2b7120237 100644
--- a/drivers/bus/dpaa/base/fman/fman.c
+++ b/drivers/bus/dpaa/base/fman/fman.c
@@ -28,6 +28,7 @@ u32 fman_dealloc_bufs_mask_lo;
 
 int fman_ccsr_map_fd = -1;
 static COMPAT_LIST_HEAD(__ifs);
+void *rtc_map;
 
 /* This is the (const) global variable that callers have read-only access to.
  * Internally, we have read-write access directly to __ifs.
@@ -539,6 +540,20 @@ fman_if_init(const struct device_node *dpa_node)
                goto err;
        }
 
+       if (!rtc_map) {
+               __if->rtc_map = mmap(NULL, FMAN_IEEE_1588_SIZE,
+                               PROT_READ | PROT_WRITE, MAP_SHARED,
+                               fman_ccsr_map_fd, FMAN_IEEE_1588_OFFSET);
+               if (__if->rtc_map == MAP_FAILED) {
+                       pr_err("Can not map FMan RTC regs base\n");
+                       _errno = -EINVAL;
+                       goto err;
+               }
+               rtc_map = __if->rtc_map;
+       } else {
+               __if->rtc_map = rtc_map;
+       }
+
        /* No channel ID for MAC-less */
        assert(lenp == sizeof(*tx_channel_id));
        na = of_n_addr_cells(mac_node);
diff --git a/drivers/bus/dpaa/include/fman.h b/drivers/bus/dpaa/include/fman.h
index 09d1ddb897..e8bc913943 100644
--- a/drivers/bus/dpaa/include/fman.h
+++ b/drivers/bus/dpaa/include/fman.h
@@ -64,6 +64,12 @@
 #define GROUP_ADDRESS          0x0000010000000000LL
 #define HASH_CTRL_ADDR_MASK    0x0000003F
 
+#define FMAN_RTC_MAX_NUM_OF_ALARMS             3
+#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES    4
+#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS       3
+#define FMAN_IEEE_1588_OFFSET                  0X1AFE000
+#define FMAN_IEEE_1588_SIZE                    4096
+
 /* Pre definitions of FMAN interface and Bpool structures */
 struct __fman_if;
 struct fman_if_bpool;
@@ -307,6 +313,44 @@ struct tx_bmi_regs {
        uint32_t fmbm_trlmts;           /**< Tx Rate Limiter Scale*/
        uint32_t fmbm_trlmt;            /**< Tx Rate Limiter*/
 };
+
+/* Description FM RTC timer alarm */
+struct t_tmr_alarm {
+       uint32_t tmr_alarm_h;
+       uint32_t tmr_alarm_l;
+};
+
+/* Description FM RTC timer Ex trigger */
+struct t_tmr_ext_trigger {
+       uint32_t tmr_etts_h;
+       uint32_t tmr_etts_l;
+};
+
+struct rtc_regs {
+       uint32_t tmr_id;        /* 0x000 Module ID register */
+       uint32_t tmr_id2;       /* 0x004 Controller ID register */
+       uint32_t reserved0008[30];
+       uint32_t tmr_ctrl;      /* 0x0080 timer control register */
+       uint32_t tmr_tevent;    /* 0x0084 timer event register */
+       uint32_t tmr_temask;    /* 0x0088 timer event mask register */
+       uint32_t reserved008c[3];
+       uint32_t tmr_cnt_h;     /* 0x0098 timer counter high register */
+       uint32_t tmr_cnt_l;     /* 0x009c timer counter low register */
+       uint32_t tmr_add;       /* 0x00a0 timer drift compensation addend 
register */
+       uint32_t tmr_acc;       /* 0x00a4 timer accumulator register */
+       uint32_t tmr_prsc;      /* 0x00a8 timer prescale */
+       uint32_t reserved00ac;
+       uint32_t tmr_off_h;     /* 0x00b0 timer offset high */
+       uint32_t tmr_off_l;     /* 0x00b4 timer offset low  */
+       struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS];
+                               /* 0x00b8 timer alarm */
+       uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES];
+                               /* 0x00d0 timer fixed period interval */
+       struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
+                               /* 0x00e0 time stamp general purpose external */
+       uint32_t reserved00f0[4];
+};
+
 struct fman_port_qmi_regs {
        uint32_t fmqm_pnc;              /**< PortID n Configuration Register */
        uint32_t fmqm_pns;              /**< PortID n Status Register */
@@ -396,6 +440,7 @@ struct __fman_if {
        void *ccsr_map;
        void *bmi_map;
        void *tx_bmi_map;
+       void *rtc_map;
        void *qmi_map;
        struct list_head node;
 };
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 682cb1c77e..82d1960356 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -1673,6 +1673,11 @@ static struct eth_dev_ops dpaa_devops = {
        .rx_queue_intr_disable    = dpaa_dev_queue_intr_disable,
        .rss_hash_update          = dpaa_dev_rss_hash_update,
        .rss_hash_conf_get        = dpaa_dev_rss_hash_conf_get,
+       .timesync_enable          = dpaa_timesync_enable,
+       .timesync_disable         = dpaa_timesync_disable,
+       .timesync_read_time       = dpaa_timesync_read_time,
+       .timesync_write_time      = dpaa_timesync_write_time,
+       .timesync_adjust_time     = dpaa_timesync_adjust_time,
        .timesync_read_rx_timestamp = dpaa_timesync_read_rx_timestamp,
        .timesync_read_tx_timestamp = dpaa_timesync_read_tx_timestamp,
 };
diff --git a/drivers/net/dpaa/dpaa_ethdev.h b/drivers/net/dpaa/dpaa_ethdev.h
index bbdb0936c0..7884cc034c 100644
--- a/drivers/net/dpaa/dpaa_ethdev.h
+++ b/drivers/net/dpaa/dpaa_ethdev.h
@@ -245,6 +245,22 @@ int
 dpaa_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
                struct timespec *timestamp);
 
+int
+dpaa_timesync_enable(struct rte_eth_dev *dev);
+
+int
+dpaa_timesync_disable(struct rte_eth_dev *dev);
+
+int
+dpaa_timesync_read_time(struct rte_eth_dev *dev,
+               struct timespec *timestamp);
+
+int
+dpaa_timesync_write_time(struct rte_eth_dev *dev,
+               const struct timespec *timestamp);
+int
+dpaa_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta);
+
 int
 dpaa_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
                struct timespec *timestamp,
diff --git a/drivers/net/dpaa/dpaa_ptp.c b/drivers/net/dpaa/dpaa_ptp.c
index 2ecdda6db0..48e29e22eb 100644
--- a/drivers/net/dpaa/dpaa_ptp.c
+++ b/drivers/net/dpaa/dpaa_ptp.c
@@ -16,7 +16,82 @@
 #include <dpaa_ethdev.h>
 #include <dpaa_rxtx.h>
 
-int dpaa_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
+int
+dpaa_timesync_enable(struct rte_eth_dev *dev __rte_unused)
+{
+       return 0;
+}
+
+int
+dpaa_timesync_disable(struct rte_eth_dev *dev __rte_unused)
+{
+       return 0;
+}
+
+int
+dpaa_timesync_read_time(struct rte_eth_dev *dev,
+                                       struct timespec *timestamp)
+{
+       uint32_t *tmr_cnt_h, *tmr_cnt_l;
+       struct __fman_if *__fif;
+       struct fman_if *fif;
+       uint64_t time;
+
+       fif = dev->process_private;
+       __fif = container_of(fif, struct __fman_if, __if);
+
+       tmr_cnt_h = &((struct rtc_regs *)__fif->rtc_map)->tmr_cnt_h;
+       tmr_cnt_l = &((struct rtc_regs *)__fif->rtc_map)->tmr_cnt_l;
+
+       time = (uint64_t)in_be32(tmr_cnt_l);
+       time |= ((uint64_t)in_be32(tmr_cnt_h) << 32);
+
+       *timestamp = rte_ns_to_timespec(time);
+       return 0;
+}
+
+int
+dpaa_timesync_write_time(struct rte_eth_dev *dev,
+                                       const struct timespec *ts)
+{
+       uint32_t *tmr_cnt_h, *tmr_cnt_l;
+       struct __fman_if *__fif;
+       struct fman_if *fif;
+       uint64_t time;
+
+       fif = dev->process_private;
+       __fif = container_of(fif, struct __fman_if, __if);
+
+       tmr_cnt_h = &((struct rtc_regs *)__fif->rtc_map)->tmr_cnt_h;
+       tmr_cnt_l = &((struct rtc_regs *)__fif->rtc_map)->tmr_cnt_l;
+
+       time = rte_timespec_to_ns(ts);
+
+       out_be32(tmr_cnt_l, (uint32_t)time);
+       out_be32(tmr_cnt_h, (uint32_t)(time >> 32));
+
+       return 0;
+}
+
+int
+dpaa_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
+{
+       struct timespec ts = {0, 0}, *timestamp = &ts;
+       uint64_t ns;
+
+       dpaa_timesync_read_time(dev, timestamp);
+
+       ns = rte_timespec_to_ns(timestamp);
+       ns += delta;
+       *timestamp = rte_ns_to_timespec(ns);
+
+       dpaa_timesync_write_time(dev, timestamp);
+
+       return 0;
+}
+
+int
+dpaa_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
                                                struct timespec *timestamp)
 {
        struct dpaa_if *dpaa_intf = dev->data->dev_private;
@@ -32,7 +107,8 @@ int dpaa_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
        return 0;
 }
 
-int dpaa_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
+int
+dpaa_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
                                                struct timespec *timestamp,
                                                uint32_t flags __rte_unused)
 {
-- 
2.25.1

Reply via email to