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 | 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(-) 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) { -- 2.25.1