From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 90326A00C3;
	Thu, 12 May 2022 19:07:43 +0200 (CEST)
Received: from [217.70.189.124] (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id AC65E42845;
	Thu, 12 May 2022 19:07:12 +0200 (CEST)
Received: from NAM11-CO1-obe.outbound.protection.outlook.com
 (mail-co1nam11on2068.outbound.protection.outlook.com [40.107.220.68])
 by mails.dpdk.org (Postfix) with ESMTP id E039942831
 for <dev@dpdk.org>; Thu, 12 May 2022 19:07:08 +0200 (CEST)
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=F3wqgrmf8a0a9LQyGTn9OaTkE80EEzVO8O8rvd7nGN9ujJgRuKWQJZjAULDP4vMGiQ3kKoxqh2K6WQSzGqrchseEp//c+XwCzHA8MvBr7qufCJdaBgr0U57s44fgCbwa3rlTOd1hxZWpLZfesmmpR9eCCUt8uJ0jrzP4EzbC0XJ12m2DFp8ppxaMnwchULzCeviUGEE/zaxU3X8QA2sZ8hCXYMc1YjH9laJZg20UL051VsO4uPDNeVcUAd1/kfTvHqbGsqNfSgoPOM3BqVyGc64qXQ22MGMPR0qekeTxcW8AVptBzMC5M2Ju+86Oa+kYNnNsTObE1TWuPIkvRuGE0w==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; 
 s=arcselector9901;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;
 bh=o814Ps8CI4s3gPVDOCVnsrwpnx2Spmwf4huIZBaiJDk=;
 b=Hq8axWbrJAIF+TazfM6YLKmoy7XmhnmfLZiwX+XRES2431B4NalxeGOHgwI8JchQYWx/98rvsboAG7XQH66Vgdvnxv7VkTKdAIf7gYDqycRQwoMbZ6Ih/HdylFV3ueJFJ7nvYK/PHb9UNMnJiqanRfVZSWoirX7A9kT8E2nNWzn5eFxtsiKVrrrDyYqsoRm/jCwLvvx5CjB0b/4f96WUfYvZBKur9j+6ZgVMVoC2RY0hajX0M0bs3BLnYk9+K6HBcl3ftdTwmBPhKJDqR+u6YQu/6pab5cNQYdJfSBb9WzOcKAmLRJ6WbkBCiLOxKAjYWZeiHXasMxo6Yp48saaHyQ==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
 smtp.mailfrom=vmware.com; dmarc=pass action=none header.from=vmware.com;
 dkim=pass header.d=vmware.com; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vmware.com;
 s=selector2;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=o814Ps8CI4s3gPVDOCVnsrwpnx2Spmwf4huIZBaiJDk=;
 b=L9Oe1yFwM7yXVDyJ9ovLvEt020KCvdzIdRELxHreKLsr5ah7SKQjVMxHMgGJr5cNus/xKX2HbH2+ubN72/yfJ2bEEgUxV2jc4hF2oIHaCbZmIgGnYjLjU29bvQThrPlbfmUunRxbNpzmhXwBHDCNavIH7KFY+Zdu6gf8l+pnFms=
Authentication-Results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=vmware.com;
Received: from BYAPR05MB5624.namprd05.prod.outlook.com (2603:10b6:a03:1d::13)
 by BL0PR05MB4721.namprd05.prod.outlook.com (2603:10b6:208:28::26)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5250.12; Thu, 12 May
 2022 17:07:05 +0000
Received: from BYAPR05MB5624.namprd05.prod.outlook.com
 ([fe80::49ad:2ac7:16c0:51c8]) by BYAPR05MB5624.namprd05.prod.outlook.com
 ([fe80::49ad:2ac7:16c0:51c8%6]) with mapi id 15.20.5273.004; Thu, 12 May 2022
 17:07:05 +0000
From: Pankaj Gupta <pagupta@vmware.com>
To: jbehrens@vmware.com
Cc: dev@dpdk.org,
	pagupta@vmware.com
Subject: [PATCH v5 5/8] net/vmxnet3: version 6
Date: Thu, 12 May 2022 13:06:39 -0400
Message-Id: <20220512170642.28930-6-pagupta@vmware.com>
X-Mailer: git-send-email 2.17.1
In-Reply-To: <20220512170642.28930-1-pagupta@vmware.com>
References: <20220512170642.28930-1-pagupta@vmware.com>
Content-Type: text/plain
X-ClientProxiedBy: BYAPR02CA0014.namprd02.prod.outlook.com
 (2603:10b6:a02:ee::27) To BYAPR05MB5624.namprd05.prod.outlook.com
 (2603:10b6:a03:1d::13)
MIME-Version: 1.0
X-MS-PublicTrafficType: Email
X-MS-Office365-Filtering-Correlation-Id: 88793f51-02f3-45be-88ac-08da3439d5e2
X-MS-TrafficTypeDiagnostic: BL0PR05MB4721:EE_
X-Microsoft-Antispam-PRVS: <BL0PR05MB4721120A8953DE4963579343C9CB9@BL0PR05MB4721.namprd05.prod.outlook.com>
X-MS-Exchange-SenderADCheck: 1
X-MS-Exchange-AntiSpam-Relay: 0
X-Microsoft-Antispam: BCL:0;
X-Microsoft-Antispam-Message-Info: HeljyRQVDBW7D9ESGnEGy3rOTmfPZ99JGTsc/fJVBA2/bHp2bUfLPC78uMQs2M6hJ9ag3tn5SqkL3QZz5d9FQ9awy9QdpfERCrTsZQCdFba8ShITH2YRg9lvs2SZgOUyLcfzoLsPgK54dIvp7e5C1nuq9C2cyxcxfKkcrnsDm+Jx2C4oGU6u4l4v6MvLvQ11I0P+fc41IJZsdC7LqhS5L/HPai0GeX+ItSCdHft6cdT6uDVA4RE0vu/5wT3Kp17vnBwzBjiI4dJFomVCndNZKPFn5cOkIxb0acVZ2S8YhwoWXSFCyRp7DGK1EnabhLapvRQ4cMNhaQK7wsFpyq4r0EnlgWr56863fZMSmI+5rTL5Y1kkgOoC5aL0lDCON3Y2yN6/Y40QP95Xac8nt66iscz1vWYlkjs9MGklEV/gE6ijjgljSDVRW209EOiFqLjWvWlrremqUE3YRBcORaOeV4j1sUkZmgQZh5dZhQ8s+rY36g7IpW8Ms+vS27c/KGj+ctNhzBPLskw8LLJ7HH5d3k3kOKuy4lhsfnn2iyocUs+77UlG3+4VoCP/VKtE/NmvlmK1uXnQAoi6LkaebZPoxtG+IxZ9KdbFk5FOj/DZzjJ/lp0uLyq4o3GnjENTjLWBR/dwX0Ynn1+wENEqIo33H4bXjREg147+WMJO/QJ9NKMHfnc3KLs06d7jRxwfJXhhqSCzWUaP+T8VYsKip/6CVfNBPQ7FErdcKBpNB43wmVg=
X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
 IPV:NLI; SFV:NSPM; H:BYAPR05MB5624.namprd05.prod.outlook.com; PTR:; CAT:NONE;
 SFS:(13230001)(4636009)(366004)(38350700002)(66476007)(66556008)(86362001)(6666004)(66946007)(8676002)(34206002)(4326008)(38100700002)(6486002)(508600001)(6636002)(37006003)(316002)(1076003)(186003)(107886003)(19627235002)(6506007)(52116002)(2616005)(5660300002)(26005)(6512007)(8936002)(2906002)(30864003)(36756003)(83380400001)(21314003);
 DIR:OUT; SFP:1101; 
X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1
X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?xaWMVhH3pHiL4JDROLGQW/JP2D7uWVBcpBv6GhVIADlheRYj7Saaax2hTeuR?=
 =?us-ascii?Q?ldPLSF2pUPltbPzWP4l4UoKznn1XG/Cz4UEaynCl4z1F51TlalHCeDUtQ98l?=
 =?us-ascii?Q?4LS3W5UU63STSBiFyxke3fRw0Bc7wGnyFkISBw9yvaQlYELNRcEdDLj5XsAX?=
 =?us-ascii?Q?py7CFLZVDbFPn+T1VGhnaSg9dQeffqXhkoXBhxbbk6ONitEubDhG4G2ppD7Q?=
 =?us-ascii?Q?GVEi/kMa7vc6dSgPww11hBvV4Mfl31rRQNdLuSzotOGltUhUrnNC8PszRIY0?=
 =?us-ascii?Q?m0xNfcus7H4fBG31Ailf28BZlku6B0YMuzWhO7HGToGl/2Wg0JtRd8Zp34uY?=
 =?us-ascii?Q?yrbKFXDLC4Ftt/k52U8Q+3mebsb2j3vDIpY0muV7OMPMncYX2ZGzgjVYv320?=
 =?us-ascii?Q?Ue/CE67gKoW6qvRCE/4pTOo7gagXtt5sp1tghzadMXdkMjJbxGfjUuIT8B+/?=
 =?us-ascii?Q?wcco6txd/CNMz0YAT5HpzwKE8iKDqnrF4euszp7XexehbFkEFglorkB4pDD3?=
 =?us-ascii?Q?jE6+hCgJHhEZCQzBnMz00ZAgTuUMwnaBc1o5eJ0UBfztA3tAS7Ka72R/Lje0?=
 =?us-ascii?Q?dsqvSxyjjg8YiMMA8qtWtECO/TkqJ5pXkTaV02+m5EhtO1SZRskiWbAGna4X?=
 =?us-ascii?Q?rlUNXU/EHugBTD2CGnOYh15Qyz3OmhbbPw0vjAwmZVrVAzSyVfuNCDx0iwbx?=
 =?us-ascii?Q?CeF/X5+VR99k1FwlerUCbg4w1BGBEHNCAR+uTkmsj1u2oCjfCn6PuSg9hkYL?=
 =?us-ascii?Q?pYE/zF2lXy43g2XNYC/1hI4mnBrt4yDW9lB/7uCKAd48V3LKUHLabLBPtTMb?=
 =?us-ascii?Q?ocF+Lf7eaIK+6hdC9h2naNUayX5q6u9qea0MvTCGffpwC7Rk5/yaIrInZx0h?=
 =?us-ascii?Q?C0FMuwHt7a1t5Jt6C7pNs79UJjNpnMkirGmYaRiyp7ARxwEKwIW9CpkvwaKq?=
 =?us-ascii?Q?dchHAI5lkaSLIPzxJFf5LczIBHde86LfRrithJhg/ydT7RHfyO4bE+g0nBZf?=
 =?us-ascii?Q?onHD3790Qg+6YYTLl57StIDaoEjEgNk526clB3+Y3yxjdFCID+ttR+8ZIY9h?=
 =?us-ascii?Q?rngk79kLCNCQOA9j1Ik/5cjKEFFZpqefhMXVjUlHnt5IPRpXAUR59H147NZZ?=
 =?us-ascii?Q?g/tPPDPv7UCmtgUHwqO4oXfZdOsistNgrkXp7VUXr4Z3qelTLL0zc0jaoQW+?=
 =?us-ascii?Q?dMPuSn0JsPzqbBo6STb7/xw0MR84TZ0kU50p2zlxlrj71Yu+WJmXPIqY+XgH?=
 =?us-ascii?Q?OWiuxcMIgl6ZjoTztRgQMlO9D9nniq2wZn/dAyPhlKABfyhYjVHxb5cSzUQk?=
 =?us-ascii?Q?Tl6n2pCKz8kUUbymlHhFwCTfPxwnE6/SegdMcMRvm/1NJeLB138gr3eqaLyj?=
 =?us-ascii?Q?7rGlXK8HnEoEKFSaZo+lUmopKueZ0lpTgC6XaZNzphZwVALCS6EyM85Qsxn1?=
 =?us-ascii?Q?4vnG1WA94cKl8sCxgHZEemc5eRVofvCnncvsUMa7t2GR4gDVVAwNr66zTLZr?=
 =?us-ascii?Q?iFqiCePqI69+DQsNY8YpPX1eHshqmcZoI4CxLQGIDgUtaRx6cVXtfIsH9K7r?=
 =?us-ascii?Q?rgcBAt5PT/vvY0ayPJLqsqI1DYulr3dNiHusA2U5aMTU6cmfHlXTEbupTp9q?=
 =?us-ascii?Q?H48ZJbugSs3Ujb0Z29b3QSVw0xwTo82j4AY3b/wJbVku6RDboT+N+f2SEJgv?=
 =?us-ascii?Q?eOmQn9YI+PYSlAVZ9k/ymAjHW7S8QvXi10qs6YOJrFyebdu8+K1FG1N23WC+?=
 =?us-ascii?Q?7b84VDbI7A=3D=3D?=
X-OriginatorOrg: vmware.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 88793f51-02f3-45be-88ac-08da3439d5e2
X-MS-Exchange-CrossTenant-AuthSource: BYAPR05MB5624.namprd05.prod.outlook.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 May 2022 17:07:03.5175 (UTC)
X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted
X-MS-Exchange-CrossTenant-Id: b39138ca-3cee-4b4a-a4d6-cd83d9dd62f0
X-MS-Exchange-CrossTenant-MailboxType: HOSTED
X-MS-Exchange-CrossTenant-UserPrincipalName: ycQTz3jci9Y82BgqUUJs1txPQCGriA9Fjh3FIwmPM72H9f5XLSG/aMhPac6kT65tsZ3wrvwkvaeD7588vdtWoQ==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL0PR05MB4721
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

vmxnet3 version 6 supports some new features, including but
not limited to:
- Increased max MTU up to 9190
- Increased max number of queues, both for Rx and Tx
- Removes power-of-two limitations
- Extended interrupt structures, required implementation for
  additional number of queues

Tested, using testpmd, for different hardware version on
ESXi 7.0 Update 2.

Signed-off-by: Pankaj Gupta <pagupta@vmware.com>
Reviewed-by: Jochen Behrens <jbehrens@vmware.com>
---
 drivers/net/vmxnet3/base/vmxnet3_defs.h |  73 ++++++--
 drivers/net/vmxnet3/vmxnet3_ethdev.c    | 220 +++++++++++++++++-------
 drivers/net/vmxnet3/vmxnet3_ethdev.h    |  10 +-
 drivers/net/vmxnet3/vmxnet3_rxtx.c      |   2 +-
 4 files changed, 226 insertions(+), 79 deletions(-)

diff --git a/drivers/net/vmxnet3/base/vmxnet3_defs.h b/drivers/net/vmxnet3/base/vmxnet3_defs.h
index 8d62b3e116..bd6695e69d 100644
--- a/drivers/net/vmxnet3/base/vmxnet3_defs.h
+++ b/drivers/net/vmxnet3/base/vmxnet3_defs.h
@@ -103,7 +103,11 @@ typedef enum {
    VMXNET3_CMD_GET_CONF_INTR,
    VMXNET3_CMD_GET_ADAPTIVE_RING_INFO,
    VMXNET3_CMD_GET_TXDATA_DESC_SIZE,
-   VMXNET3_CMD_RESERVED5,
+	VMXNET3_CMD_RESERVED5,
+	VMXNET3_CMD_RESERVED6,
+	VMXNET3_CMD_RESERVED7,
+	VMXNET3_CMD_RESERVED8,
+	VMXNET3_CMD_GET_MAX_QUEUES_CONF,
 } Vmxnet3_Cmd;
 
 /* Adaptive Ring Info Flags */
@@ -571,6 +575,24 @@ enum vmxnet3_intr_type {
 /* addition 1 for events */
 #define VMXNET3_MAX_INTRS      25
 
+/* Version 6 and later will use below macros */
+#define VMXNET3_EXT_MAX_TX_QUEUES  32
+#define VMXNET3_EXT_MAX_RX_QUEUES  32
+
+/* Version-dependent MAX RX/TX queues macro */
+#define MAX_RX_QUEUES(hw) \
+	(VMXNET3_VERSION_GE_6((hw)) ? \
+	VMXNET3_EXT_MAX_RX_QUEUES : \
+	VMXNET3_MAX_RX_QUEUES)
+#define MAX_TX_QUEUES(hw) \
+	(VMXNET3_VERSION_GE_6((hw)) ? \
+	VMXNET3_EXT_MAX_TX_QUEUES : \
+	VMXNET3_MAX_TX_QUEUES)
+
+/* addition 1 for events */
+#define VMXNET3_EXT_MAX_INTRS      65
+#define VMXNET3_FIRST_SET_INTRS    64
+
 /* value of intrCtrl */
 #define VMXNET3_IC_DISABLE_ALL  0x1   /* bit 0 */
 
@@ -587,6 +609,21 @@ struct Vmxnet3_IntrConf {
 #include "vmware_pack_end.h"
 Vmxnet3_IntrConf;
 
+typedef
+#include "vmware_pack_begin.h"
+struct Vmxnet3_IntrConfExt {
+	uint8    autoMask;
+	uint8    numIntrs;      /* # of interrupts */
+	uint8    eventIntrIdx;
+	uint8    reserved;
+	__le32   intrCtrl;
+	__le32   reserved1;
+	uint8    modLevels[VMXNET3_EXT_MAX_INTRS]; /* moderation level for each intr */
+	uint8    reserved2[3];
+}
+#include "vmware_pack_end.h"
+Vmxnet3_IntrConfExt;
+
 /* one bit per VLAN ID, the size is in the units of uint32 */
 #define VMXNET3_VFT_SIZE  (4096 / (sizeof(uint32) * 8))
 
@@ -692,6 +729,15 @@ struct Vmxnet3_DSDevRead {
 #include "vmware_pack_end.h"
 Vmxnet3_DSDevRead;
 
+typedef
+#include "vmware_pack_begin.h"
+struct Vmxnet3_DSDevReadExt {
+	/* read-only region for device, read by dev in response to a SET cmd */
+	struct Vmxnet3_IntrConfExt    intrConfExt;
+}
+#include "vmware_pack_end.h"
+Vmxnet3_DSDevReadExt;
+
 typedef
 #include "vmware_pack_begin.h"
 struct Vmxnet3_TxQueueDesc {
@@ -778,18 +824,18 @@ Vmxnet3_CmdInfo;
 typedef
 #include "vmware_pack_begin.h"
 struct Vmxnet3_DriverShared {
-   __le32               magic;
-   __le32               pad; /* make devRead start at 64-bit boundaries */
-   Vmxnet3_DSDevRead    devRead;
-   __le32               ecr;
-   __le32               reserved;
-
-   union {
-      __le32            reserved1[4];
-      Vmxnet3_CmdInfo   cmdInfo; /* only valid in the context of executing the
-				  * relevant command
-				  */
-   } cu;
+	__le32               magic;
+	__le32               size;    /* size of DriverShared */
+	Vmxnet3_DSDevRead    devRead;
+	__le32               ecr;
+	__le32               reserved;
+
+	union {
+		__le32			reserved1[4];
+		/* only valid in the context of executing the relevant command */
+		Vmxnet3_CmdInfo	cmdInfo;
+	} cu;
+	struct Vmxnet3_DSDevReadExt   devReadExt;
 }
 #include "vmware_pack_end.h"
 Vmxnet3_DriverShared;
@@ -821,6 +867,7 @@ do {\
    ((vfTable[vid >> 5] & (1 << (vid & 31))) != 0)
 
 #define VMXNET3_MAX_MTU     9000
+#define VMXNET3_V6_MAX_MTU  9190
 #define VMXNET3_MIN_MTU     60
 
 #define VMXNET3_LINK_UP         (10000 << 16 | 1)    // 10 Gbps, up
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index d14ddfcbeb..af4a1a1b40 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -222,24 +222,20 @@ vmxnet3_disable_intr(struct vmxnet3_hw *hw, unsigned int intr_idx)
 }
 
 /*
- * Enable all intrs used by the device
+ * Simple helper to get intrCtrl and eventIntrIdx based on config and hw version
  */
 static void
-vmxnet3_enable_all_intrs(struct vmxnet3_hw *hw)
+vmxnet3_get_intr_ctrl_ev(struct vmxnet3_hw *hw,
+			 uint8 **out_eventIntrIdx,
+			 uint32 **out_intrCtrl)
 {
-	Vmxnet3_DSDevRead *devRead = &hw->shared->devRead;
-
-	PMD_INIT_FUNC_TRACE();
 
-	devRead->intrConf.intrCtrl &= rte_cpu_to_le_32(~VMXNET3_IC_DISABLE_ALL);
-
-	if (hw->intr.lsc_only) {
-		vmxnet3_enable_intr(hw, devRead->intrConf.eventIntrIdx);
+	if (VMXNET3_VERSION_GE_6(hw) && hw->queuesExtEnabled) {
+		*out_eventIntrIdx = &hw->shared->devReadExt.intrConfExt.eventIntrIdx;
+		*out_intrCtrl = &hw->shared->devReadExt.intrConfExt.intrCtrl;
 	} else {
-		int i;
-
-		for (i = 0; i < hw->intr.num_intrs; i++)
-			vmxnet3_enable_intr(hw, i);
+		*out_eventIntrIdx = &hw->shared->devRead.intrConf.eventIntrIdx;
+		*out_intrCtrl = &hw->shared->devRead.intrConf.intrCtrl;
 	}
 }
 
@@ -250,15 +246,42 @@ static void
 vmxnet3_disable_all_intrs(struct vmxnet3_hw *hw)
 {
 	int i;
+	uint8 *eventIntrIdx;
+	uint32 *intrCtrl;
 
 	PMD_INIT_FUNC_TRACE();
+	vmxnet3_get_intr_ctrl_ev(hw, &eventIntrIdx, &intrCtrl);
+
+	*intrCtrl |= rte_cpu_to_le_32(VMXNET3_IC_DISABLE_ALL);
 
-	hw->shared->devRead.intrConf.intrCtrl |=
-		rte_cpu_to_le_32(VMXNET3_IC_DISABLE_ALL);
-	for (i = 0; i < hw->num_intrs; i++)
+	for (i = 0; i < hw->intr.num_intrs; i++)
 		vmxnet3_disable_intr(hw, i);
 }
 
+/*
+ * Enable all intrs used by the device
+ */
+static void
+vmxnet3_enable_all_intrs(struct vmxnet3_hw *hw)
+{
+	uint8 *eventIntrIdx;
+	uint32 *intrCtrl;
+
+	PMD_INIT_FUNC_TRACE();
+	vmxnet3_get_intr_ctrl_ev(hw, &eventIntrIdx, &intrCtrl);
+
+	*intrCtrl &= rte_cpu_to_le_32(~VMXNET3_IC_DISABLE_ALL);
+
+	if (hw->intr.lsc_only) {
+		vmxnet3_enable_intr(hw, *eventIntrIdx);
+	} else {
+		int i;
+
+		for (i = 0; i < hw->intr.num_intrs; i++)
+			vmxnet3_enable_intr(hw, i);
+	}
+}
+
 /*
  * Gets tx data ring descriptor size.
  */
@@ -333,7 +356,11 @@ eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
 	/* Check h/w version compatibility with driver. */
 	ver = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_VRRS);
 
-	if (ver & (1 << VMXNET3_REV_5)) {
+	if (ver & (1 << VMXNET3_REV_6)) {
+		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_VRRS,
+				       1 << VMXNET3_REV_6);
+		hw->version = VMXNET3_REV_6 + 1;
+	} else if (ver & (1 << VMXNET3_REV_5)) {
 		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_VRRS,
 				       1 << VMXNET3_REV_5);
 		hw->version = VMXNET3_REV_5 + 1;
@@ -508,15 +535,22 @@ vmxnet3_dev_configure(struct rte_eth_dev *dev)
 	if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
 		dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
 
-	if (dev->data->nb_tx_queues > VMXNET3_MAX_TX_QUEUES ||
-	    dev->data->nb_rx_queues > VMXNET3_MAX_RX_QUEUES) {
-		PMD_INIT_LOG(ERR, "ERROR: Number of queues not supported");
-		return -EINVAL;
+	if (!VMXNET3_VERSION_GE_6(hw)) {
+		if (!rte_is_power_of_2(dev->data->nb_rx_queues)) {
+			PMD_INIT_LOG(ERR,
+				     "ERROR: Number of rx queues not power of 2");
+			return -EINVAL;
+		}
 	}
 
-	if (!rte_is_power_of_2(dev->data->nb_rx_queues)) {
-		PMD_INIT_LOG(ERR, "ERROR: Number of rx queues not power of 2");
-		return -EINVAL;
+	/* At this point, the number of queues requested has already
+	 * been validated against dev_infos max queues by EAL
+	 */
+	if (dev->data->nb_rx_queues > VMXNET3_MAX_RX_QUEUES ||
+	    dev->data->nb_tx_queues > VMXNET3_MAX_TX_QUEUES) {
+		hw->queuesExtEnabled = 1;
+	} else {
+		hw->queuesExtEnabled = 0;
 	}
 
 	size = dev->data->nb_rx_queues * sizeof(struct Vmxnet3_TxQueueDesc) +
@@ -627,9 +661,9 @@ vmxnet3_configure_msix(struct rte_eth_dev *dev)
 		return -1;
 
 	intr_vector = dev->data->nb_rx_queues;
-	if (intr_vector > VMXNET3_MAX_RX_QUEUES) {
+	if (intr_vector > MAX_RX_QUEUES(hw)) {
 		PMD_INIT_LOG(ERR, "At most %d intr queues supported",
-			     VMXNET3_MAX_RX_QUEUES);
+			     MAX_RX_QUEUES(hw));
 		return -ENOTSUP;
 	}
 
@@ -777,6 +811,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
 	uint32_t mtu = dev->data->mtu;
 	Vmxnet3_DriverShared *shared = hw->shared;
 	Vmxnet3_DSDevRead *devRead = &shared->devRead;
+	struct Vmxnet3_DSDevReadExt *devReadExt = &shared->devReadExt;
 	uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
 	uint32_t i;
 	int ret;
@@ -853,13 +888,27 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
 	}
 
 	/* intr settings */
-	devRead->intrConf.autoMask = hw->intr.mask_mode == VMXNET3_IMM_AUTO;
-	devRead->intrConf.numIntrs = hw->intr.num_intrs;
-	for (i = 0; i < hw->intr.num_intrs; i++)
-		devRead->intrConf.modLevels[i] = hw->intr.mod_levels[i];
+	if (VMXNET3_VERSION_GE_6(hw) && hw->queuesExtEnabled) {
+		devReadExt->intrConfExt.autoMask = hw->intr.mask_mode ==
+						   VMXNET3_IMM_AUTO;
+		devReadExt->intrConfExt.numIntrs = hw->intr.num_intrs;
+		for (i = 0; i < hw->intr.num_intrs; i++)
+			devReadExt->intrConfExt.modLevels[i] =
+				hw->intr.mod_levels[i];
+
+		devReadExt->intrConfExt.eventIntrIdx = hw->intr.event_intr_idx;
+		devReadExt->intrConfExt.intrCtrl |=
+			rte_cpu_to_le_32(VMXNET3_IC_DISABLE_ALL);
+	} else {
+		devRead->intrConf.autoMask = hw->intr.mask_mode ==
+					     VMXNET3_IMM_AUTO;
+		devRead->intrConf.numIntrs = hw->intr.num_intrs;
+		for (i = 0; i < hw->intr.num_intrs; i++)
+			devRead->intrConf.modLevels[i] = hw->intr.mod_levels[i];
 
-	devRead->intrConf.eventIntrIdx = hw->intr.event_intr_idx;
-	devRead->intrConf.intrCtrl |= rte_cpu_to_le_32(VMXNET3_IC_DISABLE_ALL);
+		devRead->intrConf.eventIntrIdx = hw->intr.event_intr_idx;
+		devRead->intrConf.intrCtrl |= rte_cpu_to_le_32(VMXNET3_IC_DISABLE_ALL);
+	}
 
 	/* RxMode set to 0 of VMXNET3_RXM_xxx */
 	devRead->rxFilterConf.rxMode = 0;
@@ -937,18 +986,24 @@ vmxnet3_dev_start(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
-	/* Setup memory region for rx buffers */
-	ret = vmxnet3_dev_setup_memreg(dev);
-	if (ret == 0) {
-		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
-				       VMXNET3_CMD_REGISTER_MEMREGS);
-		ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
-		if (ret != 0)
-			PMD_INIT_LOG(DEBUG,
-				     "Failed in setup memory region cmd\n");
-		ret = 0;
+	/* Check memregs restrictions first */
+	if (dev->data->nb_rx_queues <= VMXNET3_MAX_RX_QUEUES &&
+	    dev->data->nb_tx_queues <= VMXNET3_MAX_TX_QUEUES) {
+		ret = vmxnet3_dev_setup_memreg(dev);
+		if (ret == 0) {
+			VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
+					VMXNET3_CMD_REGISTER_MEMREGS);
+			ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
+			if (ret != 0)
+				PMD_INIT_LOG(DEBUG,
+					"Failed in setup memory region cmd\n");
+			ret = 0;
+		} else {
+			PMD_INIT_LOG(DEBUG, "Failed to setup memory region\n");
+		}
 	} else {
-		PMD_INIT_LOG(DEBUG, "Failed to setup memory region\n");
+		PMD_INIT_LOG(WARNING, "Memregs can't init (rx: %d, tx: %d)",
+			     dev->data->nb_rx_queues, dev->data->nb_tx_queues);
 	}
 
 	if (VMXNET3_VERSION_GE_4(hw) &&
@@ -1203,8 +1258,6 @@ vmxnet3_hw_stats_save(struct vmxnet3_hw *hw)
 
 	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, &hw->saved_tx_stats[i]);
 	for (i = 0; i < hw->num_rx_queues; i++)
@@ -1306,7 +1359,6 @@ vmxnet3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
 	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_tx_stats_get(hw, i, &txStats);
 
@@ -1323,7 +1375,6 @@ vmxnet3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 		stats->oerrors += txStats.pktsTxError + txStats.pktsTxDiscard;
 	}
 
-	RTE_BUILD_BUG_ON(RTE_ETHDEV_QUEUE_STAT_CNTRS < VMXNET3_MAX_RX_QUEUES);
 	for (i = 0; i < hw->num_rx_queues; i++) {
 		vmxnet3_rx_stats_get(hw, i, &rxStats);
 
@@ -1377,9 +1428,27 @@ vmxnet3_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
+	int queues = 0;
+
+	if (VMXNET3_VERSION_GE_6(hw)) {
+		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
+				       VMXNET3_CMD_GET_MAX_QUEUES_CONF);
+		queues = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
+
+		if (queues > 0) {
+			dev_info->max_rx_queues =
+			  RTE_MIN(VMXNET3_EXT_MAX_RX_QUEUES, ((queues >> 8) & 0xff));
+			dev_info->max_tx_queues =
+			  RTE_MIN(VMXNET3_EXT_MAX_TX_QUEUES, (queues & 0xff));
+		} else {
+			dev_info->max_rx_queues = VMXNET3_MAX_RX_QUEUES;
+			dev_info->max_tx_queues = VMXNET3_MAX_TX_QUEUES;
+		}
+	} else {
+		dev_info->max_rx_queues = VMXNET3_MAX_RX_QUEUES;
+		dev_info->max_tx_queues = VMXNET3_MAX_TX_QUEUES;
+	}
 
-	dev_info->max_rx_queues = VMXNET3_MAX_RX_QUEUES;
-	dev_info->max_tx_queues = VMXNET3_MAX_TX_QUEUES;
 	dev_info->min_rx_bufsize = 1518 + RTE_PKTMBUF_HEADROOM;
 	dev_info->max_rx_pktlen = 16384; /* includes CRC, cf MAXFRS register */
 	dev_info->min_mtu = VMXNET3_MIN_MTU;
@@ -1430,24 +1499,50 @@ vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 }
 
 static int
-vmxnet3_dev_mtu_set(struct rte_eth_dev *dev, __rte_unused uint16_t mtu)
+vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
 {
-	if (dev->data->dev_started) {
-		PMD_DRV_LOG(ERR, "Port %d must be stopped to configure MTU",
-			    dev->data->port_id);
-		return -EBUSY;
-	}
+	struct vmxnet3_hw *hw = dev->data->dev_private;
 
+	rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)(hw->perm_addr));
+	vmxnet3_write_mac(hw, mac_addr->addr_bytes);
 	return 0;
 }
 
 static int
-vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
+vmxnet3_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 {
 	struct vmxnet3_hw *hw = dev->data->dev_private;
+	uint32_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + 4;
+
+	if (mtu < VMXNET3_MIN_MTU)
+		return -EINVAL;
+
+	if (VMXNET3_VERSION_GE_6(hw)) {
+		if (mtu > VMXNET3_V6_MAX_MTU)
+			return -EINVAL;
+	} else {
+		if (mtu > VMXNET3_MAX_MTU) {
+			PMD_DRV_LOG(ERR, "MTU %d too large in device version v%d",
+				    mtu, hw->version);
+			return -EINVAL;
+		}
+	}
+
+	dev->data->mtu = mtu;
+	/* update max frame size */
+	dev->data->dev_conf.rxmode.mtu = frame_size;
+
+	if (dev->data->dev_started == 0)
+		return 0;
+
+    /* changing mtu for vmxnet3 pmd does not require a restart
+     * as it does not need to repopulate the rx rings to support
+     * different mtu size.  We stop and restart the device here
+     * just to pass the mtu info to the backend.
+     */
+	vmxnet3_dev_stop(dev);
+	vmxnet3_dev_start(dev);
 
-	rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)(hw->perm_addr));
-	vmxnet3_write_mac(hw, mac_addr->addr_bytes);
 	return 0;
 }
 
