numam-dpdk/drivers/net/dpaa2/dpaa2_ptp.c
Priyanka Jain bc767866a3 net/dpaa2: add PTP driver
This patch adds the support for PTP driver for
DPAA2 devices.

To enable set
CONFIG_RTE_LIBRTE_IEEE1588=y in
config/defconfig_arm64-dpaa2-linuxapp-gc

Signed-off-by: Priyanka Jain <priyanka.jain@nxp.com>
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
2019-10-08 12:14:31 +02:00

182 lines
3.7 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright 2019 NXP
*/
#include <sys/queue.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <rte_ethdev.h>
#include <rte_log.h>
#include <rte_eth_ctrl.h>
#include <rte_malloc.h>
#include <rte_time.h>
#include <rte_fslmc.h>
#include <fsl_dprtc.h>
#include <fsl_dpkg.h>
#include <dpaa2_ethdev.h>
#include <dpaa2_pmd_logs.h>
struct dpaa2_dprtc_dev {
struct fsl_mc_io dprtc; /** handle to DPRTC portal object */
uint16_t token;
uint32_t dprtc_id; /*HW ID for DPRTC object */
};
static struct dpaa2_dprtc_dev *dprtc_dev;
int dpaa2_timesync_enable(struct rte_eth_dev *dev __rte_unused)
{
return 0;
}
int dpaa2_timesync_disable(struct rte_eth_dev *dev __rte_unused)
{
return 0;
}
int dpaa2_timesync_read_time(struct rte_eth_dev *dev,
struct timespec *timestamp)
{
uint64_t ns;
int ret = 0;
RTE_SET_USED(dev);
ret = dprtc_get_time(&dprtc_dev->dprtc, CMD_PRI_LOW,
dprtc_dev->token, &ns);
if (ret) {
DPAA2_PMD_ERR("dprtc_get_time failed ret: %d", ret);
return ret;
}
*timestamp = rte_ns_to_timespec(ns);
return 0;
}
int dpaa2_timesync_write_time(struct rte_eth_dev *dev,
const struct timespec *ts)
{
uint64_t ns;
int ret = 0;
RTE_SET_USED(dev);
ns = rte_timespec_to_ns(ts);
ret = dprtc_set_time(&dprtc_dev->dprtc, CMD_PRI_LOW,
dprtc_dev->token, ns);
if (ret) {
DPAA2_PMD_ERR("dprtc_set_time failed ret: %d", ret);
return ret;
}
return 0;
}
int dpaa2_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
{
uint64_t ns;
int ret = 0;
RTE_SET_USED(dev);
ret = dprtc_get_time(&dprtc_dev->dprtc, CMD_PRI_LOW,
dprtc_dev->token, &ns);
if (ret) {
DPAA2_PMD_ERR("dprtc_get_time failed ret: %d", ret);
return ret;
}
ns += delta;
ret = dprtc_set_time(&dprtc_dev->dprtc, CMD_PRI_LOW,
dprtc_dev->token, ns);
if (ret) {
DPAA2_PMD_ERR("dprtc_set_time failed ret: %d", ret);
return ret;
}
return 0;
}
int dpaa2_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
struct timespec *timestamp)
{
struct dpaa2_dev_priv *priv = dev->data->dev_private;
if (priv->next_tx_conf_queue)
dpaa2_dev_tx_conf(priv->next_tx_conf_queue);
else
return -1;
*timestamp = rte_ns_to_timespec(priv->tx_timestamp);
return 0;
}
int dpaa2_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
struct timespec *timestamp,
uint32_t flags __rte_unused)
{
struct dpaa2_dev_priv *priv = dev->data->dev_private;
*timestamp = rte_ns_to_timespec(priv->rx_timestamp);
return 0;
}
static int
dpaa2_create_dprtc_device(int vdev_fd __rte_unused,
struct vfio_device_info *obj_info __rte_unused,
int dprtc_id)
{
struct dprtc_attr attr;
int ret;
PMD_INIT_FUNC_TRACE();
/* Allocate DPAA2 dprtc handle */
dprtc_dev = rte_malloc(NULL, sizeof(struct dpaa2_dprtc_dev), 0);
if (!dprtc_dev) {
DPAA2_PMD_ERR("Memory allocation failed for DPRTC Device");
return -1;
}
/* Open the dprtc object */
dprtc_dev->dprtc.regs = rte_mcp_ptr_list[MC_PORTAL_INDEX];
ret = dprtc_open(&dprtc_dev->dprtc, CMD_PRI_LOW, dprtc_id,
&dprtc_dev->token);
if (ret) {
DPAA2_PMD_ERR("Unable to open dprtc object: err(%d)", ret);
goto init_err;
}
ret = dprtc_get_attributes(&dprtc_dev->dprtc, CMD_PRI_LOW,
dprtc_dev->token, &attr);
if (ret) {
DPAA2_PMD_ERR("Unable to get dprtc attr: err(%d)", ret);
goto init_err;
}
dprtc_dev->dprtc_id = dprtc_id;
return 0;
init_err:
if (dprtc_dev)
rte_free(dprtc_dev);
return -1;
}
static struct rte_dpaa2_object rte_dpaa2_dprtc_obj = {
.dev_type = DPAA2_DPRTC,
.create = dpaa2_create_dprtc_device,
};
RTE_PMD_REGISTER_DPAA2_OBJECT(dprtc, rte_dpaa2_dprtc_obj);