@@ -148,6 +148,7 @@ Features
- Packet type information
- Checksum offload
- Promiscuous mode
+ - IEEE1588 PTP
DPAA Mempool Driver
~~~~~~~~~~~~~~~~~~~
@@ -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
+
@@ -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);
@@ -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;
};
@@ -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,
};
@@ -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,
@@ -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)
{