From b94d93ca7380328d07547addfe93a5c83e48a889 Mon Sep 17 00:00:00 2001 From: Viacheslav Ovsiienko Date: Thu, 16 Jul 2020 08:23:17 +0000 Subject: [PATCH] net/mlx5: support reading device clock If send schedule feature is engaged there is the Clock Queue created, that reports reliable the current device clock counter value. The device clock counter can be read directly from the Clock Queue CQE. Signed-off-by: Viacheslav Ovsiienko Acked-by: Matan Azrad --- drivers/net/mlx5/linux/mlx5_os.c | 4 ++- drivers/net/mlx5/mlx5.h | 1 + drivers/net/mlx5/mlx5_txpp.c | 55 ++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index ea36309900..e7241d8497 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -2348,7 +2348,7 @@ const struct eth_dev_ops mlx5_os_dev_ops = { .xstats_get_names = mlx5_xstats_get_names, .fw_version_get = mlx5_fw_version_get, .dev_infos_get = mlx5_dev_infos_get, - .read_clock = mlx5_read_clock, + .read_clock = mlx5_txpp_read_clock, .dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get, .vlan_filter_set = mlx5_vlan_filter_set, .rx_queue_setup = mlx5_rx_queue_setup, @@ -2397,6 +2397,7 @@ const struct eth_dev_ops mlx5_os_dev_sec_ops = { .xstats_get_names = mlx5_xstats_get_names, .fw_version_get = mlx5_fw_version_get, .dev_infos_get = mlx5_dev_infos_get, + .read_clock = mlx5_txpp_read_clock, .rx_descriptor_status = mlx5_rx_descriptor_status, .tx_descriptor_status = mlx5_tx_descriptor_status, .rxq_info_get = mlx5_rxq_info_get, @@ -2427,6 +2428,7 @@ const struct eth_dev_ops mlx5_os_dev_ops_isolate = { .xstats_get_names = mlx5_xstats_get_names, .fw_version_get = mlx5_fw_version_get, .dev_infos_get = mlx5_dev_infos_get, + .read_clock = mlx5_txpp_read_clock, .dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get, .vlan_filter_set = mlx5_vlan_filter_set, .rx_queue_setup = mlx5_rx_queue_setup, diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 3304f0d246..15e35e8ac2 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -1010,6 +1010,7 @@ void mlx5_os_set_reg_mr_cb(mlx5_reg_mr_t *reg_mr_cb, int mlx5_txpp_start(struct rte_eth_dev *dev); void mlx5_txpp_stop(struct rte_eth_dev *dev); +int mlx5_txpp_read_clock(struct rte_eth_dev *dev, uint64_t *timestamp); void mlx5_txpp_interrupt_handler(void *cb_arg); #endif /* RTE_PMD_MLX5_H_ */ diff --git a/drivers/net/mlx5/mlx5_txpp.c b/drivers/net/mlx5/mlx5_txpp.c index 95b91278a2..ee19071bfb 100644 --- a/drivers/net/mlx5/mlx5_txpp.c +++ b/drivers/net/mlx5/mlx5_txpp.c @@ -1058,3 +1058,58 @@ mlx5_txpp_stop(struct rte_eth_dev *dev) MLX5_ASSERT(!ret); RTE_SET_USED(ret); } + +/* + * Read the current clock counter of an Ethernet device + * + * This returns the current raw clock value of an Ethernet device. It is + * a raw amount of ticks, with no given time reference. + * The value returned here is from the same clock than the one + * filling timestamp field of Rx/Tx packets when using hardware timestamp + * offload. Therefore it can be used to compute a precise conversion of + * the device clock to the real time. + * + * @param dev + * Pointer to Ethernet device structure. + * @param clock + * Pointer to the uint64_t that holds the raw clock value. + * + * @return + * - 0: Success. + * - -ENOTSUP: The function is not supported in this mode. Requires + * packet pacing module configured and started (tx_pp devarg) + */ +int +mlx5_txpp_read_clock(struct rte_eth_dev *dev, uint64_t *timestamp) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_ctx_shared *sh = priv->sh; + int ret; + + if (sh->txpp.refcnt) { + struct mlx5_txpp_wq *wq = &sh->txpp.clock_queue; + struct mlx5_cqe *cqe = (struct mlx5_cqe *)(uintptr_t)wq->cqes; + union { + rte_int128_t u128; + struct mlx5_cqe_ts cts; + } to; + uint64_t ts; + + mlx5_atomic_read_cqe((rte_int128_t *)&cqe->timestamp, &to.u128); + if (to.cts.op_own >> 4) { + DRV_LOG(DEBUG, "Clock Queue error sync lost."); + rte_atomic32_inc(&sh->txpp.err_clock_queue); + sh->txpp.sync_lost = 1; + return -EIO; + } + ts = rte_be_to_cpu_64(to.cts.timestamp); + ts = mlx5_txpp_convert_rx_ts(sh, ts); + *timestamp = ts; + return 0; + } + /* Not supported in isolated mode - kernel does not see the CQEs. */ + if (priv->isolated || rte_eal_process_type() != RTE_PROC_PRIMARY) + return -ENOTSUP; + ret = mlx5_read_clock(dev, timestamp); + return ret; +} -- 2.20.1