From patchwork Mon Sep 17 07:48:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yogev Chaimovich X-Patchwork-Id: 44771 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5347D2BA8; Mon, 17 Sep 2018 09:45:49 +0200 (CEST) Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on0111.outbound.protection.outlook.com [104.47.0.111]) by dpdk.org (Postfix) with ESMTP id 862792B84 for ; Mon, 17 Sep 2018 09:45:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cgstowernetworks.onmicrosoft.com; s=selector1-cgstowernetworks-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=DvG86tMuvDw8hybsSvAZH1lY56EnOF57rmxR35pGaCM=; b=Y0E7GaqcjvSNE45mbJR10BFiSyo1kfhvQkYpMxZhWVhytdcZFm67CQK8tMKTjllY2nvIUcVluZDN0KcC3fXGkbA3JrPPJJ7CfWoXbKBUTYQst29qhjh87DEUAyLXaOv1sDJoIqleejGL9w0vIknS3yvFQdo3876Q0P5yhr7tyzU= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=yogev@cgstowernetworks.com; Received: from ubuntu.cgs.com (5.144.48.231) by AM4PR0902MB1825.eurprd09.prod.outlook.com (2603:10a6:200:95::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1143.17; Mon, 17 Sep 2018 07:45:46 +0000 From: yogev ch To: dev@dpdk.org Cc: yogev ch Date: Mon, 17 Sep 2018 10:48:13 +0300 Message-Id: <1537170493-83190-1-git-send-email-yogev@cgstowernetworks.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1534923617-55302-1-git-send-email-yogev@cgstowernetworks.com> References: <1534923617-55302-1-git-send-email-yogev@cgstowernetworks.com> MIME-Version: 1.0 X-Originating-IP: [5.144.48.231] X-ClientProxiedBy: AM5PR0602CA0019.eurprd06.prod.outlook.com (2603:10a6:203:a3::29) To AM4PR0902MB1825.eurprd09.prod.outlook.com (2603:10a6:200:95::22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 41f3ae77-52c8-495c-edd4-08d61c7194a4 X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(7021125)(8989137)(4534165)(7022125)(4603075)(4627221)(201702281549075)(8990107)(7048125)(7024125)(7027125)(7023125)(5600074)(711020)(2017052603328)(7153060)(7193020); SRVR:AM4PR0902MB1825; X-Microsoft-Exchange-Diagnostics: 1; AM4PR0902MB1825; 3:Ep2EWJk0X/tR4lpxS6HDzvFJ7HBCMJp3FQkESpzbXnbjQMo1FPtAwFlS6ErcjadmxiJiu+lTyDicRSAT+86/3cDXdansaWYL+7nveJ1tW7KsJAnP3iTlPdqST/BxtB5ThzHT/ibJYK6lG49MwdeT+btmc6Wtse/FYjca8PyM7Bffeog7SZ2ZutBPt/KMr94uQO53Uyp7UM7/xUxGIXOISL0j9ibETdFl01bVfM4QUhKp8MaY4qwqie8rYzF9Z7E+; 25:8cv56aKfzMdwoAdDZtKn5ey7eHVVDMykB35arwcdI57gj9kD5Wmx0z/24IzqfzbHPwv8TuVprxJxjnbAkpf8voeXn6mpiLTWZS6pz24XuLch0wtT7Clom0valQNM+5vRgRbS/S2iXYQq0NXyFPp+Sf//tiuF0VddP8H4VWv9BO+6iJ7Xf0kkI48zTV6QElrcoye2GBwg0GiDAFEEdz6VyFrP/aL2YTP9kkf/al75WMGX5niV1w8YRn2j+8nYsxTMl2IBdiODHs1j9LCt0aFg1TfQkJ02nHf4muLM4PKQZL7VLEnN7RUqQBSfG4B1oQF4RO9ErYNWZYQgwPmsxmRfhQ==; 31:cH+5gD+C2TjQ7uste+LZxIyHwq04l4skjVNzt+c/FUG33evdpyXECOMmFpE49YtBkO5hTUfN6rUhaH0Or/VFQ7Ad6ZPLJhfafXJkN2kIxQdwhF2DouCJJeVlYubzPMrilA5F1vl1fDftyLU6yDg0gulQoewgxnHU7SE0K7m7yziYOKGr188vzrW7WNLxmSbNaYY6QAR1nhUGiBdcevX9S4/Xm42+C2IH9m2rzRK+t80= X-MS-TrafficTypeDiagnostic: AM4PR0902MB1825: X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040522)(2401047)(5005006)(8121501046)(3231355)(944501410)(52105095)(93006095)(93001095)(10201501046)(3002001)(149027)(150027)(6041310)(20161123564045)(20161123558120)(2016111802025)(20161123560045)(20161123562045)(6043046)(201708071742011)(7699050); SRVR:AM4PR0902MB1825; BCL:0; PCL:0; RULEID:; SRVR:AM4PR0902MB1825; X-Microsoft-Exchange-Diagnostics: 1; AM4PR0902MB1825; 4:+QcBAoN3SaDVnjv2854n2XMfG/CMfXGKsC/HjXpdme7XS7jckhY5Vj20sBLDaE0o985qe54yEpU9TrW5CRr68po3jts3QrDE5eUNxxUaTtFODABwlOMpltfqNNDwm1IEfZrWcd249gPgH+cSuXUq9W+pyWE2pzOjsU+wEZv60loWaPwsXr9ZyFy9YGn8nnHT7CFlRzstZ8mIsL/VM4btTafwF904POaqiFvXdp8xZvMGqSssWBXRasNzNEHA9whe+2zKlq5ATWQNfCe0kyAOIw== X-Forefront-PRVS: 0798146F16 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(136003)(376002)(396003)(346002)(366004)(39830400003)(189003)(199004)(97736004)(105586002)(53416004)(476003)(2616005)(107886003)(956004)(11346002)(68736007)(71446004)(8936002)(106356001)(2906002)(25786009)(48376002)(36756003)(50466002)(6666003)(81156014)(81166006)(50226002)(6916009)(2351001)(4326008)(66066001)(446003)(47776003)(305945005)(486006)(7736002)(5660300001)(3846002)(86362001)(86152003)(16526019)(53936002)(51416003)(508600001)(386003)(6506007)(16586007)(316002)(37156001)(1857600001)(6116002)(26005)(14444005)(186003)(6512007)(6486002)(8676002)(52116002)(76176011)(2361001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM4PR0902MB1825; H:ubuntu.cgs.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: cgstowernetworks.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM4PR0902MB1825; 23:16bFQLdconMgFMlsYiauHka0wEE2QcsNZ47Rp+l?= yhge7LhvS5Q/yHGu1yt8b85omVybPzlSuuvoXfegLzvvlsLyqIDJuFKvDV+rmSZfM3Cu9HrufmzO5r84JQcjt/dyaByS3AovrYz2JX4K8Ke5NzLbXPE4udnOMYfysIGMThhWPRKrtArZGuPIQFViQ6P5Uxz/JsUh9ugX1aqKdUC9UDldeU8Fv6rSgJaR4szd+2pG4kc+DeK34xR0BAcxQxxpYHeqG0kz/hQSNO/yYKLMipWwrKGyARt1X4vucRCe2fRG+uBGPeCfPwfyoQ645d1fLCfiPLPb+9pbQMviHvXIXnBVOuYhdrqggFeJj+7y5Zto2LQ6kTDPLkxNaL206iCI1FN3RC9u8e9TAi/qYHpNME3maHAbHlFLKMsl3Up4+8S78SzIZEHaF5h3tJ9LlPCJoHfYvSzdf7EQAU7X1p9FyodXT78cXt3O9DhuIbDmHca+wq7beJmJX+kWxwGCA6xoLcVrIXneHHejbrg4i03H1WCkFrEL4CZoByBmh2ijozm0DSNUsCP9rX/5AjtYcw0kbhE1ISXhglS2hJ1bl4mCJUVsrvAMpArnceJzc6szToZkhEWUJvvNZyS7M2rcFLewrMREImMvPp9spkxl6UX3wCzMJMILInwz1hbyUBFSBx6/mcy/s8uGMVXbG9gT4WJGEXQ8zJP6pgVnRALXI3qzdZy/8uyydxP0S4dyiIIKTbmoJ6LEf9eFhDKKh0VSS0eDShivCvy7gll132JfHWDqr0PBiQB+9foFUfS7/plpIB5Ij5a3BEGVntKVwXE3WEvJOiFvxonn4H+C3RyBHCPLiODU6WvXZH4dBoSR47QKB+5gKsBLJbX8Nh/i36RHKIJrecYQ1hwfCVuXI1WQ6bpqr8Hq2zAgpOJ01/TSkcxVjw54aywfI8LGO+lkV4ZNXI/Iuo7F+C7k5q+UUiSouwke6m1r1LEQPTsruQxJgvcl2MMe9uSaqYK5i9RTrFIm/L85VXrb+2mDvx4A+9pBjVF9aPiI4jvEjYYKpRsePn3zg6zCENV1KCU9mqvOmERTT0lKLs6kQoYwVV+q9KiD3K8ocrzTTGNscdfjLR3YDJij7NOr8LKD5xB0TXHL+RoRkS5GOyht/jyWM5pdDihXWva+Hq5Bq+LrvXQd+jjljb6/wJEyrTR4wrTimQO8FZY/aPYlsUFRg+8Bg0pHCiW0ZPHziYgU3XH9pE0IxGWAtur4x2PwvuX8+/bPfpWj78q8bKsD5AO5ZVVAzgg9wxNOpck5yTaXtFi5OKIhcnLjtrbrYB96wOAKvQLYgJLZ0nau9dRggYQA+ruCx0Gs15BCtCCxWuw== X-Microsoft-Antispam-Message-Info: lwlWgq9ln/pu8rGWM+/Xz3apS4aIKnrn9cBOWmmyICKkkmh20/budhox3KKgHGkAvFuh8VJ0T0krJ+uj1lKkhHBlFv/9Bf1fffDxCcYKSKDQlGbLZoFq8AbRuj5kwwMthe9zpS8kyabiFodDLXwOldb8fhfh9TeBBYYj4mCJathEOICQz41FMBAIyFeoIIi5JuHlNyxe0N+d+qhtDi9FCXzhISRCXF7XEWcjKMr7o/qkRzIf+JQCP+XcJUpXQSZStLgid8bESnZe6QiEw9OKTYFbbePrZhAorLlM4mDhL9S3LipLIogpPRqh1Lmy/KstsRrjLHD29NXRwbV6oiTbAC9lsdIo+Se94J2HgvDoWWY= X-Microsoft-Exchange-Diagnostics: 1; AM4PR0902MB1825; 6:qYhk1rUJv3RyRuk+qEw8g/Bc+8jTpVVuakQmkz9YMrA5ggin7MKTxlrk0P0SpSmZQ4qic5AZq/pQO1S8GfQOlWZ5djytsl+9wh9lUOV79e7sOoZBVkDma4wUBfjgSb7m/27CkyUyV2417cI/Uhc3/36P3VdMjVPENRujCVXz8j1hS6z4DRpiI3BKvm/M5PSef5mV788lITkCJ99qlIFYyFNEkdhqrDVjKNsTcBQWSKoV16Lrg+llvggfmfrNp49/zvN/WihCFCMxlShpKPact/fsr3ZA1HttsXACgXg5hsZI0yn1fNeQHjRzRyErXlod7JsZweBs6blqlP7r8E6MDuC/NyhnwcTdOWPdwsQ1lXoGoZ5RG1FT45ou6fOU8jqntIrrXw/85isXdy2gx1RNENZ6FYkNto5UfeUwh0Bq7nfUTWMco/hhDwaPb/HBVUgeLXapQpB63bh0KQ2xuQNbyA==; 5:X48sovZp5mxRu98u5zperb2zYGxDCOifJ90Wtmv554Awo9mbk+KZJ8dh2d49xJLLCPrgR6xPB6TlrGT5sq/hQ/BdH4tcMhYRsY3A4wWuu/iHpRb8IH+FChQwCsS/+XmpdXBa0NWik7jXiEi5Jd77vkj3bczaZD02tpLk7yE0lFE=; 7:N4xgk4OuzLvr/Zwakxz1cKg3HzWxHDVnE/mVZfkAxbYQpcGgm5P/w1rVdKp9FzPsReKLtV0daMUki8sM2feiUwyBYbGrFhVeLA7Si52sV68+h8vfsYzOJtJSzIoxllndb/cAbJU2eKWmKOU06K3yOt3VoDywST3ws7rlEkZCzkyByqoOopWJsh0dGDTWEUpDLmV6upH0H74+VNnhhyhf5E8HQSQQCnaPnNy4C9V0UiC/wW0avDOeiZZuhWbmR4zQ SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: cgstowernetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Sep 2018 07:45:46.7260 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 41f3ae77-52c8-495c-edd4-08d61c7194a4 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: fc9e9498-07e8-4b82-b4cf-365bba23cbbf X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR0902MB1825 Subject: [dpdk-dev] [PATCH] vmxnet3: stats_reset implementation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 'stats_reset()' callback was missing. This commit implements the callback by taking a snapshot of the stats (SNAPSHOT) each time 'stats_reset()' is called. When getting stats with 'stats_get()', hw stats which always increase reduce SNAPSHOT stats. That's how we get the "real" stats since the last 'stats_reset()'. Signed-off-by: yogev ch Acked-by: Yong Wang Acked-by: Yong Wang --- drivers/net/vmxnet3/vmxnet3_ethdev.c | 78 ++++++++++++++++++++++++++++++++++-- drivers/net/vmxnet3/vmxnet3_ethdev.h | 3 ++ 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c index 2613cd1..2348300 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethdev.c +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c @@ -78,6 +78,7 @@ static int vmxnet3_dev_link_update(struct rte_eth_dev *dev, static void vmxnet3_hw_stats_save(struct vmxnet3_hw *hw); static int vmxnet3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats); +static void vmxnet3_dev_stats_reset(struct rte_eth_dev *dev); static int vmxnet3_dev_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats, unsigned int n); @@ -120,6 +121,7 @@ static int vmxnet3_mac_addr_set(struct rte_eth_dev *dev, .stats_get = vmxnet3_dev_stats_get, .xstats_get_names = vmxnet3_dev_xstats_get_names, .xstats_get = vmxnet3_dev_xstats_get, + .stats_reset = vmxnet3_dev_stats_reset, .mac_addr_set = vmxnet3_mac_addr_set, .dev_infos_get = vmxnet3_dev_info_get, .dev_supported_ptypes_get = vmxnet3_dev_supported_ptypes_get, @@ -335,6 +337,10 @@ struct vmxnet3_xstats_name_off { memset(hw->saved_tx_stats, 0, sizeof(hw->saved_tx_stats)); memset(hw->saved_rx_stats, 0, sizeof(hw->saved_rx_stats)); + /* clear snapshot stats */ + memset(hw->snapshot_tx_stats, 0, sizeof(hw->snapshot_tx_stats)); + memset(hw->snapshot_rx_stats, 0, sizeof(hw->snapshot_rx_stats)); + /* set the initial link status */ memset(&link, 0, sizeof(link)); link.link_duplex = ETH_LINK_FULL_DUPLEX; @@ -890,7 +896,49 @@ static int eth_vmxnet3_pci_remove(struct rte_pci_device *pci_dev) VMXNET3_UPDATE_RX_STAT(hw, q, pktsRxError, res); VMXNET3_UPDATE_RX_STAT(hw, q, pktsRxOutOfBuf, res); -#undef VMXNET3_UPDATE_RX_STATS +#undef VMXNET3_UPDATE_RX_STAT +} + +static void +vmxnet3_tx_stats_get(struct vmxnet3_hw *hw, unsigned int q, + struct UPT1_TxStats *res) +{ + vmxnet3_hw_tx_stats_get(hw, q, res); + +#define VMXNET3_REDUCE_SNAPSHOT_TX_STAT(h, i, f, r) \ + ((r)->f -= (h)->snapshot_tx_stats[(i)].f) + + VMXNET3_REDUCE_SNAPSHOT_TX_STAT(hw, q, ucastPktsTxOK, res); + VMXNET3_REDUCE_SNAPSHOT_TX_STAT(hw, q, mcastPktsTxOK, res); + VMXNET3_REDUCE_SNAPSHOT_TX_STAT(hw, q, bcastPktsTxOK, res); + VMXNET3_REDUCE_SNAPSHOT_TX_STAT(hw, q, ucastBytesTxOK, res); + VMXNET3_REDUCE_SNAPSHOT_TX_STAT(hw, q, mcastBytesTxOK, res); + VMXNET3_REDUCE_SNAPSHOT_TX_STAT(hw, q, bcastBytesTxOK, res); + VMXNET3_REDUCE_SNAPSHOT_TX_STAT(hw, q, pktsTxError, res); + VMXNET3_REDUCE_SNAPSHOT_TX_STAT(hw, q, pktsTxDiscard, res); + +#undef VMXNET3_REDUCE_SNAPSHOT_TX_STAT +} + +static void +vmxnet3_rx_stats_get(struct vmxnet3_hw *hw, unsigned int q, + struct UPT1_RxStats *res) +{ + vmxnet3_hw_rx_stats_get(hw, q, res); + +#define VMXNET3_REDUCE_SNAPSHOT_RX_STAT(h, i, f, r) \ + ((r)->f -= (h)->snapshot_rx_stats[(i)].f) + + VMXNET3_REDUCE_SNAPSHOT_RX_STAT(hw, q, ucastPktsRxOK, res); + VMXNET3_REDUCE_SNAPSHOT_RX_STAT(hw, q, mcastPktsRxOK, res); + VMXNET3_REDUCE_SNAPSHOT_RX_STAT(hw, q, bcastPktsRxOK, res); + VMXNET3_REDUCE_SNAPSHOT_RX_STAT(hw, q, ucastBytesRxOK, res); + VMXNET3_REDUCE_SNAPSHOT_RX_STAT(hw, q, mcastBytesRxOK, res); + VMXNET3_REDUCE_SNAPSHOT_RX_STAT(hw, q, bcastBytesRxOK, res); + VMXNET3_REDUCE_SNAPSHOT_RX_STAT(hw, q, pktsRxError, res); + VMXNET3_REDUCE_SNAPSHOT_RX_STAT(hw, q, pktsRxOutOfBuf, res); + +#undef VMXNET3_REDUCE_SNAPSHOT_RX_STAT } static void @@ -1005,7 +1053,7 @@ static int eth_vmxnet3_pci_remove(struct rte_pci_device *pci_dev) RTE_BUILD_BUG_ON(RTE_ETHDEV_QUEUE_STAT_CNTRS < VMXNET3_MAX_TX_QUEUES); for (i = 0; i < hw->num_tx_queues; i++) { - vmxnet3_hw_tx_stats_get(hw, i, &txStats); + vmxnet3_tx_stats_get(hw, i, &txStats); stats->q_opackets[i] = txStats.ucastPktsTxOK + txStats.mcastPktsTxOK + @@ -1022,7 +1070,7 @@ static int eth_vmxnet3_pci_remove(struct rte_pci_device *pci_dev) RTE_BUILD_BUG_ON(RTE_ETHDEV_QUEUE_STAT_CNTRS < VMXNET3_MAX_RX_QUEUES); for (i = 0; i < hw->num_rx_queues; i++) { - vmxnet3_hw_rx_stats_get(hw, i, &rxStats); + vmxnet3_rx_stats_get(hw, i, &rxStats); stats->q_ipackets[i] = rxStats.ucastPktsRxOK + rxStats.mcastPktsRxOK + @@ -1044,6 +1092,30 @@ static int eth_vmxnet3_pci_remove(struct rte_pci_device *pci_dev) } static void +vmxnet3_dev_stats_reset(struct rte_eth_dev *dev) +{ + unsigned int i; + struct vmxnet3_hw *hw = dev->data->dev_private; + struct UPT1_TxStats txStats; + struct UPT1_RxStats rxStats; + + VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS); + + RTE_BUILD_BUG_ON(RTE_ETHDEV_QUEUE_STAT_CNTRS < VMXNET3_MAX_TX_QUEUES); + + for (i = 0; i < hw->num_tx_queues; i++) { + vmxnet3_hw_tx_stats_get(hw, i, &txStats); + memcpy(&hw->snapshot_tx_stats[i], &txStats, + sizeof(hw->snapshot_tx_stats[0])); + } + for (i = 0; i < hw->num_rx_queues; i++) { + vmxnet3_hw_rx_stats_get(hw, i, &rxStats); + memcpy(&hw->snapshot_rx_stats[i], &rxStats, + sizeof(hw->snapshot_rx_stats[0])); + } +} + +static void vmxnet3_dev_info_get(struct rte_eth_dev *dev __rte_unused, struct rte_eth_dev_info *dev_info) { diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.h b/drivers/net/vmxnet3/vmxnet3_ethdev.h index d3f2b35..5bc3a84 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethdev.h +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.h @@ -98,6 +98,9 @@ struct vmxnet3_hw { #define VMXNET3_VFT_TABLE_SIZE (VMXNET3_VFT_SIZE * sizeof(uint32_t)) UPT1_TxStats saved_tx_stats[VMXNET3_MAX_TX_QUEUES]; UPT1_RxStats saved_rx_stats[VMXNET3_MAX_RX_QUEUES]; + + UPT1_TxStats snapshot_tx_stats[VMXNET3_MAX_TX_QUEUES]; + UPT1_RxStats snapshot_rx_stats[VMXNET3_MAX_RX_QUEUES]; }; #define VMXNET3_REV_3 2 /* Vmxnet3 Rev. 3 */