@@ -1668,11 +1763,14 @@ vmxnet3_interrupt_handler(void *param)
 {
 	struct rte_eth_dev *dev = param;
 	struct vmxnet3_hw *hw = dev->data->dev_private;
-	Vmxnet3_DSDevRead *devRead = &hw->shared->devRead;
 	uint32_t events;
+	uint8 *eventIntrIdx;
+	uint32 *intrCtrl;
 
 	PMD_INIT_FUNC_TRACE();
-	vmxnet3_disable_intr(hw, devRead->intrConf.eventIntrIdx);
+
+	vmxnet3_get_intr_ctrl_ev(hw, &eventIntrIdx, &intrCtrl);
+	vmxnet3_disable_intr(hw, *eventIntrIdx);
 
 	events = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_ECR);
 	if (events == 0)
@@ -1681,7 +1779,7 @@ vmxnet3_interrupt_handler(void *param)
 	RTE_LOG(DEBUG, PMD, "Reading events: 0x%X", events);
 	vmxnet3_process_events(dev);
 done:
-	vmxnet3_enable_intr(hw, devRead->intrConf.eventIntrIdx);
+	vmxnet3_enable_intr(hw, *eventIntrIdx);
 }
 
 static int
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.h b/drivers/net/vmxnet3/vmxnet3_ethdev.h
index ceaeb66392..5a303717b1 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.h
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.h
@@ -70,7 +70,7 @@ struct vmxnet3_intr {
 	enum vmxnet3_intr_type      type; /* MSI-X, MSI, or INTx? */
 	uint8_t num_intrs;                /* # of intr vectors */
 	uint8_t event_intr_idx;           /* idx of the intr vector for event */
-	uint8_t mod_levels[VMXNET3_MAX_MSIX_VECT]; /* moderation level */
+	uint8_t mod_levels[VMXNET3_EXT_MAX_INTRS]; /* moderation level */
 	bool lsc_only;                    /* no Rx queue interrupt */
 };
 
