From patchwork Fri Mar 31 02:22:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simei Su X-Patchwork-Id: 125650 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4FCAA4287D; Fri, 31 Mar 2023 04:24:43 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8AD9F4161A; Fri, 31 Mar 2023 04:24:40 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id 5E48541138 for ; Fri, 31 Mar 2023 04:24:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1680229478; x=1711765478; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=gRV0Ji9iFtIndpBAW872WnV8cLuP5QUcd6PNlxtfpM0=; b=jyKxMmwoo+gMcmVKOKHWQqc+lXOgpYevFvQP/pNH4w05SZ53Hqz09tQB Zze7da7coP7yjYm9hH+i3hOTpUCkqmqmASiEN4+Nx3atdrdifkQDTduk4 aWrkrbjMR2rCoWN1L2jf9hu5X4T86r+92CU43boVG1xnThvdLodiApe2k v2+eugC+Lkv9r7ZQgSAKFg11Y/qnszTF85Cn4Qv5NhlwNuK24jWhiDg9Y QGxWIp3uJI0WKCTUF5ohyAkCnCejy3oX8wozwS8iFu93Vgwh54WD1s5Jg K8q8YCeJvef/JaDe7E0pRYCg3BRq4lGW3f0lvqAHm+J3fYBBQeFHzeBDu A==; X-IronPort-AV: E=McAfee;i="6600,9927,10665"; a="406339256" X-IronPort-AV: E=Sophos;i="5.98,306,1673942400"; d="scan'208";a="406339256" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Mar 2023 19:24:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10665"; a="678419749" X-IronPort-AV: E=Sophos;i="5.98,306,1673942400"; d="scan'208";a="678419749" Received: from unknown (HELO npg-dpdk-simeisu-cvl-119d218.sh.intel.com) ([10.67.119.208]) by orsmga007.jf.intel.com with ESMTP; 30 Mar 2023 19:24:34 -0700 From: Simei Su To: thomas@monjalon.net, ferruh.yigit@amd.com, andrew.rybchenko@oktetlabs.ru, kirill.rybalchenko@intel.com, qi.z.zhang@intel.com Cc: dev@dpdk.org, wenjun1.wu@intel.com, Simei Su Subject: [RFC 1/4] ethdev: add frequency adjustment API Date: Fri, 31 Mar 2023 10:22:55 +0800 Message-Id: <20230331022258.382085-2-simei.su@intel.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20230331022258.382085-1-simei.su@intel.com> References: <20230331022258.382085-1-simei.su@intel.com> X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch adds freq adjustment API for PTP high accuracy. Signed-off-by: Simei Su --- lib/ethdev/ethdev_driver.h | 5 +++++ lib/ethdev/ethdev_trace.h | 9 +++++++++ lib/ethdev/ethdev_trace_points.c | 3 +++ lib/ethdev/rte_ethdev.c | 18 ++++++++++++++++++ lib/ethdev/rte_ethdev.h | 19 +++++++++++++++++++ 5 files changed, 54 insertions(+) diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h index 2c9d615..b1451d2 100644 --- a/lib/ethdev/ethdev_driver.h +++ b/lib/ethdev/ethdev_driver.h @@ -633,6 +633,9 @@ typedef int (*eth_timesync_read_tx_timestamp_t)(struct rte_eth_dev *dev, /** @internal Function used to adjust the device clock. */ typedef int (*eth_timesync_adjust_time)(struct rte_eth_dev *dev, int64_t); +/** @internal Function used to adjust the clock frequency. */ +typedef int (*eth_timesync_adjust_freq)(struct rte_eth_dev *dev, int64_t); + /** @internal Function used to get time from the device clock. */ typedef int (*eth_timesync_read_time)(struct rte_eth_dev *dev, struct timespec *timestamp); @@ -1344,6 +1347,8 @@ struct eth_dev_ops { eth_timesync_read_tx_timestamp_t timesync_read_tx_timestamp; /** Adjust the device clock */ eth_timesync_adjust_time timesync_adjust_time; + /** Adjust the clock frequency */ + eth_timesync_adjust_freq timesync_adjust_freq; /** Get the device clock time */ eth_timesync_read_time timesync_read_time; /** Set the device clock time */ diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h index 3dc7d02..d92554b 100644 --- a/lib/ethdev/ethdev_trace.h +++ b/lib/ethdev/ethdev_trace.h @@ -2196,6 +2196,15 @@ RTE_TRACE_POINT_FP( rte_trace_point_emit_int(ret); ) +/* Called in loop in examples/ptpclient */ +RTE_TRACE_POINT_FP( + rte_eth_trace_timesync_adjust_freq, + RTE_TRACE_POINT_ARGS(uint16_t port_id, int64_t ppm, int ret), + rte_trace_point_emit_u16(port_id); + rte_trace_point_emit_i64(ppm); + rte_trace_point_emit_int(ret); +) + /* Called in loop in app/test-flow-perf */ RTE_TRACE_POINT_FP( rte_flow_trace_create, diff --git a/lib/ethdev/ethdev_trace_points.c b/lib/ethdev/ethdev_trace_points.c index 61010ca..c01b5d3 100644 --- a/lib/ethdev/ethdev_trace_points.c +++ b/lib/ethdev/ethdev_trace_points.c @@ -406,6 +406,9 @@ RTE_TRACE_POINT_REGISTER(rte_eth_trace_timesync_read_tx_timestamp, RTE_TRACE_POINT_REGISTER(rte_eth_trace_timesync_adjust_time, lib.ethdev.timesync_adjust_time) +RTE_TRACE_POINT_REGISTER(rte_eth_trace_timesync_adjust_freq, + lib.ethdev.timesync_adjust_freq) + RTE_TRACE_POINT_REGISTER(rte_eth_trace_timesync_read_time, lib.ethdev.timesync_read_time) diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c index 4d03255..f5934bb 100644 --- a/lib/ethdev/rte_ethdev.c +++ b/lib/ethdev/rte_ethdev.c @@ -6017,6 +6017,24 @@ rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta) } int +rte_eth_timesync_adjust_freq(uint16_t port_id, int64_t ppm) +{ + struct rte_eth_dev *dev; + int ret; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + if (*dev->dev_ops->timesync_adjust_freq == NULL) + return -ENOTSUP; + ret = eth_err(port_id, (*dev->dev_ops->timesync_adjust_freq)(dev, ppm)); + + rte_eth_trace_timesync_adjust_freq(port_id, ppm, ret); + + return ret; +} + +int rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp) { struct rte_eth_dev *dev; diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h index 99fe9e2..9737461 100644 --- a/lib/ethdev/rte_ethdev.h +++ b/lib/ethdev/rte_ethdev.h @@ -5102,6 +5102,25 @@ int rte_eth_timesync_read_tx_timestamp(uint16_t port_id, int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta); /** + * Adjust the clock increment rate on an Ethernet device. + * + * This is usually used in conjunction with other Ethdev timesync functions to + * synchronize the device time using the IEEE1588/802.1AS protocol. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param ppm + * Parts per million with 16-bit fractional field + * + * @return + * - 0: Success. + * - -ENODEV: The port ID is invalid. + * - -EIO: if device is removed. + * - -ENOTSUP: The function is not supported by the Ethernet driver. + */ +int rte_eth_timesync_adjust_freq(uint16_t port_id, int64_t ppm); + +/** * Read the time from the timesync clock on an Ethernet device. * * This is usually used in conjunction with other Ethdev timesync functions to From patchwork Fri Mar 31 02:22:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simei Su X-Patchwork-Id: 125651 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E13624287D; Fri, 31 Mar 2023 04:24:51 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0051542C54; Fri, 31 Mar 2023 04:24:42 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id 3E94D4282D for ; Fri, 31 Mar 2023 04:24:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1680229481; x=1711765481; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=cBwWlJKELDQZMZUpZzeT1vHVeLAaXFy8bC4c+RzBkGE=; b=Un0XIRXi7cTmPyu7drWFNf7oiEzQP3pgr/xwDse8cDraDDlnioehDvJk CI3xq9zGP0DcdgkR8ZwzVyt/Qi5qztvHnAsWJBPJCyyLsV+XwbF5MJ277 rQA1BwChPcZo0k2Clc8BAK8v3rj/AO78T76Nu4s34t+y0ZOuctGbeeWKn kukF2gGb+O7bY9goNBr0PnomOQtZB0N970MR+3ojRpk4O5RvSlicpJOHR 9E12Ke4ggXqtf7enHiHCwr1WIx2pl4SETPaP8AOs+WvQaS77ma+BtWy5p cVdlks2sCbheAzsB+nIh4848uj/WqKfUXHxk1x4KMiuWkMNAekCudrq5l g==; X-IronPort-AV: E=McAfee;i="6600,9927,10665"; a="406339268" X-IronPort-AV: E=Sophos;i="5.98,306,1673942400"; d="scan'208";a="406339268" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Mar 2023 19:24:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10665"; a="678419756" X-IronPort-AV: E=Sophos;i="5.98,306,1673942400"; d="scan'208";a="678419756" Received: from unknown (HELO npg-dpdk-simeisu-cvl-119d218.sh.intel.com) ([10.67.119.208]) by orsmga007.jf.intel.com with ESMTP; 30 Mar 2023 19:24:38 -0700 From: Simei Su To: thomas@monjalon.net, ferruh.yigit@amd.com, andrew.rybchenko@oktetlabs.ru, kirill.rybalchenko@intel.com, qi.z.zhang@intel.com Cc: dev@dpdk.org, wenjun1.wu@intel.com, Simei Su Subject: [RFC 2/4] net/ice: add frequency adjustment support for PTP Date: Fri, 31 Mar 2023 10:22:56 +0800 Message-Id: <20230331022258.382085-3-simei.su@intel.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20230331022258.382085-1-simei.su@intel.com> References: <20230331022258.382085-1-simei.su@intel.com> X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add ice support for new ethdev API to adjust frequency for IEEE1588 PTP. Also, this patch reworks code for converting software update to hardware update. Signed-off-by: Simei Su --- drivers/net/ice/ice_ethdev.c | 111 ++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index 9a88cf9..fa4d840 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -158,6 +158,7 @@ static int ice_timesync_read_rx_timestamp(struct rte_eth_dev *dev, static int ice_timesync_read_tx_timestamp(struct rte_eth_dev *dev, struct timespec *timestamp); static int ice_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta); +static int ice_timesync_adjust_freq(struct rte_eth_dev *dev, int64_t ppm); static int ice_timesync_read_time(struct rte_eth_dev *dev, struct timespec *timestamp); static int ice_timesync_write_time(struct rte_eth_dev *dev, @@ -274,6 +275,7 @@ static const struct eth_dev_ops ice_eth_dev_ops = { .timesync_read_rx_timestamp = ice_timesync_read_rx_timestamp, .timesync_read_tx_timestamp = ice_timesync_read_tx_timestamp, .timesync_adjust_time = ice_timesync_adjust_time, + .timesync_adjust_freq = ice_timesync_adjust_freq, .timesync_read_time = ice_timesync_read_time, .timesync_write_time = ice_timesync_write_time, .timesync_disable = ice_timesync_disable, @@ -5840,23 +5842,6 @@ ice_timesync_enable(struct rte_eth_dev *dev) } } - /* Initialize cycle counters for system time/RX/TX timestamp */ - memset(&ad->systime_tc, 0, sizeof(struct rte_timecounter)); - memset(&ad->rx_tstamp_tc, 0, sizeof(struct rte_timecounter)); - memset(&ad->tx_tstamp_tc, 0, sizeof(struct rte_timecounter)); - - ad->systime_tc.cc_mask = ICE_CYCLECOUNTER_MASK; - ad->systime_tc.cc_shift = 0; - ad->systime_tc.nsec_mask = 0; - - ad->rx_tstamp_tc.cc_mask = ICE_CYCLECOUNTER_MASK; - ad->rx_tstamp_tc.cc_shift = 0; - ad->rx_tstamp_tc.nsec_mask = 0; - - ad->tx_tstamp_tc.cc_mask = ICE_CYCLECOUNTER_MASK; - ad->tx_tstamp_tc.cc_shift = 0; - ad->tx_tstamp_tc.nsec_mask = 0; - ad->ptp_ena = 1; return 0; @@ -5871,14 +5856,13 @@ ice_timesync_read_rx_timestamp(struct rte_eth_dev *dev, ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); struct ice_rx_queue *rxq; uint32_t ts_high; - uint64_t ts_ns, ns; + uint64_t ts_ns; rxq = dev->data->rx_queues[flags]; ts_high = rxq->time_high; ts_ns = ice_tstamp_convert_32b_64b(hw, ad, 1, ts_high); - ns = rte_timecounter_update(&ad->rx_tstamp_tc, ts_ns); - *timestamp = rte_ns_to_timespec(ns); + *timestamp = rte_ns_to_timespec(ts_ns); return 0; } @@ -5891,7 +5875,7 @@ ice_timesync_read_tx_timestamp(struct rte_eth_dev *dev, struct ice_adapter *ad = ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); uint8_t lport; - uint64_t ts_ns, ns, tstamp; + uint64_t ts_ns, tstamp; const uint64_t mask = 0xFFFFFFFF; int ret; @@ -5904,8 +5888,7 @@ ice_timesync_read_tx_timestamp(struct rte_eth_dev *dev, } ts_ns = ice_tstamp_convert_32b_64b(hw, ad, 1, (tstamp >> 8) & mask); - ns = rte_timecounter_update(&ad->tx_tstamp_tc, ts_ns); - *timestamp = rte_ns_to_timespec(ns); + *timestamp = rte_ns_to_timespec(ts_ns); return 0; } @@ -5913,12 +5896,66 @@ ice_timesync_read_tx_timestamp(struct rte_eth_dev *dev, static int ice_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) { - struct ice_adapter *ad = - ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint8_t tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc; + uint32_t lo, lo2, hi; + uint64_t time, ns; + int ret; + + if (delta > INT32_MAX || delta < INT32_MIN) { + lo = ICE_READ_REG(hw, GLTSYN_TIME_L(tmr_idx)); + hi = ICE_READ_REG(hw, GLTSYN_TIME_H(tmr_idx)); + lo2 = ICE_READ_REG(hw, GLTSYN_TIME_L(tmr_idx)); + + if (lo2 < lo) { + lo = ICE_READ_REG(hw, GLTSYN_TIME_L(tmr_idx)); + hi = ICE_READ_REG(hw, GLTSYN_TIME_H(tmr_idx)); + } + + time = ((uint64_t)hi << 32) | lo; + ns = time + delta; + + return ice_ptp_init_time(hw, ns); + } + + ret = ice_ptp_adj_clock(hw, delta, true); + if (ret) + return -1; + + return 0; +} - ad->systime_tc.nsec += delta; - ad->rx_tstamp_tc.nsec += delta; - ad->tx_tstamp_tc.nsec += delta; +#define DEFAULT_INCVAL_E810 0x13b13b13bULL +static int +ice_timesync_adjust_freq(struct rte_eth_dev *dev, int64_t ppm) +{ + uint64_t freq, divisor = 1000000ULL; + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int64_t incval = DEFAULT_INCVAL_E810, diff; + int neg_adj = 0; + int ret; + + if (ppm < 0) { + neg_adj = 1; + ppm = -ppm; + } + + while ((uint64_t)ppm > UINT64_MAX / incval) { + ppm >>= 2; + divisor >>= 2; + } + + freq = (incval * (uint64_t)ppm) >> 16; + diff = freq / divisor; + + if (neg_adj) + incval -= diff; + else + incval += diff; + + ret = ice_ptp_write_incval_locked(hw, incval); + if (ret) + return -1; return 0; } @@ -5926,15 +5963,14 @@ ice_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) static int ice_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts) { - struct ice_adapter *ad = - ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); uint64_t ns; + int ret; ns = rte_timespec_to_ns(ts); - - ad->systime_tc.nsec = ns; - ad->rx_tstamp_tc.nsec = ns; - ad->tx_tstamp_tc.nsec = ns; + ret = ice_ptp_init_time(hw, ns); + if (ret) + return -1; return 0; } @@ -5943,11 +5979,9 @@ static int ice_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) { struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); - struct ice_adapter *ad = - ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); uint8_t tmr_idx = hw->func_caps.ts_func_info.tmr_index_assoc; uint32_t hi, lo, lo2; - uint64_t time, ns; + uint64_t time; lo = ICE_READ_REG(hw, GLTSYN_TIME_L(tmr_idx)); hi = ICE_READ_REG(hw, GLTSYN_TIME_H(tmr_idx)); @@ -5959,8 +5993,7 @@ ice_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) } time = ((uint64_t)hi << 32) | lo; - ns = rte_timecounter_update(&ad->systime_tc, time); - *ts = rte_ns_to_timespec(ns); + *ts = rte_ns_to_timespec(time); return 0; } From patchwork Fri Mar 31 02:22:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simei Su X-Patchwork-Id: 125652 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 694324287D; Fri, 31 Mar 2023 04:24:57 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 307D242D0D; Fri, 31 Mar 2023 04:24:46 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id 93B4042D0D for ; Fri, 31 Mar 2023 04:24:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1680229484; x=1711765484; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=dqino8eSWSEsGOIzoX4ctbN0pGtncH+1D7I77a1M40Q=; b=JzIUC1pwzoKB0E3k6KldZoh1DZC+Lot0/amwHZr3AnrkUW+mHMaPkoph pfpDFrqFSMEzhNUdSuWs2cnwur4CK/zRfSfVLq1AdV3XEWJgnIjrppqkX sRgrRSKD4anNx2SbFs5TUYd4NZgIrs1LtcqWb+h7ANcxiLxGnkCB+Urwr 3AF6ZjlKadLMXAm48fYJHqHcN6VVvKZpme7jLAvkU2/RWomCS7UO1Uuyo +/RqwcG8lEQBB9ChmLvbpau07jd3/NuYnhbWaDD5l+oMscKvPiQLcQCZw 4USiVUxi9UKcfyXwgbGZy6dxZWEnTx//mQIn8feQezuoP5vBy7Rqaf5ss A==; X-IronPort-AV: E=McAfee;i="6600,9927,10665"; a="406339285" X-IronPort-AV: E=Sophos;i="5.98,306,1673942400"; d="scan'208";a="406339285" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Mar 2023 19:24:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10665"; a="678419761" X-IronPort-AV: E=Sophos;i="5.98,306,1673942400"; d="scan'208";a="678419761" Received: from unknown (HELO npg-dpdk-simeisu-cvl-119d218.sh.intel.com) ([10.67.119.208]) by orsmga007.jf.intel.com with ESMTP; 30 Mar 2023 19:24:41 -0700 From: Simei Su To: thomas@monjalon.net, ferruh.yigit@amd.com, andrew.rybchenko@oktetlabs.ru, kirill.rybalchenko@intel.com, qi.z.zhang@intel.com Cc: dev@dpdk.org, wenjun1.wu@intel.com, Simei Su Subject: [RFC 3/4] examples/ptpclient: refine application Date: Fri, 31 Mar 2023 10:22:57 +0800 Message-Id: <20230331022258.382085-4-simei.su@intel.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20230331022258.382085-1-simei.su@intel.com> References: <20230331022258.382085-1-simei.su@intel.com> X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch reworks code to split delay request message parsing from follow up message parsing. Signed-off-by: Simei Su Signed-off-by: Wenjun Wu --- examples/ptpclient/ptpclient.c | 48 ++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/examples/ptpclient/ptpclient.c b/examples/ptpclient/ptpclient.c index cdf2da6..74a1bf5 100644 --- a/examples/ptpclient/ptpclient.c +++ b/examples/ptpclient/ptpclient.c @@ -382,21 +382,11 @@ parse_sync(struct ptpv2_data_slave_ordinary *ptp_data, uint16_t rx_tstamp_idx) static void parse_fup(struct ptpv2_data_slave_ordinary *ptp_data) { - struct rte_ether_hdr *eth_hdr; - struct rte_ether_addr eth_addr; struct ptp_header *ptp_hdr; - struct clock_id *client_clkid; struct ptp_message *ptp_msg; - struct delay_req_msg *req_msg; - struct rte_mbuf *created_pkt; struct tstamp *origin_tstamp; - struct rte_ether_addr eth_multicast = ether_multicast; - size_t pkt_size; - int wait_us; struct rte_mbuf *m = ptp_data->m; - int ret; - eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); ptp_hdr = (struct ptp_header *)(rte_pktmbuf_mtod(m, char *) + sizeof(struct rte_ether_hdr)); if (memcmp(&ptp_data->master_clock_id, @@ -413,6 +403,26 @@ parse_fup(struct ptpv2_data_slave_ordinary *ptp_data) ptp_data->tstamp1.tv_sec = ((uint64_t)ntohl(origin_tstamp->sec_lsb)) | (((uint64_t)ntohs(origin_tstamp->sec_msb)) << 32); +} + +static void +send_delay_request(struct ptpv2_data_slave_ordinary *ptp_data) +{ + struct rte_ether_hdr *eth_hdr; + struct rte_ether_addr eth_addr; + struct ptp_header *ptp_hdr; + struct clock_id *client_clkid; + struct delay_req_msg *req_msg; + struct rte_mbuf *created_pkt; + struct rte_ether_addr eth_multicast = ether_multicast; + size_t pkt_size; + int wait_us; + struct rte_mbuf *m = ptp_data->m; + int ret; + + eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); + ptp_hdr = (struct ptp_header *)(rte_pktmbuf_mtod(m, char *) + + sizeof(struct rte_ether_hdr)); if (ptp_data->seqID_FOLLOWUP == ptp_data->seqID_SYNC) { ret = rte_eth_macaddr_get(ptp_data->portid, ð_addr); @@ -550,12 +560,6 @@ parse_drsp(struct ptpv2_data_slave_ordinary *ptp_data) ((uint64_t)ntohl(rx_tstamp->sec_lsb)) | (((uint64_t)ntohs(rx_tstamp->sec_msb)) << 32); - /* Evaluate the delta for adjustment. */ - ptp_data->delta = delta_eval(ptp_data); - - rte_eth_timesync_adjust_time(ptp_data->portid, - ptp_data->delta); - ptp_data->current_ptp_port = ptp_data->portid; /* Update kernel time if enabled in app parameters. */ @@ -568,6 +572,16 @@ parse_drsp(struct ptpv2_data_slave_ordinary *ptp_data) } } +static void +ptp_adjust_time(struct ptpv2_data_slave_ordinary *ptp_data) +{ + /* Evaluate the delta for adjustment. */ + ptp_data->delta = delta_eval(ptp_data); + + rte_eth_timesync_adjust_time(ptp_data->portid, + ptp_data->delta); +} + /* This function processes PTP packets, implementing slave PTP IEEE1588 L2 * functionality. */ @@ -594,9 +608,11 @@ parse_ptp_frames(uint16_t portid, struct rte_mbuf *m) { break; case FOLLOW_UP: parse_fup(&ptp_data); + send_delay_request(&ptp_data); break; case DELAY_RESP: parse_drsp(&ptp_data); + ptp_adjust_time(&ptp_data); print_clock_info(&ptp_data); break; default: From patchwork Fri Mar 31 02:22:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simei Su X-Patchwork-Id: 125653 X-Patchwork-Delegate: andrew.rybchenko@oktetlabs.ru Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 742CE4287D; Fri, 31 Mar 2023 04:25:03 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 44B2842D17; Fri, 31 Mar 2023 04:24:50 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id 06D1E42D16 for ; Fri, 31 Mar 2023 04:24:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1680229488; x=1711765488; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=xoK8X50X8DeJj9Chic+PK2Ujql1PKOcnA8eqeXPndcg=; b=i3DgbJYYLRJaz1TkwmVMx1qLn8dqP/wLZYK+iJFcpdwtSzSLZaCEJGSU DeJ5f2HLel5feGImN6wvZM6F+XAALGIXaLBFCYMPizBFbeoVn7e3j42h0 9S6W8rnAYivf8dU5rMWIdL5nwA4wBXInmFD7Kh70O0tPR26rae8cCT1W1 lX/z8RehapsIuRqGIaiDHWvXomOxwyfLmWs0MJ/RikiGtMir4mPy1iLPZ Zu6XwCpqycUBWbsq9M5CMOnrPc2IrLXxGh1SzlNZxCxA2Ayu7hq9AyYFq HIsZiONt/bHbYXOjs36osSB1Cf7q9kK/OX/2K3V+APnAJCGiVT8XBd3Df w==; X-IronPort-AV: E=McAfee;i="6600,9927,10665"; a="406339295" X-IronPort-AV: E=Sophos;i="5.98,306,1673942400"; d="scan'208";a="406339295" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Mar 2023 19:24:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10665"; a="678419767" X-IronPort-AV: E=Sophos;i="5.98,306,1673942400"; d="scan'208";a="678419767" Received: from unknown (HELO npg-dpdk-simeisu-cvl-119d218.sh.intel.com) ([10.67.119.208]) by orsmga007.jf.intel.com with ESMTP; 30 Mar 2023 19:24:44 -0700 From: Simei Su To: thomas@monjalon.net, ferruh.yigit@amd.com, andrew.rybchenko@oktetlabs.ru, kirill.rybalchenko@intel.com, qi.z.zhang@intel.com Cc: dev@dpdk.org, wenjun1.wu@intel.com, Simei Su Subject: [RFC 4/4] examples/ptpclient: add frequency adjustment support Date: Fri, 31 Mar 2023 10:22:58 +0800 Message-Id: <20230331022258.382085-5-simei.su@intel.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20230331022258.382085-1-simei.su@intel.com> References: <20230331022258.382085-1-simei.su@intel.com> X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch adds PI servo algorithm to support frequency adjustment API for IEEE1588 PTP. For example, the command for starting ptpclient with PI algorithm is: ./build/examples/dpdk-ptpclient -a 0000:81:00.0 -c 1 -n 3 -- -T 0 -p 0x1 --controller=pi Signed-off-by: Simei Su Signed-off-by: Wenjun Wu --- examples/ptpclient/ptpclient.c | 178 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 161 insertions(+), 17 deletions(-) diff --git a/examples/ptpclient/ptpclient.c b/examples/ptpclient/ptpclient.c index 74a1bf5..3d074af 100644 --- a/examples/ptpclient/ptpclient.c +++ b/examples/ptpclient/ptpclient.c @@ -43,6 +43,28 @@ #define KERNEL_TIME_ADJUST_LIMIT 20000 #define PTP_PROTOCOL 0x88F7 +#define KP 0.7 +#define KI 0.3 + +enum servo_state { + SERVO_UNLOCKED, + SERVO_JUMP, + SERVO_LOCKED, +}; + +struct pi_servo { + double offset[2]; + double local[2]; + double drift; + int count; +}; + +enum controller_mode { + MODE_NONE, + MODE_PI, + MAX_ALL +} mode; + struct rte_mempool *mbuf_pool; uint32_t ptp_enabled_port_mask; uint8_t ptp_enabled_port_nb; @@ -132,6 +154,9 @@ struct ptpv2_data_slave_ordinary { uint8_t ptpset; uint8_t kernel_time_set; uint16_t current_ptp_port; + int64_t master_offset; + int64_t path_delay; + struct pi_servo *servo; }; static struct ptpv2_data_slave_ordinary ptp_data; @@ -290,36 +315,44 @@ print_clock_info(struct ptpv2_data_slave_ordinary *ptp_data) ptp_data->tstamp3.tv_sec, (ptp_data->tstamp3.tv_nsec)); - printf("\nT4 - Master Clock. %lds %ldns ", + printf("\nT4 - Master Clock. %lds %ldns\n", ptp_data->tstamp4.tv_sec, (ptp_data->tstamp4.tv_nsec)); - printf("\nDelta between master and slave clocks:%"PRId64"ns\n", + if (mode == MODE_NONE) { + printf("\nDelta between master and slave clocks:%"PRId64"ns\n", ptp_data->delta); - clock_gettime(CLOCK_REALTIME, &sys_time); - rte_eth_timesync_read_time(ptp_data->current_ptp_port, &net_time); + clock_gettime(CLOCK_REALTIME, &sys_time); + rte_eth_timesync_read_time(ptp_data->current_ptp_port, + &net_time); - time_t ts = net_time.tv_sec; + time_t ts = net_time.tv_sec; - printf("\n\nComparison between Linux kernel Time and PTP:"); + printf("\n\nComparison between Linux kernel Time and PTP:"); - printf("\nCurrent PTP Time: %.24s %.9ld ns", + printf("\nCurrent PTP Time: %.24s %.9ld ns", ctime(&ts), net_time.tv_nsec); - nsec = (int64_t)timespec64_to_ns(&net_time) - + nsec = (int64_t)timespec64_to_ns(&net_time) - (int64_t)timespec64_to_ns(&sys_time); - ptp_data->new_adj = ns_to_timeval(nsec); + ptp_data->new_adj = ns_to_timeval(nsec); + + gettimeofday(&ptp_data->new_adj, NULL); - gettimeofday(&ptp_data->new_adj, NULL); + time_t tp = ptp_data->new_adj.tv_sec; - time_t tp = ptp_data->new_adj.tv_sec; + printf("\nCurrent SYS Time: %.24s %.6ld ns", + ctime(&tp), ptp_data->new_adj.tv_usec); - printf("\nCurrent SYS Time: %.24s %.6ld ns", - ctime(&tp), ptp_data->new_adj.tv_usec); + printf("\nDelta between PTP and Linux Kernel time:%"PRId64"ns\n", + nsec); + } - printf("\nDelta between PTP and Linux Kernel time:%"PRId64"ns\n", - nsec); + if (mode == MODE_PI) { + printf("path delay: %"PRId64"ns\n", ptp_data->path_delay); + printf("master offset: %"PRId64"ns\n", ptp_data->master_offset); + } printf("[Ctrl+C to quit]\n"); @@ -405,6 +438,76 @@ parse_fup(struct ptpv2_data_slave_ordinary *ptp_data) (((uint64_t)ntohs(origin_tstamp->sec_msb)) << 32); } +static double +pi_sample(struct pi_servo *s, double offset, double local_ts, + enum servo_state *state) +{ + double ppb = 0.0; + + switch (s->count) { + case 0: + s->offset[0] = offset; + s->local[0] = local_ts; + *state = SERVO_UNLOCKED; + s->count = 1; + break; + case 1: + s->offset[1] = offset; + s->local[1] = local_ts; + *state = SERVO_UNLOCKED; + s->count = 2; + break; + case 2: + s->drift += (s->offset[1] - s->offset[0]) / + (s->local[1] - s->local[0]); + *state = SERVO_UNLOCKED; + s->count = 3; + break; + case 3: + *state = SERVO_JUMP; + s->count = 4; + break; + case 4: + s->drift += KI * offset; + ppb = KP * offset + s->drift; + *state = SERVO_LOCKED; + break; + } + + return ppb; +} + +static void +ptp_adjust_freq(struct ptpv2_data_slave_ordinary *ptp_data) +{ + uint64_t t1_ns, t2_ns; + double adj_freq; + enum servo_state state = SERVO_UNLOCKED; + + t1_ns = timespec64_to_ns(&ptp_data->tstamp1); + t2_ns = timespec64_to_ns(&ptp_data->tstamp2); + ptp_data->master_offset = t2_ns - t1_ns - ptp_data->path_delay; + if (!ptp_data->path_delay) + return; + + adj_freq = pi_sample(ptp_data->servo, ptp_data->master_offset, + t2_ns, &state); + switch (state) { + case SERVO_UNLOCKED: + break; + case SERVO_JUMP: + rte_eth_timesync_adjust_time(ptp_data->portid, + -ptp_data->master_offset); + t1_ns = 0; + t2_ns = 0; + break; + case SERVO_LOCKED: + rte_eth_timesync_adjust_freq(ptp_data->portid, + -(long)(adj_freq * 65.536)); + break; + } +} + static void send_delay_request(struct ptpv2_data_slave_ordinary *ptp_data) { @@ -536,6 +639,21 @@ update_kernel_time(void) } +static void +clock_path_delay(struct ptpv2_data_slave_ordinary *ptp_data) +{ + uint64_t t1_ns, t2_ns, t3_ns, t4_ns; + int64_t pd; + + t1_ns = timespec64_to_ns(&ptp_data->tstamp1); + t2_ns = timespec64_to_ns(&ptp_data->tstamp2); + t3_ns = timespec64_to_ns(&ptp_data->tstamp3); + t4_ns = timespec64_to_ns(&ptp_data->tstamp4); + + pd = (t2_ns - t3_ns) + (t4_ns - t1_ns); + ptp_data->path_delay = pd / 2; +} + /* * Parse the DELAY_RESP message. */ @@ -560,6 +678,9 @@ parse_drsp(struct ptpv2_data_slave_ordinary *ptp_data) ((uint64_t)ntohl(rx_tstamp->sec_lsb)) | (((uint64_t)ntohs(rx_tstamp->sec_msb)) << 32); + if (mode == MODE_PI) + clock_path_delay(ptp_data); + ptp_data->current_ptp_port = ptp_data->portid; /* Update kernel time if enabled in app parameters. */ @@ -608,11 +729,14 @@ parse_ptp_frames(uint16_t portid, struct rte_mbuf *m) { break; case FOLLOW_UP: parse_fup(&ptp_data); + if (mode == MODE_PI) + ptp_adjust_freq(&ptp_data); send_delay_request(&ptp_data); break; case DELAY_RESP: parse_drsp(&ptp_data); - ptp_adjust_time(&ptp_data); + if (mode == MODE_NONE) + ptp_adjust_time(&ptp_data); print_clock_info(&ptp_data); break; default: @@ -709,7 +833,10 @@ ptp_parse_args(int argc, char **argv) char **argvopt; int option_index; char *prgname = argv[0]; - static struct option lgopts[] = { {NULL, 0, 0, 0} }; + static struct option lgopts[] = { + {"controller", 1, 0, 0}, + {NULL, 0, 0, 0} + }; argvopt = argv; @@ -737,6 +864,11 @@ ptp_parse_args(int argc, char **argv) ptp_data.kernel_time_set = ret; break; + case 0: + if (!strcmp(lgopts[option_index].name, "controller")) + if (!strcmp(optarg, "pi")) + mode = MODE_PI; + break; default: print_usage(prgname); @@ -780,6 +912,15 @@ main(int argc, char *argv[]) rte_exit(EXIT_FAILURE, "Error with PTP initialization\n"); /* >8 End of parsing specific arguments. */ + if (mode == MODE_PI) { + ptp_data.servo = malloc(sizeof(*(ptp_data.servo))); + if (!ptp_data.servo) + rte_exit(EXIT_FAILURE, "no memory for servo\n"); + + ptp_data.servo->drift = 0; + ptp_data.servo->count = 0; + } + /* Check that there is an even number of ports to send/receive on. */ nb_ports = rte_eth_dev_count_avail(); @@ -819,6 +960,9 @@ main(int argc, char *argv[]) /* Call lcore_main on the main core only. */ lcore_main(); + if (mode == MODE_PI) + free(ptp_data.servo); + /* clean up the EAL */ rte_eal_cleanup();