net/mlx5: support reading device clock
authorViacheslav Ovsiienko <viacheslavo@mellanox.com>
Thu, 16 Jul 2020 08:23:17 +0000 (08:23 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 21 Jul 2020 13:44:36 +0000 (15:44 +0200)
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 <viacheslavo@mellanox.com>
Acked-by: Matan Azrad <matan@mellanox.com>
drivers/net/mlx5/linux/mlx5_os.c
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_txpp.c

index ea36309..e7241d8 100644 (file)
@@ -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,
index 3304f0d..15e35e8 100644 (file)
@@ -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_ */
index 95b9127..ee19071 100644 (file)
@@ -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;
+}