@@ -108,6 +108,7 @@ struct vmxnet3_hw {
 	uint64_t              queueDescPA;
 	uint16_t              queue_desc_len;
 	uint16_t              mtu;
+	bool                  queuesExtEnabled;
 
 	VMXNET3_RSSConf       *rss_conf;
 	uint64_t              rss_confPA;
@@ -117,19 +118,20 @@ struct vmxnet3_hw {
 	Vmxnet3_MemRegs	      *memRegs;
 	uint64_t	      memRegsPA;
 #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	      saved_tx_stats[VMXNET3_EXT_MAX_TX_QUEUES];
+	UPT1_RxStats	      saved_rx_stats[VMXNET3_EXT_MAX_RX_QUEUES];
 	UPT1_TxStats          snapshot_tx_stats[VMXNET3_MAX_TX_QUEUES];
 	UPT1_RxStats          snapshot_rx_stats[VMXNET3_MAX_RX_QUEUES];
 };
 
+#define VMXNET3_REV_6		5		/* Vmxnet3 Rev. 6 */
 #define VMXNET3_REV_5		4		/* Vmxnet3 Rev. 5 */
 #define VMXNET3_REV_4		3		/* Vmxnet3 Rev. 4 */
 #define VMXNET3_REV_3		2		/* Vmxnet3 Rev. 3 */
 #define VMXNET3_REV_2		1		/* Vmxnet3 Rev. 2 */
 #define VMXNET3_REV_1		0		/* Vmxnet3 Rev. 1 */
 
+#define VMXNET3_VERSION_GE_6(hw) ((hw)->version >= VMXNET3_REV_6 + 1)
 #define VMXNET3_VERSION_GE_5(hw) ((hw)->version >= VMXNET3_REV_5 + 1)
 #define VMXNET3_VERSION_GE_4(hw) ((hw)->version >= VMXNET3_REV_4 + 1)
 #define VMXNET3_VERSION_GE_3(hw) ((hw)->version >= VMXNET3_REV_3 + 1)
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index e15b377d8c..c94e3762e6 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -1400,7 +1400,7 @@ vmxnet3_rss_configure(struct rte_eth_dev *dev)
 	/* loading hashKeySize */
 	dev_rss_conf->hashKeySize = VMXNET3_RSS_MAX_KEY_SIZE;
 	/* loading indTableSize: Must not exceed VMXNET3_RSS_MAX_IND_TABLE_SIZE (128)*/
-	dev_rss_conf->indTableSize = (uint16_t)(hw->num_rx_queues * 4);
+	dev_rss_conf->indTableSize = (uint16_t)((MAX_RX_QUEUES(hw)) * 4);
 
 	if (port_rss_conf->rss_key == NULL) {
 		/* Default hash key */
-- 
2.17.1