[v2,10/18] net/dpaa: support IEEE 1588 PTP

Message ID 20240823073240.3708320-11-hemant.agrawal@nxp.com (mailing list archive)
State Changes Requested
Delegated to: Ferruh Yigit
Headers
Series NXP DPAA ETH driver enhancement and fixes |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Hemant Agrawal Aug. 23, 2024, 7:32 a.m. UTC
From: Vanshika Shukla <vanshika.shukla@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.shukla@nxp.com>
---
 doc/guides/nics/dpaa.rst          |  1 +
 doc/guides/nics/features/dpaa.ini |  2 +
 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, 162 insertions(+), 2 deletions(-)
  

Patch

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..2c2e79dcb5 100644
--- a/doc/guides/nics/features/dpaa.ini
+++ b/doc/guides/nics/features/dpaa.ini
@@ -19,9 +19,11 @@  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
 FW version           = Y
 ARMv8                = Y
 Usage doc            = Y
+
diff --git a/drivers/bus/dpaa/base/fman/fman.c b/drivers/bus/dpaa/base/fman/fman.c
index 89786636d9..a79b0b75dd 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 857eef3d2f..109c1a4a22 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 df6df1ddf2..f9337a9468 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)
 {