get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/8341/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 8341,
    "url": "http://patches.dpdk.org/api/patches/8341/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1446198204-9852-4-git-send-email-danielx.t.mrzyglod@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1446198204-9852-4-git-send-email-danielx.t.mrzyglod@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1446198204-9852-4-git-send-email-danielx.t.mrzyglod@intel.com",
    "date": "2015-10-30T09:43:21",
    "name": "[dpdk-dev,v2,3/6] igb: add additional ieee1588 support functions",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "fe356eb8f57b8a5a2d8d8ca77d578be42723d009",
    "submitter": {
        "id": 23,
        "url": "http://patches.dpdk.org/api/people/23/?format=api",
        "name": "Daniel Mrzyglod",
        "email": "danielx.t.mrzyglod@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1446198204-9852-4-git-send-email-danielx.t.mrzyglod@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/8341/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/8341/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 834048E6C;\n\tFri, 30 Oct 2015 10:46:51 +0100 (CET)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id 4C5D68E68\n\tfor <dev@dpdk.org>; Fri, 30 Oct 2015 10:46:49 +0100 (CET)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga101.jf.intel.com with ESMTP; 30 Oct 2015 02:46:49 -0700",
            "from unknown ([10.217.248.15])\n\tby orsmga002.jf.intel.com with SMTP; 30 Oct 2015 02:46:46 -0700",
            "by  (sSMTP sendmail emulation); Fri, 30 Oct 2015 10:46:03 +0100"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.20,217,1444719600\"; d=\"scan'208\";a=\"838723098\"",
        "From": "Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri, 30 Oct 2015 10:43:21 +0100",
        "Message-Id": "<1446198204-9852-4-git-send-email-danielx.t.mrzyglod@intel.com>",
        "X-Mailer": "git-send-email 2.1.4",
        "In-Reply-To": "<1446198204-9852-1-git-send-email-danielx.t.mrzyglod@intel.com>",
        "References": "<1443799208-9408-1-git-send-email-danielx.t.mrzyglod@intel.com>\n\t<1446198204-9852-1-git-send-email-danielx.t.mrzyglod@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 3/6] igb: add additional ieee1588 support\n\tfunctions",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Pablo de Lara <pablo.de.lara.guarch@intel.com>\n\nAdd additional functions to support the existing IEEE1588\nfunctionality and to enable getting, setting and adjusting\nthe device time.\n\nSigned-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>\nSigned-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>\n---\n drivers/net/e1000/e1000_ethdev.h |  22 +++\n drivers/net/e1000/igb_ethdev.c   | 338 +++++++++++++++++++++++++++++++++++++--\n 2 files changed, 350 insertions(+), 10 deletions(-)",
    "diff": "diff --git a/drivers/net/e1000/e1000_ethdev.h b/drivers/net/e1000/e1000_ethdev.h\nindex 4e69e44..c8772b7 100644\n--- a/drivers/net/e1000/e1000_ethdev.h\n+++ b/drivers/net/e1000/e1000_ethdev.h\n@@ -220,6 +220,26 @@ struct e1000_filter_info {\n };\n \n /*\n+ * Structure for cyclecounter IEEE1588 functionality.\n+ */\n+struct cyclecounter {\n+\tuint64_t (*read)(struct rte_eth_dev *dev);\n+\tuint64_t mask;\n+\tuint32_t shift;\n+};\n+\n+/*\n+ * Structure to hold and calculate Unix epoch time.\n+ */\n+struct timecounter {\n+\tstruct cyclecounter *cc;\n+\tuint64_t cycle_last;\n+\tuint64_t nsec;\n+\tuint64_t mask;\n+\tuint64_t frac;\n+};\n+\n+/*\n  * Structure to store private data for each driver instance (for each port).\n  */\n struct e1000_adapter {\n@@ -230,6 +250,8 @@ struct e1000_adapter {\n \tstruct e1000_vf_info    *vfdata;\n \tstruct e1000_filter_info filter;\n \tbool stopped;\n+\tstruct cyclecounter cc;\n+\tstruct timecounter tc;\n };\n \n #define E1000_DEV_PRIVATE(adapter) \\\ndiff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c\nindex 3ab082e..fea11f8 100644\n--- a/drivers/net/e1000/igb_ethdev.c\n+++ b/drivers/net/e1000/igb_ethdev.c\n@@ -78,10 +78,12 @@\n #define IGB_8_BIT_MASK   UINT8_MAX\n \n /* Additional timesync values. */\n-#define E1000_ETQF_FILTER_1588 3\n-#define E1000_TIMINCA_INCVALUE 16000000\n-#define E1000_TIMINCA_INIT     ((0x02 << E1000_TIMINCA_16NS_SHIFT) \\\n-\t\t\t\t| E1000_TIMINCA_INCVALUE)\n+#define NSEC_PER_SEC                 1000000000L\n+#define E1000_CYCLECOUNTER_MASK      0xffffffffffffffff\n+#define E1000_ETQF_FILTER_1588       3\n+#define IGB_82576_TSYNC_SHIFT        16\n+#define E1000_INCPERIOD_82576        (1 << E1000_TIMINCA_16NS_SHIFT)\n+#define E1000_INCVALUE_82576         (16 << IGB_82576_TSYNC_SHIFT)\n #define E1000_TSAUXC_DISABLE_SYSTIME 0x80000000\n \n static int  eth_igb_configure(struct rte_eth_dev *dev);\n@@ -230,6 +232,11 @@ static int igb_timesync_read_rx_timestamp(struct rte_eth_dev *dev,\n \t\t\t\t\t  uint32_t flags);\n static int igb_timesync_read_tx_timestamp(struct rte_eth_dev *dev,\n \t\t\t\t\t  struct timespec *timestamp);\n+static int igb_timesync_time_adjust(struct rte_eth_dev *dev, int64_t delta);\n+static int igb_timesync_time_get(struct rte_eth_dev *dev,\n+\t\tstruct timespec *timestamp);\n+static int igb_timesync_time_set(struct rte_eth_dev *dev,\n+\t\tstruct timespec *timestamp);\n static int eth_igb_rx_queue_intr_enable(struct rte_eth_dev *dev,\n \t\t\t\t\tuint16_t queue_id);\n static int eth_igb_rx_queue_intr_disable(struct rte_eth_dev *dev,\n@@ -327,6 +334,9 @@ static const struct eth_dev_ops eth_igb_ops = {\n \t.get_eeprom_length    = eth_igb_get_eeprom_length,\n \t.get_eeprom           = eth_igb_get_eeprom,\n \t.set_eeprom           = eth_igb_set_eeprom,\n+\t.timesync_time_adjust  = igb_timesync_time_adjust,\n+\t.timesync_time_get     = igb_timesync_time_get,\n+\t.timesync_time_set     = igb_timesync_time_set,\n };\n \n /*\n@@ -3883,20 +3893,286 @@ eth_igb_set_mc_addr_list(struct rte_eth_dev *dev,\n \treturn 0;\n }\n \n+static inline uint64_t\n+timespec_to_ns(const struct timespec *ts)\n+{\n+\treturn ((uint64_t) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;\n+}\n+\n+static struct timespec\n+ns_to_timespec(uint64_t nsec)\n+{\n+\tstruct timespec ts = {0, 0};\n+\n+\tif (nsec == 0)\n+\t\treturn ts;\n+\n+\tts.tv_sec = nsec / NSEC_PER_SEC;\n+\tts.tv_nsec = nsec % NSEC_PER_SEC;\n+\n+\treturn ts;\n+}\n+\n+/*\n+ * Converts cycle counter cycles to nanoseconds.\n+ */\n+static inline uint64_t\n+cyclecounter_cycles_to_ns(const struct cyclecounter *cc, uint64_t cycles,\n+\t\t\tuint64_t mask, uint64_t *frac)\n+{\n+\tuint64_t ns;\n+\n+\t/* Add fractional nanoseconds. */\n+\tns = cycles + *frac;\n+\t*frac = ns & mask;\n+\n+\t/* Shift to get only nanoseconds. */\n+\treturn (ns >> cc->shift);\n+}\n+\n+/*\n+ * Like cyclecounter_cycles_to_ns(), but this is used when\n+ * computing a time previous to the stored in the cycle counter.\n+ */\n+static uint64_t\n+cyclecounter_cycles_to_ns_backwards(const struct cyclecounter *cc,\n+\t\t\tuint64_t cycles, uint64_t frac)\n+{\n+\treturn ((cycles - frac) >> cc->shift);\n+}\n+\n+/*\n+ * Register units might not be nanoseconds. This function converts\n+ * these units into nanoseconds and adds to the previous time stored.\n+ */\n+static uint64_t\n+timecounter_cycles_to_ns_time(struct timecounter *tc, uint64_t cycle_tstamp)\n+{\n+\tuint64_t delta;\n+\tuint64_t nsec = tc->nsec, frac = tc->frac;\n+\n+\tdelta = (cycle_tstamp - tc->cycle_last) & tc->cc->mask;\n+\t/*\n+\t * Cycle counts that are correctly converted as they\n+\t * are between -1/2 max cycle count and +1/2 max cycle count.\n+\t */\n+\tif (delta > (tc->cc->mask / 2)) {\n+\t\tdelta = (tc->cycle_last - cycle_tstamp) & tc->cc->mask;\n+\t\tnsec -= cyclecounter_cycles_to_ns_backwards(tc->cc, delta, frac);\n+\t} else {\n+\t\tnsec += cyclecounter_cycles_to_ns(tc->cc, delta, tc->mask, &frac);\n+\t}\n+\n+\treturn nsec;\n+}\n+\n+static uint64_t\n+igb_read_timesync_cyclecounter(struct rte_eth_dev *dev)\n+{\n+\tstruct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tuint64_t systime_cycles = 0;\n+\n+\tswitch (hw->mac.type) {\n+\tcase e1000_i210:\n+\tcase e1000_i211:\n+\t\t/*\n+\t\t * Need to read System Time Residue Register to be able\n+\t\t * to read the other two registers.\n+\t\t */\n+\t\tE1000_READ_REG(hw, E1000_SYSTIMR);\n+\t\t/* SYSTIMEL stores ns and SYSTIMEH stores seconds. */\n+\t\tsystime_cycles = (uint64_t)E1000_READ_REG(hw, E1000_SYSTIML);\n+\t\tsystime_cycles += (uint64_t)E1000_READ_REG(hw, E1000_SYSTIMH)\n+\t\t\t\t* NSEC_PER_SEC;\n+\t\tbreak;\n+\tcase e1000_82580:\n+\tcase e1000_i350:\n+\tcase e1000_i354:\n+\t\t/*\n+\t\t * Need to read System Time Residue Register to be able\n+\t\t * to read the other two registers.\n+\t\t */\n+\t\tE1000_READ_REG(hw, E1000_SYSTIMR);\n+\t\tsystime_cycles |= (uint64_t)E1000_READ_REG(hw, E1000_SYSTIML);\n+\t\t/* Only the 8 LSB are valid. */\n+\t\tsystime_cycles |= (uint64_t)(E1000_READ_REG(hw, E1000_SYSTIMH)\n+\t\t\t\t& 0xff) << 32;\n+\t\tbreak;\n+\tdefault:\n+\t\tsystime_cycles |= (uint64_t)E1000_READ_REG(hw, E1000_SYSTIML);\n+\t\tsystime_cycles |= (uint64_t)E1000_READ_REG(hw, E1000_SYSTIMH)\n+\t\t\t\t<< 32;\n+\t\tbreak;\n+\t}\n+\n+\treturn systime_cycles;\n+}\n+\n+/*\n+ * Get nanoseconds since the last call of this function.\n+ */\n+static uint64_t\n+timecounter_read_ns_delta(struct rte_eth_dev *dev)\n+{\n+\tuint64_t cycle_now, cycle_delta;\n+\tuint64_t ns_offset;\n+\tstruct e1000_adapter *adapter =\n+\t\t\t\t(struct e1000_adapter *)dev->data->dev_private;\n+\tstruct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\n+\t/* Read cycle counter. */\n+\tcycle_now = adapter->tc.cc->read(dev);\n+\n+\t/* Calculate the delta since the last timecounter_read_delta(). */\n+\tcycle_delta = (cycle_now - adapter->tc.cycle_last) & adapter->tc.cc->mask;\n+\n+\t/* Convert to nanoseconds. */\n+\tswitch (hw->mac.type) {\n+\tcase e1000_i210:\n+\tcase e1000_i211:\n+\tcase e1000_82580:\n+\tcase e1000_i350:\n+\tcase e1000_i354:\n+\t\t/* Registers store directly nanoseconds, no need to convert. */\n+\t\tns_offset = cycle_delta;\n+\t\tbreak;\n+\tdefault:\n+\t\tns_offset = cyclecounter_cycles_to_ns(adapter->tc.cc, cycle_delta,\n+\t\t\t\t\tadapter->tc.mask, &adapter->tc.frac);\n+\t}\n+\n+\t/* Store current cycle counter for next timecounter_read_ns_delta() call. */\n+\tadapter->tc.cycle_last = cycle_now;\n+\n+\treturn ns_offset;\n+}\n+\n+static uint64_t\n+timecounter_read(struct rte_eth_dev *dev)\n+{\n+\tuint64_t nsec;\n+\tstruct e1000_adapter *adapter =\n+\t\t\t(struct e1000_adapter *)dev->data->dev_private;\n+\n+\t/* increment time by nanoseconds since last call */\n+\tnsec = timecounter_read_ns_delta(dev);\n+\tnsec += adapter->tc.nsec;\n+\tadapter->tc.nsec = nsec;\n+\n+\treturn nsec;\n+}\n+\n+\n+static void\n+timecounter_init(struct rte_eth_dev *dev,\n+\t\t      uint64_t start_time)\n+{\n+\tstruct e1000_adapter *adapter =\n+\t\t\t\t(struct e1000_adapter *)dev->data->dev_private;\n+\tstruct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\n+\tadapter->tc.cc = &adapter->cc;\n+\tadapter->tc.cycle_last = adapter->tc.cc->read(dev);\n+\tadapter->tc.nsec = start_time;\n+\tswitch (hw->mac.type) {\n+\tcase e1000_82580:\n+\tcase e1000_i350:\n+\tcase e1000_i354:\n+\t\t/* 32 LSB bits + 8 MSB bits = 40 bits */\n+\t\tadapter->tc.mask = (1ULL << 40) - 1;\n+\tdefault:\n+\t\tadapter->tc.mask = (1ULL << adapter->tc.cc->shift) - 1;\n+\t}\n+\tadapter->tc.frac = 0;\n+}\n+\n+static void\n+igb_start_cyclecounter(struct rte_eth_dev *dev)\n+{\n+\tstruct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct e1000_adapter *adapter =\n+\t\t(struct e1000_adapter *)dev->data->dev_private;\n+\tuint32_t incval = 1;\n+\tuint32_t shift = 0;\n+\n+\tswitch (hw->mac.type) {\n+\tcase e1000_i210:\n+\tcase e1000_i211:\n+\tcase e1000_82580:\n+\tcase e1000_i350:\n+\tcase e1000_i354:\n+\t\t/* Start incrementing the register used to timestamp PTP packets. */\n+\t\tE1000_WRITE_REG(hw, E1000_TIMINCA, incval);\n+\t\tbreak;\n+\tcase e1000_82576:\n+\t\tincval = E1000_INCVALUE_82576;\n+\t\tshift = IGB_82576_TSYNC_SHIFT;\n+\t\tE1000_WRITE_REG(hw, E1000_TIMINCA, E1000_INCPERIOD_82576 | incval);\n+\t\tbreak;\n+\tdefault:\n+\t\t/* Not supported */\n+\t\treturn;\n+\t}\n+\n+\tmemset(&adapter->cc, 0, sizeof(struct cyclecounter));\n+\tadapter->cc.read = igb_read_timesync_cyclecounter;\n+\tadapter->cc.mask = E1000_CYCLECOUNTER_MASK;\n+\tadapter->cc.shift = shift;\n+}\n+\n+static int\n+igb_timesync_time_adjust(struct rte_eth_dev *dev, int64_t delta)\n+{\n+\tstruct e1000_adapter *adapter =\n+\t\t\t(struct e1000_adapter *)dev->data->dev_private;\n+\n+\tadapter->tc.nsec += delta;\n+\n+\treturn 0;\n+}\n+\n+static int\n+igb_timesync_time_set(struct rte_eth_dev *dev, struct timespec *ts)\n+{\n+\tuint64_t ns;\n+\n+\tns = timespec_to_ns(ts);\n+\n+\t/* Reset the timecounter. */\n+\ttimecounter_init(dev, ns);\n+\n+\treturn 0;\n+}\n+\n+static int\n+igb_timesync_time_get(struct rte_eth_dev *dev, struct timespec *ts)\n+{\n+\tuint64_t ns;\n+\n+\tns = timecounter_read(dev);\n+\t*ts = ns_to_timespec(ns);\n+\n+\treturn 0;\n+}\n+\n static int\n igb_timesync_enable(struct rte_eth_dev *dev)\n {\n \tstruct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n \tuint32_t tsync_ctl;\n \tuint32_t tsauxc;\n+\tuint64_t ns;\n+\tstruct timespec zerotime = {0, 0};\n \n \t/* Enable system time for it isn't on by default. */\n \ttsauxc = E1000_READ_REG(hw, E1000_TSAUXC);\n \ttsauxc &= ~E1000_TSAUXC_DISABLE_SYSTIME;\n \tE1000_WRITE_REG(hw, E1000_TSAUXC, tsauxc);\n \n-\t/* Start incrementing the register used to timestamp PTP packets. */\n-\tE1000_WRITE_REG(hw, E1000_TIMINCA, E1000_TIMINCA_INIT);\n+\t/* Set 0.0 epoch time to initialize timecounter. */\n+\tns = timespec_to_ns(&zerotime);\n+\tigb_start_cyclecounter(dev);\n+\ttimecounter_init(dev, ns);\n \n \t/* Enable L2 filtering of IEEE1588/802.1AS Ethernet frame types. */\n \tE1000_WRITE_REG(hw, E1000_ETQF(E1000_ETQF_FILTER_1588),\n@@ -3948,9 +4224,13 @@ igb_timesync_read_rx_timestamp(struct rte_eth_dev *dev,\n \t\t\t       uint32_t flags __rte_unused)\n {\n \tstruct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct e1000_adapter *adapter =\n+\t\t\t(struct e1000_adapter *)dev->data->dev_private;\n+\n \tuint32_t tsync_rxctl;\n \tuint32_t rx_stmpl;\n \tuint32_t rx_stmph;\n+\tuint64_t regival = 0;\n \n \ttsync_rxctl = E1000_READ_REG(hw, E1000_TSYNCRXCTL);\n \tif ((tsync_rxctl & E1000_TSYNCRXCTL_VALID) == 0)\n@@ -3958,9 +4238,26 @@ igb_timesync_read_rx_timestamp(struct rte_eth_dev *dev,\n \n \trx_stmpl = E1000_READ_REG(hw, E1000_RXSTMPL);\n \trx_stmph = E1000_READ_REG(hw, E1000_RXSTMPH);\n+\ttimecounter_read(dev);\n+\n+\tswitch (hw->mac.type) {\n+\tcase e1000_82580:\n+\tcase e1000_i350:\n+\tcase e1000_i354:\n+\t\tregival = (uint64_t)((((uint64_t)(rx_stmph & 0xff)) << 32)\n+\t\t\t| rx_stmpl);\n+\t\tbreak;\n+\tcase e1000_i210:\n+\tcase e1000_i211:\n+\t\tregival = (uint64_t)((uint64_t)rx_stmph * NSEC_PER_SEC\n+\t\t\t+ rx_stmpl);\n+\t\tbreak;\n+\tdefault:\n+\t\tregival = (uint64_t)(((uint64_t)rx_stmph << 32) | rx_stmpl);\n+\t}\n \n-\ttimestamp->tv_sec = (uint64_t)(((uint64_t)rx_stmph << 32) | rx_stmpl);\n-\ttimestamp->tv_nsec = 0;\n+\tregival = timecounter_cycles_to_ns_time(&adapter->tc, regival);\n+\t*timestamp = ns_to_timespec(regival);\n \n \treturn  0;\n }\n@@ -3970,6 +4267,10 @@ igb_timesync_read_tx_timestamp(struct rte_eth_dev *dev,\n \t\t\t       struct timespec *timestamp)\n {\n \tstruct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct e1000_adapter *adapter =\n+\t\t\t(struct e1000_adapter *)dev->data->dev_private;\n+\tuint64_t regival = 0;\n+\n \tuint32_t tsync_txctl;\n \tuint32_t tx_stmpl;\n \tuint32_t tx_stmph;\n@@ -3980,9 +4281,26 @@ igb_timesync_read_tx_timestamp(struct rte_eth_dev *dev,\n \n \ttx_stmpl = E1000_READ_REG(hw, E1000_TXSTMPL);\n \ttx_stmph = E1000_READ_REG(hw, E1000_TXSTMPH);\n+\ttimecounter_read(dev);\n+\n+\tswitch (hw->mac.type) {\n+\tcase e1000_82580:\n+\tcase e1000_i350:\n+\tcase e1000_i354:\n+\t\tregival = (uint64_t)((((uint64_t)(tx_stmph & 0xff)) << 32)\n+\t\t\t| tx_stmpl);\n+\t\tbreak;\n+\tcase e1000_i210:\n+\tcase e1000_i211:\n+\t\tregival = (uint64_t)((uint64_t)tx_stmph * NSEC_PER_SEC\n+\t\t\t+ tx_stmpl);\n+\t\tbreak;\n+\tdefault:\n+\t\tregival = (uint64_t)(((uint64_t)tx_stmph << 32) | tx_stmpl);\n+\t}\n \n-\ttimestamp->tv_sec = (uint64_t)(((uint64_t)tx_stmph << 32) | tx_stmpl);\n-\ttimestamp->tv_nsec = 0;\n+\tregival = timecounter_cycles_to_ns_time(&adapter->tc, regival);\n+\t*timestamp = ns_to_timespec(regival);\n \n \treturn  0;\n }\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "3/6"
    ]
}